例子:各种数据所存放的段
#define DATA (0x10000000) /* RO-Data */
char const GcChar = 5; /* RO-Data */
char GcStr[] = "string."; /* RW-Data */
char GcZero; /* ZI-Data */
在随意一个MDK工程的listings文件夹中都会生成一个map文件,最底下会有链接信息,可知ROM会包括Code ,RO Data以及RW Data段。其中,前面两个段容易理解,代码段和只读数据段自然是存放在flash中。
==============================================================================
Code (inc. data) RO Data RW Data ZI Data Debug
11080 1488 2976 28 2084 2984889 Grand Totals
11080 1488 2976 28 2084 2984889 ELF Image Totals
11080 1488 2976 28 0 0 ROM Totals
==============================================================================
Total RO Size (Code + RO Data) 14056 ( 13.73kB)
Total RW Size (RW Data + ZI Data) 2112 ( 2.06kB)
Total ROM Size (Code + RO Data + RW Data) 14084 ( 13.75kB)
==============================================================================
由于RT1052没有内置flash,需要外界FLASH以实现程序的存放。再加上外扩RAM的存在,每个板子设计的flash和ram容量大小都不相同,使得在程序链接以及运行时必须根据这些信息以实现程序的链接以及初始化。也就是把不同的代码数据放在不同的存储空间,而且,在程序链接时,会包含有各种各样的域,标准的,自定义的域。
需要使用到自动以分散加载文件的情况:
首先,分散加载的语法遵循 Backus-Naur Form规范.
作者:猫山王
来源:CSDN
原文:https://blog.csdn.net/PINBODEXIAOZHU/article/details/25389441
版权声明:本文为博主原创文章,转载请附上博文链接!
巴科斯范式的内容
在双引号中的字(“word”)代表着这些字符本身。而double_quote用来代表双引号。
在双引号外的字(有可能有下划线)代表着语法部分。
尖括号( < > )内包含的为必选项。
方括号( [ ] )内包含的为可选项。
大括号( { } )内包含的为可重复0至无数次的项。
竖线( | )表示在其左右两边任选一项,相当于"OR"的意思。
::= 是“被定义为”的意思。
基本概念
load_region_name (base_address | ("+" offset)) [attribute_list] [max_size]
"{"
execution_region_description+
"}"
exec_region_name(base_address|"+"offset)[attribute_list][max_size|" "length]
{
input_section_description*
}
module_select_pattern["("input_section_selector(","input_section_selector)*")"]
("+" input_section_attr | input_section_pattern | input_symbol_pattern)
上面介绍了三个分散加载文件的语法,现在先不直接上RT1052复杂的分散加载文件,先来个简单的STM32F103C8T6的分散加载文件,分散加载文件主要由一个加载时域和多个运行时域组成。
LR_IROM1 0x08000000 0x00010000{;定义一个加载时域,域基地址:0x08000000,大小:0x00010000
;这个空间就是STM32flash的实际信息
ER_IROM1 0x08000000 0x00010000 { ;定义第一个一个运行时域,第一个运行时域必须和加载
;时域起始地址相同,否则库不能加载到该时域的
;错误,其域大小一般也和加载时域大小相同
*.o (RESET, +First) ;RESET在启动文件中有定义,为一个异常向量表
*(InRoot$$Sections) ;MDK自动生成的段,主要在_main中执行
.ANY (+RO) ;剩下所有代码段
}
RW_IRAM1 0x20000000 0x00005000 {;定义第二个运行时域,域基地址:0x08000000,大小:0x00005000
.ANY (+RW +ZI) ;所有数据段
}
}
; 外部QSPI FLASH 起始地址:0x60000000
; 存放QSPI FLASH 参数,如几线制的 SPI Flash, SPI 的时钟频率, LUT 查找表, DDR/SDR 模式以及片选 CS管脚的 hold/setup time 等信息
; 0x00001000 = 4KB
#define m_flash_config_start 0x60000000
#define m_flash_config_size 0x00001000
; 存放Image Vector Table(IVT)
#define m_ivt_start 0x60001000
#define m_ivt_size 0x00001000
; 存放中断向量表
#define m_interrupts_start 0x60002000
#define m_interrupts_size 0x00000400
; 程序从这里开始存储
#define m_text_start 0x60002400
#define m_text_size 0x01FFDC00
; ITCM :起始地址:0000_0000 ,大小128KB
; DTCM :起始地址:2000_0000 ,大小128KB
; OCRAM:起始地址:2020_0000 ,大小256KB
; ITCM,128KB,用来存放指令
;#define m_data_start 0x00000000
;#define m_data_size 0x00020000
; DTCM,128KB,用来存放数据
#define m_data_start 0x20000000
#define m_data_size 0x00020000
; OCRAM,256KB,用来存放数据
#define m_data2_start 0x20200000
#define m_data2_size 0x00040000
/* Sizes */
#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
; 0x0400 = 1KB
#define Stack_Size 0x0400
#endif
#if (defined(__heap_size__))
#define Heap_Size __heap_size__
#else
#define Heap_Size 0x0400
#endif
LR_m_rom_config m_flash_config_start m_flash_config_size { ; load region size_region
RW_m_config_text m_flash_config_start m_flash_config_size { ; load address = execution address
* (.boot_hdr.conf, +FIRST)
}
}
LR_m_rom_ivt m_ivt_start m_ivt_size { ; load region size_region
RW_m_ivt_text m_ivt_start m_ivt_size { ; load address = execution address
* (.boot_hdr.ivt, +FIRST)
* (.boot_hdr.boot_data)
* (.boot_hdr.dcd_data)
}
}
LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_size { ; load region size_region
VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
* (RESET,+FIRST)
}
ER_m_text m_text_start m_text_size { ; load address = execution address
* (InRoot$$Sections)
.ANY (+RO)
}
RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
.ANY (+RW +ZI)
* (NonCacheable.init)
* (NonCacheable)
}
ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up
}
ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
}
}
加载域 | 域 | 域描述 |
---|---|---|
0x60000000~0x60000FFF | .boot_hdr_conf | 外部QSPI FLASH 起始地址:0x60000000。存放QSPI FLASH 参数,如几线制的 SPI Flash, SPI 的时钟频率, LUT 查找表, DDR/SDR 模式以及片选 CS管脚的 hold/setup time 等信息 |
0x60001000~0x60001FFF | .boot_hdr.ivt + .boot_hdr.boot_data + .boot_hdr.dcd_data | 存放Image Vector Table(IVT) |
0x60002000~0x600023FF | RESET | 存放中断向量表 |
0x60002400~0x62000000 | InRoot$$Sections + .ANY (+RO) | 程序从这里开始存储 |
0x00000000~0x0001FFFF | ITCM | ITCM 128KB,用来缓存指令。因为在程序连接时不需要,所以没写在scf上 |
0x20000000~0x2001F7FF | DTCM | DTCM,126KB,用来存放数据 |
0x2001F800~0x2001FBFF | Heap | Heap,1KB,系统堆区,往上增长 |
0x2001FC00~0x2001FFFF | Stack | Stack,1KB,系统栈区,往下增长 |
参考文献
C:\Keil_v5\ARM\Hlp\DUI0377G_02_mdk_armlink_user_guide.pdf
分散加载文件浅析-周立功.pdf