当前位置: 首页 > news >正文

内存分配基础:修改SCT文件的简单例子

一个简单例子,熟悉最基本的语法,有个初步的理解

一、SCT文件修改

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************;片上Flash
LR_IROM1   0x08000000 0x00100000  {    ; load region size_region  0x08000000是片上Flash的首地址,表示程序的存放地址ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address  ER_IROM1表示运行时从哪里开始执行程序*.o (RESET, +First) ;*通配符,匹配所有文件,*.o 则表示所有以.o结尾的文件*(InRoot$$Sections) ;表示系统初始化文件即C库.ANY (+RO)  ;.ANY表示所有文件,但是是*之后的.ANY (+XO)}RW_IRAM1 0x20000000 0x00020000  {.ANY (+RW +ZI)};FSMC外部总线,运行时才有,输入加载区域; 1、FPGA区域FPGA_ADC_REG 0x60000000 UNINIT 0x00000010  {  ; adc data*(.fpga_adc_reg)  ; 确保段名fpga_adc_reg与代码中一致,*通配符,匹配所有文件}FPGA_PWM_REG 0x60000010 UNINIT 0x00000010  {  ; pwm data*(.fpga_pwm_reg)  ; 确保段名fpga_pwm_reg与代码中一致,*通配符,匹配所有文件}; 2、外部SRAM区域EX_RAM_DATA 0x60008000  0x00004000 { .ANY (+RW +ZI)  ;扩充片上RAM,用于RW和ZI变量,128KB}EX_RAM_DATA_UART 0x6000C000  0x00001000 { ;指定变量存放地址MyUart.o (+RW +ZI)  ;MyUart.c文件中用到的所有RW和ZI数据都放在这个地址段0x0x6000C000 ~ 0x0x6000D000}EX_RAM_DATA_GPIO 0x6000D000  0x00001000 { MyGpio.o  (+RW +ZI) ;MyGpio.c文件中用到的所有RW和ZI数据都放在这个地址段0x0x6000D000 ~ 0x0x6000E000}EX_RAM_DATA_USER 0x6000E000  0x00001000 { *(.my_data_user) ;*通配符,匹配所有文件,包括数据和代码}EX_RAM_DATA_TEST 0x6000F000  0x00001000 { *(.my_data_test)}EX_RAM_CODE 0x60010000  0x00080000 { ;运行起来时将程序复制到RAM区域,运行更快,256KB*(.copy_code)}; ... 加载域可以在这一直划分扩展下去
};片外Flash,比如QSPI型,将其划分成两段使用
EX_ROM_PART1 0x08100000   0x00080000 {  ;表示程序的存放地址EX_ROM1    0x08100000   0x00080000   {     ;表示程序运行起来后从哪个地址开始执行MyUart.o (+RO)  ;MyUart.c文件中所有RO即RO数据和Code都放在这个地址段0x08100000 ~ 0x08180000MyGpio.o (+RO)  ;MyGpio.c文件中所有RO即RO数据和Code都放在这个地址段0x08100000 ~ 0x08180000}}EX_ROM_PART2 0x08180000   0x00080000 {EX_ROM2    0x08180000   0x00080000   {     ;表示程序运行起来后从哪个地址开始执行MyUart.o (ex_flash_uart_code)  ;为MyUart.c文件分配一个代码存储段ex_flash_uart_code,只能存放MyUart.c中的代码*.o(ex_flash_all_code)         ;为所有.c文件分配一个代码存储段ex_flash_all_code}}
  1. 加载区域表示代码和数据下载到芯片时存储到哪段地址,可以存储到片上Flash,也可以存储到片外Flash,也可以存储到RAM里。
  • 对于代码,为只读类型,运行时无法更改,因此存储在Flash中即加载区域是Flash地址段。
  • 对于数据,其分成几类:
    • 对于RO只读数据,比如const类型、字符串等等,其存储在Flash,因此加载区域也是Flash地址段;
    • 对于RW读写数据,比如.data,如果其有初值,那么初值要存放在Flash中,运行时先从Flash中取出初值对RW数据进行赋值,然后运行时RW数据的访问地址是在RAM里,也就是RW数据的加载区域是Flash地址段,执行区域是RAM地址段;
    • 对于ZI数据,比如.bss和stack、heap,表示初始化为零的全局变量,因此无需在Flash中存放初值,也就无所谓加载区域,只有执行区域,执行区域也就是程序运行时,如果要访问这个变量,要去哪个地址段寻找。
  1. 执行区域表示上电运行后程序和数据从哪个地址开始执行
  • 对于代码:也就是从哪个地址开始读取代码语句并执行,一般是程序存储在哪里,就从哪里执行,代码的执行区域和加载区域保持一致。
  • 对于数据:表示程序运行起来后,去哪个地址可以访问数据,
  • 对于RO数据,例如const,需要存储在Flash中,因此其执行区域地址就处在Flash中,对应到ER_IROM1里的这个内存分配语句 .ANY (+RO) ;.ANY表示所有文件,但是是*之后的,程序运行起来后也是去Flash地址段访问const变量,因此其执行区域也是Flash地址段,两个区域保持一致
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address  ER_IROM1表示运行时从哪里开始执行程序*.o (RESET, +First) ;*通配符,匹配所有文件,*.o 则表示所有以.o结尾的文件*(InRoot$$Sections) ;表示系统初始化文件即C库.ANY (+RO)  ;.ANY表示所有文件,但是是*之后的.ANY (+XO)}
  • 对于RW数据,如果初值不为零,那么初值需要存储到Flash中(即使初值为零,加载区域似乎也是Flash段),则其加载区域是Flash地址段,运行时访问RW数据则要去RAM里,因此执行区域是RAM地址段。例如

(1)在MyUart.c中定义一个RW变量uart_baud,带有非零初始值,注意这里是volatile类型,会有点不同,会变成RW类型。没有volatile修饰则就是RO类型

volatile const unsigned int uart_baud[2] = {9600,115200};

(2)修改SCT文件,将MyUart.c中的RW变量存放到0x6000C000地址

  EX_RAM_DATA_UART 0x6000C000  0x00001000 { ;指定变量存放地址MyUart.o (+RW +ZI)  ;MyUart.c文件中用到的所有RW和ZI数据都放在这个地址段0x0x6000C000 ~ 0x0x6000D000}

(3)查看Map文件,确认RW变量uart_baud的地址是0x6000C000,并且可以看到属性是myuart.o(.data),表示是myuart.c文件中的.data变量即RW类型

uart_baud            0x6000c000   Data           8  myuart.o(.data)

(4)查看Map文件,uart_baud的执行区域是0x6000C000即指定地址,加载区域则是0x08000340,由编译器分配

    Execution Region EX_RAM_DATA_UART (Exec base: 0x6000c000, Load base: 0x08000340, Size: 0x00000018, Max: 0x00001000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x6000c000   0x08000340   0x00000008   Data   RW           39    .data               myuart.o0x6000c008        -       0x00000010   Zero   RW           38    .bss                myuart.o

(5)在MyGpio.c

  • 定义常量gpio_port和全局变量gpio
//没有volatile的const
const unsigned char gpio_port[2] = {1,2}; 
volatile unsigned char gpio[32];
  • 设置常量gpio_port的存储地址是EX_ROM1,设置全局变量gpio的村粗地址是EX_RAM_DATA_GPIO

;RW执行区域EX_RAM_DATA_GPIO 0x6000D000  0x00001000 { MyGpio.o  (+RW +ZI) ;MyGpio.c文件中用到的所有RW和ZI数据都放在这个地址段0x0x6000D000 ~ 0x0x6000E000};片外Flash,比如QSPI型,将其划分成两段使用
EX_ROM_PART1 0x08100000   0x00080000 {  ;表示程序的存放地址EX_ROM1    0x08100000   0x00080000   {     ;表示程序运行起来后从哪个地址开始执行MyUart.o (+RO)  ;MyUart.c文件中所有RO即RO数据和Code都放在这个地址段0x08100000 ~ 0x08180000MyGpio.o (+RO)  ;MyGpio.c文件中所有RO即RO数据和Code都放在这个地址段0x08100000 ~ 0x08180000}}
  • 变量uart_baud的地址是0x6000C000,并且可以看到属性是myuart.o(.data),表示是myuart.c文件中的.data变量即RW类型
  • 变量uart的地址是0x6000c008,并且可以看到属性是myuart.o(.bss),表示是myuart.c文件中的.bss变量即ZI类型
  • 常量gpio_port的地址是0x08100044,并且可以看到属性是mygpio.o(.constdata),表示是mygpio.c文件中的const变量即RO类型
  • 变量gpio的地址是0x6000D000,并且可以看到属性是mygpio.o(.bss),表示是mygpio.c文件中的.bss变量即ZI类型
 gpio_port        0x08100044   Data           2  mygpio.o(.constdata)gpio             0x6000d000   Data          32  mygpio.o(.bss)uart_baud        0x6000c000   Data           8  myuart.o(.data)uart             0x6000c008   Data          16  myuart.o(.bss)

总结:
【1】const变量如果被volatile修饰,则会变成RW类型
【2】ZI类型如果被attribute指定执行地址,则会变成RW类型

  • 对于ZI数据,如果没有通过SCT文件修改其执行地址即编译器自动确定,则其只有执行区域,没有加载区域,但如果通过SCT文件修改了其执行区域,则似乎变成了RW类型,就会出现加载区域,例如

(1)在main.c中定义两个初值为零的全局变量,可读可写

unsigned char test_i;
__attribute__((section(".fpga_adc_reg"))) volatile ST_REG ADC_REG[16];
__attribute__((section(".fpga_pwm_reg")))  ST_REG PWM_REG[16]; 

(2)修改SCT文件,将ADC_REG存放到指定地址0x60000000

  FPGA_ADC_REG 0x60000000 UNINIT 0x00000010  {  ; adc data*(.fpga_adc_reg)  ; 确保段名fpga_adc_reg与代码中一致,*通配符,匹配所有文件}FPGA_PWM_REG 0x60000010 UNINIT 0x00000010  {  ; pwm data*(.fpga_pwm_reg)  ; 确保段名fpga_pwm_reg与代码中一致,*通配符,匹配所有文件}

(3)查看Map文件,test_i 由编译器自动分配,分配到了片上RAMADC_REG由用户指定,分配到0x60000000地址

 test_i          0x20000000   Data           1  main.o(.data)ADC_REG         0x60000000   Data          16  main.o(.fpga_adc_reg)PWM_REG         0x60000010   Data          16  main.o(.fpga_pwm_reg)

(4)查看Map文件,test_i没有加载区域,只有执行区域0x20000000ADC_REG既有加载区域0x08000354,又有执行区域0x60000000

    Execution Region FPGA_ADC_REG (Exec base: 0x60000000, Load base: 0x08000354, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x60000000   0x08000354   0x00000010   Data   RW            4    .fpga_adc_reg       main.oExecution Region FPGA_PWM_REG (Exec base: 0x60000010, Load base: 0x08000354, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x60000010   0x08000354   0x00000010   Data   RW            5    .fpga_pwm_reg       main.o
  1. SCT文件的基础语法
语法说明
LR_IROM1加载域(Load Region)名称,名字自定义
0x08000000加载域起始地址即程序和数据存放的起始地址
0x00080000加载域的空间大小即留给程序和数据的最大存储空间
ER_IROM1执行域(Execution Region)名称,名字自定义
*.o *表示通配符,*.o 表示所有以.o为结尾的文件
*.o (RESET, +First)存放所有.o文件时将 RESET 段(中断向量表)的变量放在最开头的位置,其他.o存放顺序不做严格要求
*(InRoot$$Sections)表示所有的系统初始化代码即C库的初始化代码(如 __main
.ANY (+RO)代表程序里用到的所有只读(Read-Only)数据
.ANY (+RW +ZI)代表程序里用到的所有可读写(RW)和零初始化(ZI)数据
+ZI代表程序里用到的Zero-Initialized 数据(如未初始化的全局变量.bss、stack、heap
MyGpio.o (+RO)代表MyGpio.c文件里用到的所有只读(Read-Only)数据
MyGpio.o (gpio_section)代表为MyGpio.c划分出一个段即名字是gpio_section,用于存放MyGpio.c文件中的数据或代码
* (.all_section)代表为所有文件划分出一个段即名字是.all_section,所有文件都可以往这个段放数据或者代码

二、MyUart.c文件

volatile const unsigned int uart_baud[2] = {9600,115200};volatile unsigned char uart[16];void uart_test()
{for(unsigned char i = 0; i < 16; i++){uart[i] = i + uart_baud[0];}}__attribute__((section("ex_flash_uart_code"))) void uart_ex_flash()
{uart_test();for(unsigned char i = 0; i < 16; i++){uart[i]--;}}

三、MyGpio.c文件

volatile const unsigned char gpio_port[2] = {1,2};volatile unsigned char gpio[32];void gpio_test()
{for(unsigned char i = 0; i < 32; i++){gpio[i] = i*2 + gpio_port[0];}}__attribute__((section("ex_flash_all_code"))) void gpio_ex_flash()
{gpio_test();for(unsigned char i = 0; i < 16; i++){gpio[i]--;}}

四、MyTest.c文件

__attribute__((section(".my_data_user"))) volatile unsigned char user[10];__attribute__((section(".my_data_test"))) volatile unsigned char test[20];__attribute__((section("ex_flash_all_code"))) void my_test()
{for(unsigned char i = 0; i < 10; i++){user[i] = i*2;test[i] = i*3;}}

五、主函数里要调用


typedef struct
{unsigned char bit0:1;unsigned char bit1:1;unsigned char bit2:1;unsigned char bit3:1;unsigned char bit4:1;unsigned char bit5:1;unsigned char bit6:1;unsigned char bit7:1;
}ST_BITS; //位域,按位访问typedef union
{unsigned char all;ST_BITS       bits;
}ST_REG; //按位或者整体访问__attribute__((section(".fpga_adc_reg"))) volatile ST_REG ADC_REG[16];
__attribute__((section(".fpga_pwm_reg"))) volatile ST_REG PWM_REG[16]; void my_test();
void uart_ex_flash();
void gpio_ex_flash();int main(void)
{	unsigned char i= 0;	/*   1、分散加载文件指定FPGA变量存放地址    */for(i = 0; i<16;i++){ADC_REG[i].all=i;PWM_REG[i].bits.bit0 = i+0;}/*   2、分散加载文件测试    */my_test();uart_ex_flash();gpio_ex_flash();while(1){}}

一定要调用这些变量和函数,否则编译器会将其优化移除,也就看不到存储到指定地址的效果了

六、查看Map表

6.1 Memory Map of the image

  1. 程序和只读变量的加载区域和执行区域一致,都是0x08000000
Image Entry point : 0x08000189Load Region LR_IROM1 (Base: 0x08000000, Size: 0x0000036c, Max: 0x00100000, ABSOLUTE)Execution Region ER_IROM1 (Exec base: 0x08000000, Load base: 0x08000000, Size: 0x00000320, Max: 0x00100000, ABSOLUTE)
    Execution Region ER_IROM1 (Exec base: 0x08000000, Load base: 0x08000000, Size: 0x00000320, Max: 0x00100000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x08000000   0x08000000   0x00000188   Data   RO           30    RESET               startup_stm32f40xx.o0x08000188   0x08000188   0x00000000   Code   RO           90  * .ARM.Collect$$$$00000000  mc_w.l(entry.o)0x08000188   0x08000188   0x00000004   Code   RO           93    .ARM.Collect$$$$00000001  mc_w.l(entry2.o)0x0800018c   0x0800018c   0x00000004   Code   RO           96    .ARM.Collect$$$$00000004  mc_w.l(entry5.o)0x08000190   0x08000190   0x00000000   Code   RO           98    .ARM.Collect$$$$00000008  mc_w.l(entry7b.o)0x08000190   0x08000190   0x00000000   Code   RO          100    .ARM.Collect$$$$0000000A  mc_w.l(entry8b.o)0x08000190   0x08000190   0x00000008   Code   RO          101    .ARM.Collect$$$$0000000B  mc_w.l(entry9a.o)0x08000198   0x08000198   0x00000004   Code   RO          108    .ARM.Collect$$$$0000000E  mc_w.l(entry12b.o)0x0800019c   0x0800019c   0x00000000   Code   RO          103    .ARM.Collect$$$$0000000F  mc_w.l(entry10a.o)0x0800019c   0x0800019c   0x00000000   Code   RO          105    .ARM.Collect$$$$00000011  mc_w.l(entry11a.o)0x0800019c   0x0800019c   0x00000004   Code   RO           94    .ARM.Collect$$$$00002712  mc_w.l(entry2.o)0x080001a0   0x080001a0   0x00000024   Code   RO           31    .text               startup_stm32f40xx.o0x080001c4   0x080001c4   0x00000024   Code   RO          109    .text               mc_w.l(init.o)0x080001e8   0x080001e8   0x00000002   Code   RO            1    i.SystemInit        main.o0x080001ea   0x080001ea   0x0000000e   Code   RO          113    i.__scatterload_copy  mc_w.l(handlers.o)0x080001f8   0x080001f8   0x00000002   Code   RO          114    i.__scatterload_null  mc_w.l(handlers.o)0x080001fa   0x080001fa   0x0000000e   Code   RO          115    i.__scatterload_zeroinit  mc_w.l(handlers.o)0x08000208   0x08000208   0x00000088   Code   RO            2    i.main              main.o0x08000290   0x08000290   0x00000090   Data   RO          111    Region$$Table       anon$$obj.o
  1. STACK属于ZI变量,定义在启动文件里,这里是由编译器自动分配地址,分配到起始地址0x20000008,栈所在空间大小是0x00000400。也可以修改SCT文件,达到用户指定其地址的效果。
Stack_Size      EQU     0x00000400AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
    Execution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x08000350, Size: 0x00000408, Max: 0x00020000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x20000000   0x08000350   0x00000001   Data   RW            3    .data               main.o0x20000001   0x08000351   0x00000007   PAD0x20000008        -       0x00000400   Zero   RW           29    STACK               startup_stm32f40xx.o
  1. 程序和SCT文件配合将变量ADC_REGPWM_REG存放到指定地址段,修改了执行地址,变成了RW变量,RW变量有加载区域和执行区域。ADC_REG的执行区域是0x60000000即去0x60000000地址可以访问到ADC_REG变量,加载区域是0x08000320,即上电运行时先从Flash地址0x08000320取数据赋值给ADC_REG变量作为初值。
__attribute__((section(".fpga_adc_reg"))) volatile ST_REG ADC_REG[16];
__attribute__((section(".fpga_pwm_reg"))) volatile ST_REG PWM_REG[16];  
    Execution Region FPGA_ADC_REG (Exec base: 0x60000000, Load base: 0x08000320, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x60000000   0x08000320   0x00000010   Data   RW            3    .fpga_adc_reg       main.oExecution Region FPGA_PWM_REG (Exec base: 0x60000010, Load base: 0x08000330, Size: 0x00000010, Max: 0x00000010, ABSOLUTE, UNINIT)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x60000010   0x08000330   0x00000010   Data   RW            4    .fpga_pwm_reg       main.o
  1. 修改SCT文件划分出段EX_RAM_DATA ,用于存放运行时的任意RW和ZI数据,用于补充片上RAM空间不足的问题。但这个程序片上RAM空间足够,因此编译器没有将变量放到段EX_RAM_DATA,编译时也就报了个警告:No section assigned to this execution region
  EX_RAM_DATA 0x60008000  0x00004000 { .ANY (+RW +ZI)  ;扩充片上RAM,用于RW和ZI变量,128KB}
    Execution Region EX_RAM_DATA (Exec base: 0x60008000, Load base: 0x08000340, Size: 0x00000000, Max: 0x00004000, ABSOLUTE)**** No section assigned to this execution region ****
  1. MyUart.c文件中的RW和ZI变量,即uart_bauduart存放到段EX_RAM_DATA_UART,此变量有加载地址和执行地址
volatile const unsigned int uart_baud[2] = {9600,115200};
volatile unsigned char uart[16];
  1. MyGpio.c文件中的RW和ZI变量,即gpio_portgpio存放到段EX_RAM_DATA_GPIO,此变量有加载地址和执行地址
volatile const unsigned char gpio_port[2] = {1,2};
volatile unsigned char gpio[32];
  1. MyTest.c文件中的RW和ZI变量,即user通过attribute指令存放到段.my_data_usertest通过attribute指令存放到段.my_data_test,此变量有加载地址和执行地址
__attribute__((section(".my_data_user"))) volatile unsigned char user[10];
__attribute__((section(".my_data_test"))) volatile unsigned char test[20];
    Execution Region EX_RAM_DATA_UART (Exec base: 0x6000c000, Load base: 0x08000340, Size: 0x00000018, Max: 0x00001000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x6000c000   0x08000340   0x00000008   Data   RW           39    .data               myuart.o0x6000c008        -       0x00000010   Zero   RW           38    .bss                myuart.oExecution Region EX_RAM_DATA_GPIO (Exec base: 0x6000d000, Load base: 0x08000348, Size: 0x00000024, Max: 0x00001000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x6000d000   0x08000348   0x00000002   Data   RW           59    .data               mygpio.o0x6000d002   0x0800034a   0x00000002   PAD0x6000d004        -       0x00000020   Zero   RW           58    .bss                mygpio.oExecution Region EX_RAM_DATA_USER (Exec base: 0x6000e000, Load base: 0x0800034c, Size: 0x0000000c, Max: 0x00001000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x6000e000   0x0800034c   0x0000000a   Data   RW           78    .my_data_user       mytest.oExecution Region EX_RAM_DATA_TEST (Exec base: 0x6000f000, Load base: 0x08000358, Size: 0x00000014, Max: 0x00001000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x6000f000   0x08000358   0x00000014   Data   RW           77    .my_data_test       mytest.o
  1. 未在此段存放数据或代码,因此报了告警:No section assigned to this execution region
    Execution Region EX_RAM_CODE (Exec base: 0x60010000, Load base: 0x0800036c, Size: 0x00000000, Max: 0x00080000, ABSOLUTE)**** No section assigned to this execution region ****
  1. 修改SCT文件划分出了片外Flash段,用于外接Flash设备的情况,可以将一些代码或者RO数据存放到片外Flash,能够灵活启动程序,比如从外部Flash启动程序,并且外部Flash可以做成可插拔替换的形式,那么只需更换外部Flash,就可以执行不同的程序,而无需重新烧写程序。片外Flash划分成两段使用,这是Part1
  • MyUart.c文件中所有RORO数据和Code都放在这个地址段0x08100000 ~ 0x08180000
  • MyGpio.c文件中所有RORO数据和Code都放在这个地址段0x08100000 ~ 0x08180000
i.gpio_test           0x08100000   Section        0  mygpio.o(i.gpio_test)
i.uart_test           0x08100024   Section        0  myuart.o(i.uart_test)
  Load Region EX_ROM_PART1 (Base: 0x08100000, Size: 0x00000044, Max: 0x00080000, ABSOLUTE)Execution Region EX_ROM1 (Exec base: 0x08100000, Load base: 0x08100000, Size: 0x00000044, Max: 0x00080000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x08100000   0x08100000   0x00000024   Code   RO           57    i.gpio_test         mygpio.o0x08100024   0x08100024   0x00000020   Code   RO           37    i.uart_test         myuart.o
  1. 片外Flash划分成两段使用,这是Part2
  • MyUart.c文件分配一个代码存储段ex_flash_uart_code,只能存放MyUart.c中的代码;
  • 为所有.c文件分配一个代码存储段ex_flash_all_code
EX_ROM_PART2 0x08180000   0x00080000     {EX_ROM2    0x08180000   0x00080000   {     ;表示程序运行起来后从哪个地址开始执行MyUart.o (ex_flash_uart_code)  ;为MyUart.c文件分配一个代码存储段ex_flash_uart_code,只能存放MyUart.c中的代码*.o(ex_flash_all_code)         ;为所有.c文件分配一个代码存储段ex_flash_all_code}
}__attribute__((section("ex_flash_uart_code"))) void uart_ex_flash()__attribute__((section("ex_flash_all_code"))) void gpio_ex_flash()
__attribute__((section("ex_flash_all_code"))) void my_test()
 gpio_ex_flash        0x08180001   Thumb Code    30  mygpio.o(ex_flash_all_code)my_test              0x08180025   Thumb Code    30  mytest.o(ex_flash_all_code)uart_ex_flash        0x0818004d   Thumb Code    30  myuart.o(ex_flash_uart_code)
  Load Region EX_ROM_PART2 (Base: 0x08180000, Size: 0x00000070, Max: 0x00080000, ABSOLUTE)Execution Region EX_ROM2 (Exec base: 0x08180000, Load base: 0x08180000, Size: 0x00000070, Max: 0x00080000, ABSOLUTE)Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object0x08180000   0x08180000   0x00000024   Code   RO           56    ex_flash_all_code   mygpio.o0x08180024   0x08180024   0x00000028   Code   RO           76    ex_flash_all_code   mytest.o0x0818004c   0x0818004c   0x00000024   Code   RO           36    ex_flash_uart_code  myuart.o

6.2 Image Symbol Table

    i.main                                   0x08000208   Section        0  main.o(i.main)i.gpio_test                              0x08100000   Section        0  mygpio.o(i.gpio_test)i.uart_test                              0x08100024   Section        0  myuart.o(i.uart_test).constdata                               0x08100044   Section        2  mygpio.o(.constdata)ex_flash_all_code                        0x08180000   Section        0  mygpio.o(ex_flash_all_code)ex_flash_all_code                        0x08180024   Section        0  mytest.o(ex_flash_all_code)ex_flash_uart_code                       0x0818004c   Section        0  myuart.o(ex_flash_uart_code).data                                    0x20000000   Section        1  main.o(.data)STACK                                    0x20000008   Section     1024  startup_stm32f40xx.o(STACK).fpga_adc_reg                            0x60000000   Section       16  main.o(.fpga_adc_reg).fpga_pwm_reg                            0x60000010   Section       16  main.o(.fpga_pwm_reg).data                                    0x6000c000   Section        8  myuart.o(.data).bss                                     0x6000c008   Section       16  myuart.o(.bss).bss                                     0x6000d000   Section       32  mygpio.o(.bss).my_data_user                            0x6000e000   Section       10  mytest.o(.my_data_user).my_data_test                            0x6000f000   Section       20  mytest.o(.my_data_test)
    main                                     0x08000209   Thumb Code   146  main.o(i.main)Region$$Table$$Base                      0x080002b0   Number         0  anon$$obj.o(Region$$Table)Region$$Table$$Limit                     0x08000340   Number         0  anon$$obj.o(Region$$Table)gpio_test                                0x08100001   Thumb Code    26  mygpio.o(i.gpio_test)uart_test                                0x08100025   Thumb Code    24  myuart.o(i.uart_test)gpio_port                                0x08100044   Data           2  mygpio.o(.constdata)gpio_ex_flash                            0x08180001   Thumb Code    30  mygpio.o(ex_flash_all_code)my_test                                  0x08180025   Thumb Code    30  mytest.o(ex_flash_all_code)uart_ex_flash                            0x0818004d   Thumb Code    30  myuart.o(ex_flash_uart_code)test_i                                   0x20000000   Data           1  main.o(.data)__initial_sp                             0x20000408   Data           0  startup_stm32f40xx.o(STACK)ADC_REG                                  0x60000000   Data          16  main.o(.fpga_adc_reg)PWM_REG                                  0x60000010   Data          16  main.o(.fpga_pwm_reg)uart_baud                                0x6000c000   Data           8  myuart.o(.data)uart                                     0x6000c008   Data          16  myuart.o(.bss)gpio                                     0x6000d000   Data          32  mygpio.o(.bss)user                                     0x6000e000   Data          10  mytest.o(.my_data_user)test                                     0x6000f000   Data          20  mytest.o(.my_data_test)
http://www.xdnf.cn/news/935713.html

相关文章:

  • JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
  • 【Ftrace 专栏】Ftrace 基础使用
  • LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
  • AI 大模型统一集成|Spring AI + DeepSeek 实战接入指南
  • 【教学类-53-02】20250607自助餐餐盘教学版(配餐+自助餐)
  • Windows下用CMake编译DCMTK及配置测试
  • DeepSeek R1 V2 深度探索:开源AI编码新利器,效能与创意并进
  • Argo CD 入门 - 安装与第一个应用的声明式同步
  • IDEA为何一直无法使用超过4g内存
  • 文献阅读:Exploring Autoencoder-based Error-bounded Compression for Scientific Data
  • LSTM-SVM多变量时序预测(Matlab完整源码和数据)
  • VB调用CryReport指南方案
  • JVM——对象模型:JVM对象的内部机制和存在方式是怎样的?
  • 【学习笔记】深入理解Java虚拟机学习笔记——第5章 调优案例分析与实战
  • 第12篇:数据库中间件日志设计与追踪系统落地实践
  • MySQL知识回顾总结----数据库基础
  • 计算机常用快捷键分类汇总,涵盖 Windows、macOS 以及通用软件场景
  • STM32[笔记]--1.前置准备
  • AI系统的构建
  • 基于React 的 AntD 库进行前端开发过程中的问题汇总
  • 空间转录组数据下游分析(二)
  • 玄机——某次行业攻防应急响应(带镜像)
  • Java求职者面试指南:计算机基础与源码原理深度解析
  • 智警杯备赛--机器学习算法实践
  • 深度学习登上Nature子刊!特征选择创新思路
  • C# 表达式和运算符(表达式和字面量)
  • 【JavaScript-Day 35】从 window 到 location,一文掌握浏览器对象模型 BOM
  • Web前端开发:JavaScript中的eval()函数
  • triton学习笔记7: GEMM相关
  • uniapp跳转到webview组件的时候,要注意:移除所有不可见字符(包括零宽空格)