【草堂笔记】ARM5到ARM6 分散文件加载错误问题

server/2025/3/17 17:43:42/

一 、 背景

在最近的一次项目中,使用的是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_regionER_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、解决方案:

  1. 确保正确的编译器宏判断
    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_regionER_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)}
}

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

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


http://www.ppmy.cn/server/175745.html

相关文章

LeetCode--198. 打家劫舍【从返回最大值到输出路径】

198. 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房…

Qt 通过MSVC编译运行项目

第一步下载Qt 把Qt能选的插件都选上&#xff0c;有的是连接数据库必须得插件&#xff0c;有的是做图表必须得插件&#xff0c;有的是运行MSVC必须得插件&#xff0c;能选尽量都选上。 第二步安装VS2017&#xff0c;当然我们安装2017的目的主要是用C的编译器&#xff0c;这里提…

uniapp上传文件问题以及返回上一页出现退出app的问题记录

uniapp上传文件使用uni.uploadFile&#xff0c;如果直接一次性在success里完成会导致页面自动刷新&#xff0c;特别是添加了本页面有onshow()方法&#xff0c;上传完会自动调用onshow()方法。 建议使用官方的方式分成两个方法处理&#xff1a; async afterRead(event) {let f…

如何打造TikTok矩阵:多账号管理与内容引流的高效策略

随着短视频平台的崛起&#xff0c;TikTok成为了全球范围内最具影响力的社交平台之一。在这个平台上&#xff0c;通过精确的内容营销和运营策略&#xff0c;许多创作者和品牌成功实现了曝光、粉丝增长和变现。为了提高运营效率&#xff0c;许多专业的内容创作者和团队开始使用Ti…

【每日学点HarmonyOS Next知识】页面引用问题、Json三方库、路由表使用、下拉刷新问题、视频播放错误

1、HarmonyOS 全屏的自定义组件被其他页面引用后导致其他页面按钮功能无法使用问题&#xff1f; 参考代码&#xff1a; //1.index.ets Entry Component struct First {State visible: Visibility Visibility.Nonebuild() {// 使用stack可以实现假的dialog覆盖原页面上面Stac…

摄像头模块ISP处理流程

摄像头模块的ISP&#xff08;图像信号处理器&#xff09;处理流程是对图像传感器输出的原始信号进行系统性优化的过程&#xff0c;主要分为以下关键步骤及对应功能模块&#xff1a; 一、原始信号输入与预处理 ‌传感器信号捕获‌ CMOS/CCD传感器将光信号转换为模拟电信号&…

【QA】建造者模式在Qt有哪些应用

#设计模式 #Qt 一、QDomDocument&#xff08;XML 文档构建&#xff09; 模式角色&#xff1a; Builder&#xff1a;QDomDocument 本身Product&#xff1a;XML 文档对象Director&#xff1a;用户代码通过 QDomDocument 逐步构建文档结构 示例代码&#xff1a; QDomDocument…

DeepSeek-prompt指令-当DeepSeek答非所问,应该如何准确的表达我们的诉求?

当DeepSeek答非所问&#xff0c;应该如何准确的表达我们的诉求&#xff1f;不同使用场景如何向DeepSeek发问&#xff1f;是否有指令公式&#xff1f; 目录 1、 扮演专家型指令2、 知识蒸馏型指令3、 颗粒度调节型指令4、 时间轴推演型指令5、 极端测试型6、 逆向思维型指令7、…