分散加載說明以GD32F103ZE為例,分別用Keil、IAR和Embedded Builder工具實現:將函數放置某個地址、將常量放置某個地址、將函數放在RAM中運行的三種效果。
1、將led_toggle()函數放在0x08040000地址后。
2、將tempbuf[1024]常量放在0x08020000地址后。
3、將void led_flow(void) 函數在RAM中運行,放在0x20008000地址后面。
1.Keil IDE example
1.1.將函數放置某個地址
生成.sct 文件
單擊 MDK 的 Option -> linker 取消勾選“Use memory layout from target Dialog”。
單擊“Scatter file”中的“Edit” ,keil 工程會出現“.sct”文件。
修改.sct 文件,將 512k flash 分成 LR_IROM1 和 LR_IROM2 兩個加載區域,分別為 256K 的 flash。
將 void led_toggle(void)函數添加到 LR_IROM2 地址內。
led.o 表示 led.c 文件生成的.o 文件。led_toggle 表示所添加的函數。
void led_toggle(void)函數需要添加“attribute”,代碼如下。
void led_toggle(void) attribute((section ("led_toggle")));其中“led_toggle”名稱可以任意。
雙擊工程名“Tartget1” 生成.map 文件,查看是否加載成功。
查看.map 文件。led_toggle 函數 在地址 0x08040000 后。說明加載成功。
1.2.將常量放置某個地址
將 tempbuf[1024]放置到 0x08020000,添加如下代碼。此時可以不用修改.sct 文件。const uint8_t tempbuf [1024] attribute((at(0x08020000))) = {0};
查看.map 文件。常量 tempbuf[1024]在地址 0x08020000 后。說明加載成功。
1.3.將函數放置 RAM 中運行
在 led.c 文件將 led_flow(void)申明,代碼添加如下。
void led_flow(void) attribute((section ("led_flow")));
修改.sct 文件,將 mcu 的 64K RAM 分成 RW_IRAM1 和 RW_IRAM2 兩個區,分別32K 大小 。在 LR_IROM2 增加 RW_IRAM2 執行區域和 led_flow 函數,如圖。
查看.map 文件,led_flow 函數在地址 0x20008000 后。說明加載成功。
1.4.將程序中所有 const 快速放置在 data 區域
專門劃分出一塊區域 0x08040000-0x08080000 放置 const 數據
修改 sct 文件如下:
代碼編譯出來效果如下:
2.IAR IDE example
2.1.將函數放置某個地址
打開配置文件.icf
Option -> linker -> config 勾選“override default”。單擊“Edit”進行修改。
修改 icf 文件,將 512K flash 分成 ROM 和 ROM1,各 256K 加載區,添加代碼如下:
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF; define symbol __ICFEDIT_region_ROM1_start__ = 0x08040000; define symbol __ICFEDIT_region_ROM1_end__ = 0x0807FFFF; define region ROM1_region=mem:[from__ICFEDIT_region_ROM1_start__to __ICFEDIT_region_ROM1_end__]
修改 icf 文件,將 void led_toggle(void)函數放置在地址 0x08040000 后,添加代碼如下。
place at address mem:0x08040000 { readonly section led_toggle };
在 led.c 文件中添加函數屬性。添加代碼如下。
void led_toggle(void)@ “led_toggle”其中“led_toggle”名稱可以任意。
生成.map 文件,查看是否加載成功。在 IAR 中 Option -> linker -> List 勾選“generate linker map file”。
查看.map 文件。led_toggle 函數 在地址 0x08040000 后。說明加載成功。
2.2.將常量放置某個地址
將tempbuf[1024]放置到0x08020000,添加如下代碼。此時可以不用修改.icf 文件。const uint8_t tempbuf [1024] attribute((at(0x08020000))) = {0};
查看.map 文件。函數 tempbuf 在地址 0x08020000 后。說明加載成功。
2.3.將函數放在 RAM 中運行
在 led.c 文件設置 led_flow 屬性,添加代碼如下。void led_flow(void) @"led_flow";
修改.sct 文件,將 MCU 的 64K RAM 分成 RAM 和 RW_IRAM1 兩個 區,分別 32K 大小。
將函數從 flash copy 到 RAM 中,添加代碼如下。
initialize by copy { readwrite,section led_flow };
將 void led_flow(void)函數放置地址 0x20008000 后,需要增加如下函數。如圖。
place at address mem:0x20008000 { section led_flow };
查看.map 文件,函數 led_flow 在地址 0x20008000 后說明加載成功。
2.4. 將程序中的 const data 快速的放置到某個區域
相關語法如下:place at address mem:0x08040000 { section .rodata };
運行效果如下:
3. Embedded Builder IDE example
直接使用手動編寫的 ld 文件,在 Embedded Builder 中的的“ Window->ShowView->Project
Explore->ldscripts” 中 雙 擊 gd32f10x_flash.ld 文件或者也可到工程目錄
“GD32F4xx_ScatterLoading_v1.0.0_Eclipse\ldscripts\gd32f4xx_flash.ld”下打開編輯, 代碼下圖所示:
3.1.將函數放置某個地址
將 led_toggle()函數放置在 flash 的 0x08003400 位置
3.2.將常量放置某個地址
將常量數組放置在 flash 的 0x08003000 地址,
在 gd32f10x_flash.ld 中 添加如下語句
3.3.將函數放置 RAM 中運行
將函數 gd_eval_led_toggle 放在 SRAM 中運行,在 gd32f10x_flash.ld 添加如下代碼
/* memory map */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K RAM1 (xrw) : ORIGIN = 0x20000400, LENGTH = 1K } ENTRY(Reset_Handler) SECTIONS { __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; /* ISR vectors */ .vectors : { . = ALIGN(4); KEEP(*(.vectors)) . = ALIGN(4); __Vectors_End = .; __Vectors_Size = __Vectors_End - __gVectors; } >FLASH /* Load .sram1_text and gd32f4xx_it.o to RAM1 starting address */ _ram1_text = 0x08003500; .ram1_text : AT(_ram1_text) { . = ALIGN(4); _sram1_text = .; *(.sram1_text) *(.sram1_text*) *gd32f10x_it.o(.text .text.*) . = ALIGN(4); _erma1_text = .; } > RAM1
上述代碼將.sram1_text 段和 gd32f10x_it.o 文件加載到 RAM1(0x20005000)起始地址處,在啟動文件startup_gd32f10x_md.S 中加入如下匯編代碼
CopyData3: ldr r3, =_ram1_text ldr r3, [r3, r1] str r3, [r0, r1] adds r1, r1, #4 b LoopCopyDataInit2 LoopCopyDataInit2: ldr r0, =_sram1_text ldr r3, =_erma1_text adds r2, r0, r1 cmp r2, r3 bcc CopyData3
上述匯編代碼完成將.sram1_text 段和 gd32f10x_it.o 文件由 flash 搬運到指定的 ram 地址中。
在函數前加上attribute ((section(".sram1_text")))。
/*! \brief toggle selected led \param[in] lednum: specify the led to be toggled \arg LED2 \arg LED3 \arg LED4 \arg LED5 \param[out] none \retval none */ __attribute__ ((section(".sram1_text"))) void gd_eval_led_toggle(led_typedef_enum lednum) { gpio_bit_write(GPIO_PORT[lednum], GPIO_PIN[lednum], (bit_status)(1-gpio_input_bit_get(GPIO_PORT[lednum], GPIO_PIN[lednum]))); }
調試運行驗證函數地址
-
單片機
+關注
關注
6037文章
44558瀏覽量
635226 -
嵌入式
+關注
關注
5082文章
19123瀏覽量
305150 -
IAR
+關注
關注
5文章
352瀏覽量
36678 -
開發板
+關注
關注
25文章
5050瀏覽量
97456 -
keil
+關注
關注
68文章
1213瀏覽量
166875
發布評論請先 登錄
相關推薦
評論