痞子衡嵌入式:在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法。
痞子衡旧文 《在IAR下将关键函数重定向到RAM中执行的方法》 里介绍了三种关键函数重定向方法,不过这三种方法只是写法形式不同,本质上没啥区别,都是利用 IAR 链接器特性将函数重定向到工程数据段(RW)所在 RAM 里。
对于 i.MXRT 这种拥有多块地址非连续的 RAM 的芯片,其实我们也可以单独将这些重定向函数放到一个指定的 RAM 里,不一定非得跟数据段放在同一个 RAM 里。具体实现也很简单,只需要在链接文件里额外加一句 place in 语句处理即可,恩智浦官方 SDK 包里就是这么做的。
然而痞子衡最近在支持 i.MXRT1170 客户过程中,不使用恩智浦 SDK 里那种自定义函数段处理的方法,而是在 IAR 链接文件里使用指定源文件 object 的方式将代码重定向到 ITCM 竟然失效了,这是怎么回事?今天我们一起来看一下:
- Note 1: 阅读本文前需要对 《IAR链接文件(.icf)》、《IAR映射文件(.map)》 这两种文件有所了解。
- Note 2: 本文使用的 IAR EWARM 软件版本是 v9.10.2。
一、回顾SDK里函数重定向做法
我们以最经典的 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm7\iar 例程来看,工程 Build 选择 flexspi_nor_debug,即代码段放在 Flash 里(0x30000000 - ),数据段放在 DTCM 里(0x20000000 - )。
我们现在新建一个名为 ram_code.c 的源文件,在这个源文件里定义如下两个 delay1/2() 函数,然后将这个源文件添加进工程使用。按照 SDK 里做法,如果我们想将这两个函数重定向,需要加 AT_QUICKACCESS_SECTION_CODE 宏来修饰,其实就是将函数放到名为 CodeQuickAccess 的自定义段里。
#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
AT_QUICKACCESS_SECTION_CODE(void delay1(void));
void delay1(void)
{
__NOP();
}
AT_QUICKACCESS_SECTION_CODE(void delay2(void));
void delay2(void)
{
__NOP();
__NOP();
}
然后工程链接文件 MIMXRT1176xxxxx_cm7_flexspi_nor.icf 里(仅摘录部分),CodeQuickAccess 段单独放在 ITCM 里(0x00000000 - ),这就是官方 SDK 里的实现。
define symbol m_data_start = 0x20000000;
define symbol m_data_end = 0x2003FFFF;
define symbol m_itcm_start = 0x00000000;
define symbol m_itcm_end = 0x0003FFFF;
define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__];
define region ITCM_region = mem:[from m_itcm_start to m_itcm_end];
define block RW { first readwrite, section m_usb_dma_init_data };
define block QACCESS_CODE { section CodeQuickAccess };
initialize by copy { readwrite, section .textrw, section CodeQuickAccess };
place in DATA_region { block RW };
place in ITCM_region { block QACCESS_CODE };
编译链接 hello_world_demo_cm7.ewp 工程,然后查看其映射文件(hello_world_demo_cm7.map)找到跟 delay1/2() 函数相关的内容如下,显然这是符合预期的。这里特别注意一下,CodeQuickAccess 的类别显示的是 inited,表明其不是常见的 ro code,而是经过重定向的,而且 delay1/2() 函数所在 ram_code.o 里包含了 10 个字节的 rw code。
*******************************************************************************
*** PLACEMENT SUMMARY
***
define block QACCESS_CODE { section CodeQuickAccess };
"P8": place in [from 0x0 to 0x3'ffff] { block QACCESS_CODE };
Section Kind Address Size Object
------- ---- ------- ---- ------
"P8": 0xc
QACCESS_CODE 0x0 0xc <Block>
QACCESS_CODE-1 0x0 0xa <Init block>
CodeQuickAccess inited 0x0 0xa ram_code.o [6]
- 0xc 0xc
*******************************************************************************
*** MODULE SUMMARY
***
Module ro code rw code ro data rw data
------ ------- ------- ------- -------
ram_code.o 10 10
*******************************************************************************
*** ENTRY LIST
***
Entry Address Size Type Object
---- ------- ---- ---- ------
delay1 0x1 0x4 Code Gb ram_code.o [6]
delay2 0x5 0x6 Code Gb ram_code.o [6]
如果你打开工程镜像文件 hello_world_demo_cm7.srec 查看,这里也只有一段连续的 Flash 地址空间数据,没有 RAM 地址空间数据,所以这个镜像文件是符合独立工具(比如 MCUBootUtility)下载以及 BootROM 启动条件的。
二、引出源文件Object方式重定向失效问题
现在来看客户遇到的问题,客户不想在源文件里逐一修饰需要重定向的函数(即 ram_code.c 文件里 delay1/2() 函数不加 AT_QUICKACCESS_SECTION_CODE 修饰),这种情况下我们需要改动一下链接文件,将 object ram_code.o 放到 initialize by copy 语句和 place in ITCM_region 语句里。
initialize by copy { readwrite, section .textrw, section CodeQuickAccess, object ram_code.o };
place in ITCM_region { object ram_code.o };
这时候重新编译链接工程,查看映射文件,找到跟 delay1/2() 函数相关的内容如下,这个结果跟第一小节里结果有点区别,虽然 delay1/2() 确实链接在了 ITCM 里(0x00000000 - ),但是同时也增加了 0x0 - 0xb 区域的 Initializer bytes。
*******************************************************************************
*** PLACEMENT SUMMARY
***
define block QACCESS_CODE { section CodeQuickAccess };
"P8": place in [from 0x0 to 0x3'ffff] { block QACCESS_CODE };
"P9": place in [from 0x0 to 0x3'ffff] { object ram_code.o };
Section Kind Address Size Object
------- ---- ------- ---- ------
"P8-P9": 0x18
Initializer bytes const 0x0 0xc <for P8-P9-1>
P8-P9-1 0xc 0xa <Init block>
.text inited 0xc 0xa ram_code.o [6]
- 0x16 0x16
*******************************************************************************
*** MODULE SUMMARY
***
Module ro code ro data rw data
------ ------- ------- -------
ram_code.o 10 10
*******************************************************************************
*** ENTRY LIST
***
Entry Address Size Type Object
---- ------- ---- ---- ------
delay1 0xd 0x4 Code Gb ram_code.o [6]
delay2 0x11 0x6 Code Gb ram_code.o [6]
如果此时再打开工程镜像文件 hello_world_demo_cm7.srec 查看,除了 Flash 地址空间数据,还新增了 RAM 地址空间数据,很显然这个镜像文件不符合独立工具(比如 MCUBootUtility)下载以及 BootROM 启动,仅能用于 IDE 中在线下载调试(即分散加载了)。
三、源文件Object方式重定向失效分析
我们再做一个实验,按 《在IAR下将关键函数重定向到RAM中执行的方法》 一文 2.3 针对源文件中全部函数 方法,在链接文件中仅将 object ram_code.o 放到 initialize by copy 语句里,那么 ram_code.o 中的内容会被统一重定向到工程数据段 RW 所在 RAM 区域里(即 DTCM 0x20000000 -),这种情况下 delay1/2() 函数重定向是成功的。
initialize by copy { readwrite, section .textrw, section CodeQuickAccess, object ram_code.o };
//place in ITCM_region { object ram_code.o };
所以我们能够得出结论,在不自定义函数段名的情况下,object ram_code.o 中内容会在默认 RO、RW 段里,在做函数重定向时,IAR 链接器无法将对应 ram_code.o 的 Initializer bytes 从默认 RO 段里单独提取出来拷贝到非 RW 段所在区,它只能统一处理 RO 段 Initializer bytes 到 RW 区的拷贝。如果硬要将 object ram_code.o 重定向到非 RW 所在 RAM 区,IAR 链接器会直接将其 Initializer bytes 也从 RO 段里抽出来,与其 RW 属性的 .text 放在一起,这其实几乎等效于分散加载了。
四、源文件Object方式重定向失效解决方案
分析到这里,解决方案清晰了,还是需要自定义程序段,不过既然不想单个函数加修饰,那有没有整个文件范围内代码统一加修饰呢?当然是有的,这时候需要借助如下 #pragma default_function_attributes 语法,将这一对语句放置到源文件首行和末行,那么该源文件里所有函数都进入了 .myCodeSection 自定义段里:
// 作用全部函数
#pragma default_function_attributes = @ ".myCodeSection"
// 作用全部变量(如有必要)
//#pragma default_variable_attributes = @ ".myVariSection"
void delay1(void)
{
__NOP();
}
void delay2(void)
{
__NOP();
__NOP();
}
#pragma default_function_attributes =
//#pragma default_variable_attributes =
然后在工程链接文件 MIMXRT1176xxxxx_cm7_flexspi_nor_sdram.icf 里直接将 section .myCodeSection 放到 ITCM 里就可以了:
initialize by copy { readwrite, section .textrw, section CodeQuickAccess, section .myCodeSection };
place in ITCM_region { section .myCodeSection };
这时候再编译链接工程查看映射文件,函数重定向结果就符合预期了,这个结果跟第一小节里的结果一致。
*******************************************************************************
*** PLACEMENT SUMMARY
***
"P8": place in [from 0x0 to 0x3'ffff] { block QACCESS_CODE };
"P9": place in [from 0x0 to 0x3'ffff] { section .myCodeSection };
Section Kind Address Size Object
------- ---- ------- ---- ------
"P8-P9": 0xc
P8-P9 0x0 0xc <Init block>
.myCodeSection inited 0x0 0xa ram_code.o [6]
- 0xc 0xc
*******************************************************************************
*** MODULE SUMMARY
***
Module ro code rw code ro data rw data
------ ------- ------- ------- -------
ram_code.o 10 10
*******************************************************************************
*** ENTRY LIST
***
Entry Address Size Type Object
---- ------- ---- ---- ------
delay1 0x1 0x4 Code Gb ram_code.o [6]
delay2 0x5 0x6 Code Gb ram_code.o [6]
至此,在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
痞子衡嵌入式:在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法的更多相关文章
- 痞子衡嵌入式:在IAR开发环境下为工程开启CRC完整性校验功能的方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下为工程开启CRC完整性校验功能的方法. CRC校验在嵌入式领域里的应用非常广,比如在通信领域,CRC检验值可以作为数据 ...
- 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...
- 痞子衡嵌入式:在IAR开发环境下RT-Thread工程函数重定向失效分析
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下RT-Thread工程函数重定向失效分析. 痞子衡旧文 <在IAR下将关键函数重定向到RAM中执行的方法> ...
- 痞子衡嵌入式:IAR内部C-SPY调试组件配套宏文件(.mac)用法介绍
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR内部C-SPY调试组件配套宏文件(.mac)用法. 痞子衡之前写过一篇 <JLink Script文件基础及其在IAR下调用 ...
- 痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link / CMSIS-DAP)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 做Cortex-M内核MCU嵌入式软件开发,可用的集成开发环境( ...
- 痞子衡嵌入式:其实i.MXRT下改造FlexSPI driver同样支持AHB方式去写入NOR Flash
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT下改造FlexSPI driver以AHB方式去写入NOR Flash. 痞子衡前段时间写过一篇 <串行NAND Fl ...
- 痞子衡嵌入式:史上最强i.MX RT学习资源汇总(持续更新中...)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MX RT学习资源. 类别 资源 简介 官方汇总 i.MXRT产品主页 恩智浦官方i.MXRT产品主页,最权威的资料都在这里,参考手 ...
- 痞子衡嵌入式:一次利用IAR自带CRC完整性校验功能的实践(为KBOOT加BCA)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是利用IAR自带CRC完整性校验功能的一次实践(为KBOOT加BCA). 痞子衡之前写过两篇关于IAR中自带CRC校验功能的文章 < ...
- 痞子衡嵌入式:探析开启CRC完整性校验的IAR工程生成.out和.bin文件先后顺序
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是开启CRC完整性校验的IAR工程生成.out和.bin文件先后顺序问题. 痞子衡之前写了一篇 <在IAR开发环境下为工程开启CRC ...
随机推荐
- [IDEA] chapter_reader - idea看小说插件 idea阅读插件 idea摸鱼插件
目录 1. 简述: 2. 使用说明: 2.1 版本说明: 2.2 重要说明: 2.3 简单使用方法: 2.4 目前支持的网站有 (新↓): 2.5 菜单介绍: 2.6 快捷键设置及推荐: 2.7 在线 ...
- MySQL信息系统函数
- 推荐2个Mac OS X上的JSON工具
原文:http://www.giser.net/?p=887 1 visual JSON 能够将JSON串以列表的方式展示,方便对JSON数据的解析. 2 JSONModeler 可以解析JSON串生 ...
- Kafka从入门到放弃(三) —— 详说生产者
上一篇对Kafka做了简单介绍,还没看的朋友可以点击下方链接. Kafka从入门到放弃(一) -- 初识别Kafka 消息中间件必须与生产者和消费者一起存在才有意义,这次先来聊聊Kafka的生产者. ...
- 前置任务(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 在[前置任务列]中编辑任务关联,这是个正经的设置. 说他"正经",是因为在[手动模式]下,这个设置也是 ...
- CF946B Weird Subtraction Process 题解
Content 有两个数 \(a,b\),执行如下操作: 如果 \(a,b\) 中有一个数是 \(0\),结束操作,否则跳到操作 \(2\). 如果 \(a\geqslant 2b\),那么 \(a\ ...
- CF999B Reversing Encryption 题解
Content 给一个长度为 \(n\) 的字符串 \(s\),执行以下操作: 降序遍历 \(n\) 的所有因子(从 \(n\) 到 \(1\)). 对于每一个因子 \(i\) 翻转字符串 \(s_{ ...
- Tornado WEB服务器框架 Epoll-- 【Mysql数据库】
5.1 数据库 与Django框架相比,Tornado没有自带ORM,对于数据库需要自己去适配.我们使用MySQL数据库. 在Tornado3.0版本以前提供tornado.database模块用来操 ...
- 当ligerui的grid出现固定列与非固定列不在同一水平线上时,改怎么处理
当ligerui的grid出现固定列与非固定列不在同一水平线上时,如下图所示: 此时可以增加fixedCellHeight:false属性进行解决.这个属性在IE上不起作用,那么该怎么处理,可以这样处 ...
- WPF控件界面自适应
之前就听说WPF流式布局,顺滑的很.但由于专业只学习了winform,工作对界面的要求并不高一直没去玩它.目前公司一些软件都是WPF布局,加上工作内容涉及Socket通讯较多,决定用WPF做一个通讯小 ...