打印
[开发资料]

ARM5到ARM6 分散文件加载错误问题

[复制链接]
316|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Zhiniaocun|  楼主 | 2025-7-7 21:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一 、 背景
在最近的一次项目中,使用的是ciu32L系列的单片机,因为初始化时,需要对flash进行一些数据写入,发现其使用的是ARM5编译
用官方的历程编译一切正常,但我项目使用的是ARM6编译器,所以我也试了下,直接将编译器改为ARM6,此时编译报了各警告
如下:



二、解决方案
2.1、 官方例程如下:
#if   defined ( __CC_ARM )
#pragma arm section code = "FAST_PROGRAM"
#elif defined ( __ICCARM__ )
__ramfunc
#elif defined ( __GNUC__ )
__attribute__  ((section (".RamFunc")))
#endif

/**
* @brief  Flash快速编程,往目标地址快速编程半页数据
* @param  address 编程地址
* @param  data_buf 编程数据
* @retval std_status_t 本函数执行结果
*/
std_status_t bsp_flash_fast_write(uint32_t address, uint32_t *data_buf)
{
    std_status_t status = STD_OK;
    uint32_t prog_count = 0;

    /* 启动快速编程模式 */
    FLASH->CR |= FLASH_CR_FSTPG_MODE;

    /* 向目标地址写入数据 */
    for (prog_count=0; prog_count < FSTPG_WORD_COUNT; prog_count++)
    {
        ((uint32_t *)address)[prog_count] = data_buf[prog_count];

        /* 查询等待BSY标志被清除 */
        while ((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY);

        /* 若出现错误,则退出编程循环 */
        if (FLASH->SR & FLASH_FLAG_ALL_ERR)
        {
            status = STD_ERR;
            break;
        }
    }

    /* 查询等待FSTPG_MODE状态被自动清零 */
    while ((FLASH->CR & FLASH_CR_FSTPG_MODE) == FLASH_CR_FSTPG_MODE);

    /* 清除Flash标志 */
    FLASH->SR = (FLASH_FLAG_ALL_ERR | FLASH_SR_EOP);

    return (status);
}

#if   defined ( __CC_ARM )
#pragma arm section
#endif









分散加载文件如下:

LR_IROM1 0x08000000 0x00040000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00040000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00001000  {  ; RW data
   *.o(FAST_PROGRAM)
   .ANY (+RW +ZI)
  }
}



注意:

在ARM6(即AC6编译器,基于LLVM/Clang)环境下,__CC_ARM 这个宏已被废弃,GNUC
也被Keil的ARM编译器6支持。但你遇到的问题的根本原因是,没有正确地在链接脚本和代码中统一声明和使用 .FAST_PROGRAM
段,导致编译时找不到匹配的 .o(FAST_PROGRAM) 段。

2.2、解决方案:
确保正确的编译器宏判断
ARM6 编译器在 Keil 中的宏是 __ARMCC_VERSION
#if defined(__CC_ARM)  // ARM Compiler 5
#pragma arm section code="FAST_PROGRAM"
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6000000)  // ARM Compiler 6
__attribute__((section(".FAST_PROGRAM"), used))
#elif defined(__ICCARM__)  // IAR
__ramfunc
#elif defined(__GNUC__)  // GCC
__attribute__((section(".FAST_PROGRAM"), used))
#endif



分散加载文件如下:

LR_IROM1 0x08000000 0x00040000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00040000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  RW_IRAM1 0x20000000 0x00002000  {  ; RW data
    *(FAST_PROGRAM)   ; 让 .FAST_PROGRAM 段放入 RAM
    .ANY (+RW +ZI)
  }
}




此时编译通过,程序运行正常。

写笔记的目的其实就是当再次遇到同一个问题,时间久了可能会忘记处理方法,同时也可以解决大家在项目中碰到此类问题,给以快速解决方案。赠人玫瑰,手有余香。养成做笔记的习惯。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/Porter_007/article/details/146230194

使用特权

评论回复
沙发
彩虹捕手| | 2025-7-10 11:41 | 只看该作者
感谢分享,这个解决方案对于我们这些经常需要在不同ARM版本之间切换的开发者来说非常有帮助。

使用特权

评论回复
板凳
星空魔法师| | 2025-7-10 14:51 | 只看该作者
感谢分享,遇到类似的问题时,确实需要这样的详细解决方案。你的笔记对于我们这些开发者来说非常有帮助。

使用特权

评论回复
地板
破晓战神| | 2025-7-12 10:05 | 只看该作者
感谢分享,遇到类似的问题时,确实需要详细的步骤和解决方案。你的笔记对于我们这些经常需要在不同ARM版本间切换的开发者来说非常有帮助。

使用特权

评论回复
5
不想起床喵星人| | 2025-7-15 09:52 | 只看该作者
感谢分享!这个解决方案对于我们这些使用不同ARM编译器的人来说非常有帮助。确保编译器宏的正确使用是关键。

使用特权

评论回复
6
懒癌晚期患者| | 2025-7-15 13:01 | 只看该作者
看起来你已经找到了问题的根源和解决方案,这确实是一个常见的问题,特别是在升级编译器时。确保链接脚本和代码中正确声明和使用段是非常重要的。你的解决方案很详细,对遇到同样问题的人会很有帮助。

使用特权

评论回复
7
逆鳞风暴| | 2025-7-23 08:52 | 只看该作者
感谢分享,遇到ARM编译器升级导致的问题确实很头疼,你的解决方案很有帮助。

使用特权

评论回复
8
蚊子的噩梦| | 2025-7-23 15:29 | 只看该作者
博主分享的这个问题和解决方案非常有用,我之前也遇到过类似的编译器升级导致的问题。按照你提供的修改,确实可以解决问题。

使用特权

评论回复
9
懒癌晚期患者| | 2025-7-23 16:08 | 只看该作者
感谢分享,这个解决方案很有用,我之前也遇到过类似的问题,一直以为是硬件问题,原来是编译器宏定义的问题。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

200

帖子

1

粉丝