2016-11-02 25 views
1

Фон

Я пытаюсь использовать специальный раздел 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)?

ответ

0

Определив ваш раздел как «.pma», скорее всего, дал ему тип «PROGBITS» (проверьте с помощью readelf), который указывает раздел, который будет загружен в цель.

Что вам нужно/нужно определить раздел, который не нужно загружать на цель, например раздел «.bss», который имеет тип «NOBITS».

Я часто использую следующее определение раздела, чтобы избежать некоторых буферов в раздел «.bss» (как это замедляет фазы запуска в связи с нулевым инициализационными раздела «.bss»):

static uint8_t uart1_buffer_rx [4096] __ атрибут __ ((раздел (". noinit, \" aw \ ",% nobits @")));

Я не помню, почему я использовал имя «.noinit», но эти разделы появляются после раздела «.bss».

В вашем случае это, вероятно, поможет добавить флаги «aw» и «nobits» после объявления раздела «.pma».