2017-01-03 3 views
0

Давайте посмотрим на сценарии компоновок STM32F103:Linking и памяти вопросы для STM32F1 микроконтроллеров

/* Entry Point */ 
ENTRY(Reset_Handler) 

/* Highest address of the user mode stack */ 
_estack = 0x20005000; /* End of 20K RAM */ 

/* Generate a link error if heap and stack don't fit into RAM */ 
_Min_Heap_Size = 0;  /* Required amount of heap */ 
_Min_Stack_Size = 0x100; /* Required amount of stack */ 

/* Specify the memory areas */ 
MEMORY 
{ 
    FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 128K 
    RAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 20K 
    MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K 
} 

/* Define output sections */ 
SECTIONS 
{ 
    /* The startup code goes first into FLASH */ 
    .isr_vector : 
    { 
    . = ALIGN(4); 
    KEEP(*(.isr_vector)) /* Startup code */ 
    . = ALIGN(4); 
    } >FLASH 

    /* The program code and other data goes into FLASH */ 
    .text : 
    { 
    . = ALIGN(4); 
    *(.text)   /* .text sections (code) */ 
    *(.text*)   /* .text* sections (code) */ 
    *(.rodata)   /* .rodata sections (constants, strings, etc.) */ 
    *(.rodata*)  /* .rodata* sections (constants, strings, etc.) */ 
    *(.glue_7)   /* Glue arm to thumb code */ 
    *(.glue_7t)  /* Glue thumb to arm code */ 

    KEEP (*(.init)) 
    KEEP (*(.fini)) 

    . = ALIGN(4); 
    _etext = .;  /* Define a global symbols at end of code */ 
    } >FLASH 


    .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH 
    .ARM : { 
    __exidx_start = .; 
     *(.ARM.exidx*) 
     __exidx_end = .; 
    } >FLASH 

    .ARM.attributes : { *(.ARM.attributes) } > FLASH 

    .preinit_array  : 
    { 
    PROVIDE_HIDDEN (__preinit_array_start = .); 
    KEEP (*(.preinit_array*)) 
    PROVIDE_HIDDEN (__preinit_array_end = .); 
    } >FLASH 
    .init_array : 
    { 
    PROVIDE_HIDDEN (__init_array_start = .); 
    KEEP (*(SORT(.init_array.*))) 
    KEEP (*(.init_array*)) 
    PROVIDE_HIDDEN (__init_array_end = .); 
    } >FLASH 
    .fini_array : 
    { 
    PROVIDE_HIDDEN (__fini_array_start = .); 
    KEEP (*(.fini_array*)) 
    KEEP (*(SORT(.fini_array.*))) 
    PROVIDE_HIDDEN (__fini_array_end = .); 
    } >FLASH 

    /* Used by the startup to initialize data */ 
    _sidata = .; 

    /* Initialized data sections goes into RAM, load LMA copy after code */ 
    .data : AT (_sidata) 
    { 
    . = ALIGN(4); 
    _sdata = .;  /* Create a global symbol at data start */ 
    *(.data)   /* .data sections */ 
    *(.data*)   /* .data* sections */ 

    . = ALIGN(4); 
    _edata = .;  /* Define a global symbol at data end */ 
    } >RAM 

    /* Uninitialized data section */ 
    . = ALIGN(4); 
    .bss : 
    { 
    /* This is used by the startup in order to initialize the .bss secion */ 
    _sbss = .;   /* Define a global symbol at BSS start */ 
    __bss_start__ = _sbss; 
    *(.bss) 
    *(.bss*) 
    *(COMMON) 

    . = ALIGN(4); 
    _ebss = .;   /* Define a global symbol at BSS end */ 
    __bss_end__ = _ebss; 
    } >RAM 

    PROVIDE (end = _ebss); 
    PROVIDE (_end = _ebss); 

    /* User_heap_stack section, used to check that there is enough RAM left */ 
    ._user_heap_stack : 
    { 
    . = ALIGN(4); 
    . = . + _Min_Heap_Size; 
    . = . + _Min_Stack_Size; 
    . = ALIGN(4); 
    } >RAM 

    /* MEMORY_bank1 section, code must be located here explicitly   */ 
    /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */ 
    .memory_b1_text : 
    { 
    *(.mb1text)  /* .mb1text sections (code) */ 
    *(.mb1text*)  /* .mb1text* sections (code) */ 
    *(.mb1rodata)  /* read-only data (constants) */ 
    *(.mb1rodata*) 
    } >MEMORY_B1 

    /* Remove information from the standard libraries */ 
    /DISCARD/ : 
    { 
    libc.a (*) 
    libm.a (*) 
    libgcc.a (*) 
    } 
} 

я могу видеть, что ISR векторы размещаются вспышки, так что если программа должна вызвать адрес, хранящийся в некотором векторе, он будет считываться из флэш-памяти.

Первый вопрос: Какое оборудование не имеет значения между чтением из ОЗУ и вспышкой? И зачем мне тогда нужны специальные регистры для записи или чтения из флэш-памяти в коде и не может просто явно писать или читать по ее адресам?

Второй вопрос - это то, насколько медленнее читать со вспышки, чем из ОЗУ? И если я знаю, какая функция используется больше всего в моем коде, то могу ли я перенести ее в раздел RAM, чтобы существенно ускорить его выполнение? Я считаю, что MEMORY_B1 в этом скрипте специально создан для этой цели.

Третий вопрос: Как мы можем поместить что-нибудь в MEMORY_B1, если оно имеет длину 0?

И последний вопрос: Если я создаю дополнительный раздел во флэш-памяти, могу ли я создать простой аналог виртуальной памяти? Я думаю, что ответ на этот вопрос зависит от первого.

ответ

2
  1. Аппаратное обеспечение не имеет значения, поскольку обе памяти (и фактически что-либо еще) отображаются в общем адресном пространстве. Однако это не означает, что вы можете легко записать флеш-память, чтобы рассматривать ее как оперативную память, так как она медленная и может быстро повредить память (она имеет типичную продолжительность записи в 100k циклов). Более того, его можно стереть только на полных страницах (размер которых может составлять 128   kB для некоторых чипов STM32), что действительно затрудняет использование в качестве замены оперативной памяти.

  2. Разница в скорости незначительна. Запуск кода из ОЗУ на микроконтроллерах ARM Cortex-M будет медленнее, чем вы ожидаете, поскольку оперативная память подключена к другой шине (предназначена для данных), а для ее использования для использования кода требуется использование более медленного «межсоединения».

  3. Вы не можете. Если вы захотите что-то там разместить, размер памяти должен быть увеличен (а размер «нормальной RAM» - уменьшен).

  4. Как правило, вы можете это сделать, но это будет очень медленно, и вы быстро повредите вспышку.

0

1/2. Is не на STM32F1. Это будет стоить вам только при скорости ядра более 100 МГц. Даже этот чип имеет кеш и предварительную выборку. С этим ядром может быть незначительная небольшая прибыль, если вы поместите векторную таблицу в ОЗУ в некоторых особых случаях.

Возможно, существует ограничение на оборудование, которое применяется к доступу шириной. Но эта вспышка не влияет на это.

3. Да, вы, безусловно, можете. Вы могли бы поместить в него файловую систему. Но у вас есть диапазон температур, в котором можно надежно записать вспышку.И, поскольку есть только один банк вспышки, вся активность останавливается до тех пор, пока стирание/флэш не будет выполнено. Если код не запущен из ОЗУ. Два дополнительных оговорки в том, что программирование/стирание флэш-памяти может занять миллисекунды, и вам придется учитывать стирание страниц по 2 кБ каждый, но все флэш-контроллеры должны.

Если вам нужна дополнительная оперативная память, поставьте SPI FRAM на свою доску.