Пт мар 26, 2021 21:55:34
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 80K
/*
ДОБАВИЛ определения для встроенной в контроллер EEPROM. Значения адресов и размеров взяты из даташита.
*/
EEP1 (rw) : ORIGIN = 0x08080000, LENGTH = 8K
EEP2 (rw) : ORIGIN = 0x08082000, LENGTH = 8K
}
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > ROM
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > ROM
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > ROM
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss (NOLOAD):
{
__bss_start__ = .;
*(.bss*)
*(COMMON)
__bss_end__ = .;
} > RAM
.heap (NOLOAD):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (NOLOAD):
{
*(.stack)
} > RAM
/*
ДОБАВИЛ две секции, соответствующие двум банкам EEPROM.
Использовал KEEP, чтобы компоновщик не удалял данные, которые по той или иной причине должны быть записаны в память, но не используются в программе непосредственно.
*/
.eeprom_bank_1 :
{
KEEP (*(.eep_bank_1));
} > EEP1
.eeprom_bank_2 :
{
KEEP (*(.eep_bank_2));
} > EEP2
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}
volatile uint32_t a[10] __attribute__ ((section(".eep_bank_2"))) = {1,2,3,4,5,6,7,8,9,10};
MEMORY
{
...
EEP1 (rw) : ORIGIN = 0x08080000, LENGTH = 8K
...
}
...
.eeprom_bank_1 :
{
KEEP (*(.eep_bank_1));
} > EEP1
.eeprom_bank_1 0x08080000 :
{
KEEP(*(.eep_bank_1));
}
Пт мар 26, 2021 23:43:14
Потому что данные для ОЗУ, но хранятся во флеше.YS писал(а):зачем при объявлении секции .data используется атрибут AT?
EEPROM в STM32 поддерживает прямую запись?YS писал(а):EEP1 (rw) : ORIGIN = 0x08080000, LENGTH = 8K
EEP2 (rw) : ORIGIN = 0x08082000, LENGTH = 8K
Сб мар 27, 2021 10:18:18
EEPROM в STM32 поддерживает прямую запись?
Сб мар 27, 2021 11:09:53
Чт апр 08, 2021 23:17:14
Чт апр 15, 2021 14:59:52
все время работать с разблокированным на запись EEPROM не очень удачная идея с точки зрения сохранности данных в нем.
И это, при рестарте переменные инициализируются же.
А как вы начальные значения пропишете только 1 раз?
И вообще как оно будет non-volatile при этом, если так в лоб?
Кроме того - доступ на запись может bus stall на довольно почтенное время. Вам совсем плевать на реальное время и вы готовы с неконтролируемым (вами явно) тупняком чипа от такого доступа жить?
но осторожно, указатели они такие
Пт апр 23, 2021 13:50:58
Пт апр 23, 2021 18:31:11
Пт апр 23, 2021 18:49:49
Пт апр 23, 2021 19:20:01
Пт апр 23, 2021 20:19:51
Пт апр 23, 2021 20:59:19
Вс апр 25, 2021 16:47:03
Как можно сделать, чтобы эти функции при линковке загрузчика ложились в определенное место в прошивке, а в приложении эти функции подхватывались из того же места?
MEMORY
{
...
SHARED_CODE_REGION (rx) : ORIGIN <где должен начинаться разделяемый код>, LENGTH = <сколько выделим под разделяемый код>
}
...
.shared_code_section:
{
__shared_code_start__ = .;
KEEP(*(.shared_code));
} > SHARED_CODE_REGION;
<тип> function(...) __attribute__ ((section(".shared_code")))
{
...
}
Вс апр 25, 2021 17:16:17
YS писал(а):В той программе, которая эти функции должна только использовать, но не содержать, к секции .shared_code_section добавляем атрибут NOLOAD.