背景
我試圖利用我的STM32設備上位於地址0x40006000
的特殊部分的SRAM。我在ST的示例代碼中看到的一種做法是僅僅創建指向其內存的值的指針。我想要做的是讓鏈接器爲我管理該部分中的靜態分配。爲什麼objcopy排除一個部分而不是另一個部分?
基本上,我從一些事情是這樣的:
static uint16_t *buffer0 = ((uint16_t *)0x40006000);
static uint16_t *buffer1 = ((uint16_t *)0x40006080);
爲了這樣的事情(我認爲這是遠不易破碎,而不是作爲哈克,雖不如便攜式):
#define _PMA __attribute__((section(".pma"), aligned(2)))
static uint16_t _PMA buffer0[64];
static uint16_t _PMA buffer1[64];
爲了做到這一點,我修改了我的鏈接描述文件,在0x40006000
上有一個名爲「PMA」的新內存,我在其中找到了「.pma」部分,如下所示:
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
PMA (xrw) : ORIGIN = 0x40006000, LENGTH = 1024 /* This is the memory I added */
}
SECTIONS
{
.text
{
..blah blah blah..
} > FLASH
...more sections, like rodata and init_array..
/* Initialized data goes into RAM, load LMA copy after code */
.data
{
..blah blah blah with some linker symbols to denote the start and end..
} >RAM AT> FLASH
.bss
{
..blah blah blah..
} >RAM
.pma /* My new section! */
{
_pma_start = .;
. = ALIGN(2);
*(.pma)
*(.pma*)
} >PMA
}
會發生什麼
因此,這似乎是所有罰款和花花公子,我的東西編譯和地圖顯示我buffer0
和buffer1
確實放置在0x40006000
和0x40006080
。這裏是我的Makefile文件的最後一位的輸出:
arm-none-eabi-gcc obj/usb_desc.o obj/usb_application.o obj/osc.o obj/usb.o obj/main.o obj/system_stm32f1xx.o obj/queue.o obj/list.o obj/heap_1.o obj/port.o obj/tasks.o obj/timers.o obj/startup_stm32f103x6.o -TSTM32F103X8_FLASH.ld -mthumb -mcpu=cortex-m3 --specs=nosys.specs -Wl,-Map,bin/blink.map -o bin/blink.elf
arm-none-eabi-objdump -D bin/blink.elf > bin/blink.lst
arm-none-eabi-size --format=SysV bin/blink.elf
bin/blink.elf :
section size addr
.isr_vector 268 134217728
.text 13504 134218000
.rodata 44 134231504
.ARM 8 134231548
.init_array 8 134231556
.fini_array 4 134231564
.data 1264 536870912
.jcr 4 536872176
.bss 1348 536872180
._user_heap_stack 1536 536873528
.pma 256 1073766400
.ARM.attributes 41 0
.debug_info 26748 0
.debug_abbrev 5331 0
.debug_aranges 368 0
.debug_line 5274 0
.debug_str 8123 0
.comment 29 0
.debug_frame 4988 0
Total 69146
arm-none-eabi-objcopy -R .stack -O binary bin/blink.elf bin/blink.bin
我看到.pma
使用了256個字節,就如我所料。地址看起來也是正確的。現在,當我ls
的bin
目錄,我迎接這樣的:
-rwxr-xr-x 1 kevin users 939548800 Nov 2 00:04 blink.bin*
-rwxr-xr-x 1 kevin users 221528 Nov 2 00:04 blink.elf*
這bin
文件是什麼,我加載到通過OpenOCD的我芯片的閃存。它是從0x08000000開始的閃光的圖像。
旁註:在我意識到它有多大之前,我實際上已經試圖將這個bin文件加載到我的芯片上......這顯然不起作用。
這裏就是我得到的,當我刪除PMA部分:
arm-none-eabi-size --format=SysV bin/blink.elf
bin/blink.elf :
section size addr
.isr_vector 268 134217728
.text 13504 134218000
.rodata 44 134231504
.ARM 8 134231548
.init_array 8 134231556
.fini_array 4 134231564
.data 1392 536870912
.jcr 4 536872304
.bss 1348 536872308
._user_heap_stack 1536 536873656
.ARM.attributes 41 0
.debug_info 26748 0
.debug_abbrev 5331 0
.debug_aranges 368 0
.debug_line 5274 0
.debug_str 8123 0
.comment 29 0
.debug_frame 4988 0
Total 69018
和文件大小是完全按照我期望:
-rwxr-xr-x 1 kevin users 15236 Nov 2 00:09 blink.bin
-rwxr-xr-x 1 kevin users 198132 Nov 2 00:09 blink.elf
問題
據我瞭解,這裏發生的是objcopy
剛剛從0x08000000
到0x400060FF
複製到該bin文件中的所有內容。這顯然不是我想要發生的事情。我預計它會複製閃光燈。
現在,很明顯,我可以只在我的objcopy
命令上說-R .pma
,一切都會很開心。但是,我很好奇的是objcopy
知道不要將.data
複製到二進制映像中。我注意到運行objcopy -R .data
與運行objcopy
的結果完全相同。與.bss
一樣的東西。這告訴我,這是不是在鏈接腳本的命令AT
(這是唯一的真正的區別我可以看到.data
之間.bss
)
我能做些什麼讓我的.pma
部分行爲相同的方式爲.data
或.bss
from objcopy
的角度?或許我正在使用的中間精靈文件中有.data
/.bss
有一些有趣的事情(請參閱上面的鏈接器命令生成elf文件)?