热度 23
2013-12-14 11:33
3709 次阅读|
1 个评论
前文所述的代码分段,限定比较大,对于使用 #pragma arm section code=".ARM.__at_0x8100000" 固定地址的方式,每个文件都需要指定不同的地址以区别。这样极大的不便,因为很多时候,你貌似没必要查看map去计算每个函数的大小吧。。。另外这样也可能造成资源的浪费。 本指望MDK可以像KEIL C那样可以在location页设置一些宏即可定位,无奈没有这个功能。转到最后还是走回了分散加载的路子。大家讨论的比较多,但是都比较泛泛,网络上能找到的,基本一个样子,抄来抄去。 查了半天帮助文档,经过几天的尝试,总算摸清了一点。现在分享给大家,希望有人可以一起讨论。 首先:我的目的是把我的代码分成两个段,BSP和APP彻底分开!但是我每部分代码都有好多的文件,所以不可能我在每个文件都加上一个函数属性。 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// sct文件: 1. LR_IROM1 0x08000000 0x00020000 { ; load region size_region ; Code 1 ER_IROM1 0x08000000 0x00000400 { ; load addr' = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } ; Code 2 ; Code 1~Code 2之间用0填充 ER_IROM2 0x08000500 FIXED { ; load addr= execution address .ANY (my_code) } ; RAM RW_IRAM1 0x20000000 0x00010000 { ; RW data .ANY (+RW +ZI) } } 在一个数据段内定义分区, 必须加入"FIXED"修饰 加入 FIXED 修饰之后可以固定段(my_code)的地址 但是现在中间部分都会放入 0x0000000 初始化 2. LR_IROM1 0x08000000 0x00000400 { ; load region size_region ; Code 1 ER_IROM1 0x08000000 0x00000400 { ; load addr'= execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } ; RAM RW_IRAM1 0x20000000 0x00010000 { ; RW data .ANY (+RW +ZI) } } LR_IROM1 0x08000500 0x00010000 { ; load region size_region ; Code 2 ER_IROM2 0x08000500 { ; load addr'=execution address .ANY (my_code) } } 上述方式可以定义段的位置, 而且不会出现全是0的空段. 在hex文件自动分区处理. 这样的话将数据分为两个数据段处理. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 上述第二种方式可用。 它可以直接把代码分成两个段。第一种方式必须使用FIXED之后才能把第二个段定位,但是他中间是填充的模式(还是一个段)。 需要注意的是: 1. map文件大多是对的,但是hex不一定对。 2. 编译之后必须验证hex文件的正确性。 3. 很多现有的hex2bin的工具不能转换扩展的hex格式。 4. 建议自己写一个hex2bin的工具,把你分的段分别转换成两个文件。分开烧录(主要是升级使用),这样远程升级的代码量会变小。 其实上述想法主要是来源于近期对Freesacle MCU的研究。他的函数都需要指定代码段的地址。虽然麻烦,但是也有一定的方便性。 今天就写到这里,祝大家周末愉快!