本帖最后由 idiy 于 2019-11-25 14:18 编辑
链接脚本是由 MCUXPresso IED 自动生成,在 Debug 或者 Release 目录下,这取决于项目的配置。
默认映像布局如下:
几点说明: - 地址自下往上增长
- 4个存储块
- FLASH:地址范围 0x0000 0000 - 0x0007 FFFF
- 中断向量表
- 可运行代码
- 初始化为非零值的变量初始值
- 常量变量
- SRAMX:地址范围 0x0400 0000 - 0x0400 7FFF
- SRAM UPPER:地址范围 0x2000 0000 - 0x2002 7FFF
- 默认变量存储区
- 初始化为非0值的变量
- 初始化为0值的变量
- 未初始化变量
- 堆(heap)在 BSS 段之后,向上增长
- 栈(stack)在存储器的顶端向下生长
- 指定的可运行代码
- USB RAM:地址范围 0x4010 0000 - 0x4010 1FFF
- 启动时,DATA 被拷贝到 SRAM,并且将 BSS 初始化为0
存储器配置可使用存储器配置编辑器设置,Project Properties -> C/C++ Build -> MCU settings,打开如下:
修改 heap 和 stackProject Properties -> C/C++ Build -> Settings -> MCU Linker -> Managed Linker Scripts
在源代码里指定放置的代码和数据在源代码里通过 IDE 提供的宏来完成放置代码和数据到不同的存储区。源代码里需要增加一行:
- #include <cr_section_macros.h>
复制代码
这里提供一个例子,更多的用法打开 cr_section_macros.h 参考使用。 连接脚本中有以下一段:
- .data_RAM2 : ALIGN(4)
- {
- FILL(0xff)
- PROVIDE(__start_data_RAM2 = .) ;
- *(.ramfunc.$RAM2)
- *(.ramfunc.$SRAMX)
- *(.data.$RAM2)
- *(.data.$SRAMX)
- *(.data.$RAM2.*)
- *(.data.$SRAMX.*)
- . = ALIGN(4) ;
- PROVIDE(__end_data_RAM2 = .) ;
- } > SRAMX AT>PROGRAM_FLASH
复制代码
为了将数据放置到这个存储段,使用了 __DATA 宏,如下:
- // create an unitialised 1k buffer in RAM2
- __DATA(RAM2) char data_buffer[1024];
复制代码
使用 FreeMarker 链接脚本模板修改参数IDE 内置了 FreeMarker 模板引擎。在编译的时候,IDE 调用 FreeMarker ,并将数据模型传递给 FreeMarker 。数据模型描述了目标的存储器布局和根模板,根模板被处理并生成链接脚本。根据本包含了更多的组件模板,这个结构使得链接脚本可以拆分成不同的组件,用户可以为某个组件提供自己的模板而不必修改所有的链接脚本。
在项目文件下建立 linkscripts 目录,将修改好的连接器脚本模板放到这个目录下,然后编译。 这里也举一个例子。我想对 bss 进行绝对定位,所以需要修改连接器脚本。在安装目录\ide\Wizards\linker下,复制main_bss_section.ldt到 linkscripts 目录下,内容如下:
- /* MAIN BSS SECTION */
- .bss 0x20010000:
- {
- . = ALIGN(${bss_align}) ;
- _bss = .;
- KEEP(*(.bss.test))
- <#include "extrasections_bss.ldt">
- <#include "main_bss.ldt">
- *(COMMON)
- . = ALIGN(${bss_align}) ;
- _ebss = .;
- PROVIDE(end = .);
- } > ${DATA}
复制代码
在源代码里,定义如下数组:
- __attribute__ (section(".bss.test"))uint8_t testbuf[4096];
复制代码
这样 testbuf 数组的绝对地址就定位到了 0x20010000 。
|