Questions:如何在Eclipse中实现分散加载?
Answer:
修改脚本链接文件可以将某些函数和数据编排到特定的区域内。
-
链接脚本文件一般是放在根目录下的ldscripts文件夹内,后缀为.ld。添加脚本链接文件的方法是“Project -> Properties -> C/C++ Build -> Setting -> Tool Settings -> “GNU ARM Cross C Linker” -> “General” -> 添加脚本链接文件。
-
修改脚本链接文件将某些函数和数据编排到特定的区域内,脚本链接文件可以使用记事本打开。以AT32F413xC(FLASH=256K,SRAM=32K)为例,其划分区块默认如下:
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
r代表read-only,x代表可执行代码,w代表read/write,ORIGIN是该区块的起始地址,LENGTH是该区块的大小。
如果需要将某些函数和数据编排到特定的FLASH区域内,则可以将FLASH划分为几个区域,以下是将FLASH划分为3个区域,可以将函数和数据编排到任意一个区域内。
/* Specify the memory areas */
MEMORY
{
FLASH_1 (rx) : ORIGIN = 0x08000000, LENGTH = 128K
FLASH_2 (rx) : ORIGIN = 0x08020000, LENGTH = 64K
FLASH_3 (rx) : ORIGIN = 0x08030000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
比如需要把算法文件algorithm_1.c和algorithm_2.c内的函数和数据编排到FLASH_2区域内;把算法文件algorithm_3.c和algorithm_4.c内的函数和数据编排到FLASH_3区域内。则需要在SECTIONS添加设置,如下红色部分。完整的脚本链接文件请参考附录1。
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH_1
.algorithm_code1 :
{
. = ALIGN(4);
*algorithm_1.o (.text .text*);
*algorithm_2.o (.text .text*);
. = ALIGN(4);
} > FLASH_2
.algorithm_code2 :
{
. = ALIGN(4);
*algorithm_3.o (.text .text*);
*algorithm_4.o (.text .text*);
. = ALIGN(4);
} > FLASH_3
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(EXCLUDE_FILE (*algorithm_1.o * algorithm_2.o) .text .text*)
*(EXCLUDE_FILE (*algorithm_3.o * algorithm_4.o) .text .text*)
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH_1
- .algorithm_code1和.algorithm_code2是自行命名的 section 名称,用户在实际编写时可以自定义名称。 { } 包含的 .o 文件就是要放进section 内的代码,{ } 末尾的 > FLASH_2 就是将 .algorithm_code1 这个 section 指定到先前定义的 FLASH_2 区块。例如algorithm_1.o、algorithm_2.o就是 algorithm_1.c 、algorithm_2.c这两个 c 代码文档编译后的 object code, 写在这个c 文档里的函数和数据,就全部会被编排到此section 内。假设有10个函数,那 10 个函数就都会被放进来。
注意:
-
.o 文件名前面都要加 * 号, 代表要将这个文件中的全部代码和数据都编排进来;
-
.text 和 .text* 是可执行的代码;
-
section 名称后的冒号与section 名称之间要加空格,如:.algorithm_ code1 :。
-
将.text{ } section指定到FLASH_1 区块。一定要加入 EXECLUDE_FILE这个命令,使用 EXCLUDE_FILE标示的代码就不会被编排到FLASH_1,不然前面第1)点所作的设置就会失效。此区段内的*(.text)和 (.text), 就是告诉 linker 将EXCLUDE_FILE标示以外的代码都放到 .text 这个 section 内。
- 对于AT32F403/AT32F413/AT32F403A/AT32F407等FLASH有零等待和非零等待的MCU,如果需要将某些函数和数据编排到零等待或者非零等待域内,则可以将FLASH划分为2个区域,如下是以AT32F413xC(FLASH=256K,SRAM=32K)为例,可以将函数和数据编排到任意一个区域内。
/* Specify the memory areas */
MEMORY
{
FLASH_ZW (rx) : ORIGIN = 0x08000000, LENGTH = 96K
FLASH_NZW (rx) : ORIGIN = 0x08018000, LENGTH = 160K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH