周末卷起来,讲个知识点很散的LD文件,这东西难度完全看原来的LD文件怎么写,我们顶多就是改改,从零开始写的话,人都要到异世界生活了。
说在前面
它不像代码一样都是要定义的,大部分都是标号,没定义过的标号第一次出现就是给他定义。
它的注释一般是C语言那种/**/,其他的不知道能不能用
它有几个大块,花括号{}外面部分、MEMORY部分、SECTIONS部分、其他带花括号的部分。
花括号{}外面部分
这些比较简单,就是一些宏定义。
ENTRY入口地址
ENTRY(Reset_Handler)
以Reset_Handler作为进程执行的第一条用户空间的指令在进程地址空间的地址,简单来说就是代码从这里开始执行,Reset_Handler一般在startup之类的汇编文件里面写着。
DEFINED检查定义
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x00000400;
DEFINED(heap_size) 检查__heap_size__是否已经被定义,如果有定义就返回1,没定义就返回0。但是这里后面跟着? heap_size : 0x00000400;意义就变了,变成了像C语言一样"DEFINED(heap_size) ? heap_size : 0x00000400"成了一个整体。
如果__heap_size__有定义就返回__heap_size__的值,没定义就返回0x00000400。
MEMORY部分
就是MEMORY然后用花括号括住的部分,像刻光盘一样,给你的芯片分个区,这里仅仅只是分区,不会塞东西进去。
MEMORY
{
iROM_0 : ORIGIN = 0x00000000, LENGTH = 1206k
iRAM_0 : ORIGIN = 0x04000000, LENGTH = 32k
}
有像上面这样写的最简单的,分个iROM_0区域,0x00000000开始,长度为1206k。
MEMORY
{
/* Flash */
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x000EBBF0
/* SRAM */
m_data_2 (RW) : ORIGIN = 0x1FFF4800, LENGTH = 0x0001A000
MagicFlag (RW) : ORIGIN = 0x2000EB00, LENGTH = 0x00000500
}
有像这样写得详细一点的,分开flash和RAM区域,还标注清楚权限。
SECTIONS部分
SECTIONS是最重要的,不仅细化了MEMORY的分区,还能嵌套别的{}。SECTIONS里面的{}也叫SECTIONS。
SECTIONS
{
/* Start of internal ROM area (iROM_0) */
.intvect align (512) :>iROM_0 /* start of interrupt vector */
.intvect_end 0x00200 :>. /* end of interrupt vector */
EIINTTBL align (4) :>.
.text align(4) :>. /* program code area */
.romdata ROM(.data) :>. /* constant data to initialize variables (copied to RAM at startup)*/
.romzdata ROM(.zdata) :>. /* constant data to initialize variables in ZDA area (copied to RAM at startup)*/
__top_of_iROM_0 = MEMENDADDR(iROM_0);
}
这里只提取了iROM_0的部分,我们逐句解析。
.intvect align (512) :>iROM_0
.intvect_end 0x00200 :>.
EIINTTBL align (4) :>.
.text align(4) :>. /* program code area */
先分了个叫".intvect"的中断向量表的区域出来,这里的SECTIONS名前面都要加点号。align是个对齐的命令,要开512字节的空间并且将里面中断向量表的内容对齐。:>就是放入的意思。把这512字节放到iROM_0里面,也就是上面的MEMORY里面的首地址0x00000000。
.就是当前地址的意思,由于上面已经占用了512字节,也就是0x200,那么下面的.会自动向后移动512字节。那就是把intvect_end放到0x200的位置。
后面的自然都懂
.romdata ROM(.data) :>. /* constant data to initialize variables (copied to RAM at startup)*/
.romzdata ROM(.zdata) :>. /* constant data to initialize variables in ZDA area (copied to RAM at startup)*/