前文所述的代码分段,限定比较大,对于使用
#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的研究。他的函数都需要指定代码段的地址。虽然麻烦,但是也有一定的方便性。
今天就写到这里,祝大家周末愉快!
用户403664 2013-12-16 09:46