Фон
Я пытаюсь использовать специальный раздел SRAM на моем устройстве STM32, который находится по адресу 0x40006000
. Один из способов сделать это, который я видел в примере кода ST, состоял в том, чтобы просто создать указатели, значение которых оказалось в этом разделе ОЗУ. То, что я пытаюсь сделать, это заставить компоновщик управлять статическими выделениями в этом разделе для меня.Почему objcopy исключает один раздел, но не другой?
В принципе, я хочу от чего-то вроде этого:
static uint16_t *buffer0 = ((uint16_t *)0x40006000);
static uint16_t *buffer1 = ((uint16_t *)0x40006080);
Чтобы что-то вроде этого (который я думаю, далеко менее хрупким, а не как Hacky, хотя и не так портативные):
#define _PMA __attribute__((section(".pma"), aligned(2)))
static uint16_t _PMA buffer0[64];
static uint16_t _PMA buffer1[64];
для того, чтобы достичь этого, я изменил мой компоновщик сценарий, чтобы иметь новую память под названием «PMA» находится на 0x40006000
и я нахожусь в разделе «.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.
Sidenote: Я на самом деле попытался загрузить этот файл 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. Это, очевидно, не то, что я хотел. Я ожидал, что он просто скопирует вспышку.
Теперь, я могу просто сказать -R .pma
на моей команде objcopy
, и все будет счастливо. Однако мне интересно, как objcopy
знает, что не нужно копировать .data
в двоичное изображение. Я заметил, что работающий objcopy -R .data
имеет тот же результат, что и работающий objcopy
без этого. То же самое с .bss
.Это говорит мне, что это не AT
команды в скрипте линкера (что единственное реальное различие я вижу между .data
и .bss
)
Что я могу сделать, чтобы мой .pma
раздела вести себя так же, как .data
или .bss
с точки зрения objcopy
? Что-то интересное происходит с .data
/.bss
в промежуточном файле elf, который я использую, возможно (см. Выше для команды компоновщика, генерирующей файл elf)?