Что вы хотите получить отображением флэш на ОЗУ вообще не понятно...
Зачем stm32 требует самостоятельно настраивать startup.s ?
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Почему было использовать физические адреса ОЗУ и записывать во флеш, а не по виртуальному адресу.
Зачем для отображения флэш использовать ОЗУ? Его и так мало в контроллере, обычно даже меньше чем флэш. ОЗУ используется для данных, а таблица векторов прерываний, обычно, только для чтения. Если уж хочется "на лету" менять что-то в таблице векторов прерываний, то в вашем контроллере можно перенести её в ОЗУ с помощью регистра VTOR. Что вы хотите получить отображением флэш на ОЗУ вообще не понятно...
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Линкер берёт его из своего скрипта. Загляните в *.ld-файл. Наверняка, что-то похожее найдёте
Да действительно. Код: Выделить всё
MEMORY
{
FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K
SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 20K
}Посмотрел nm'ом бинарники для ардуины, там адреса начинаются с близких к нулю.
А вот вывод от блинка из Eclipse для stm32f4
Спойлер
08001894 W __aeabi_idiv008001894 W __aeabi_ldiv0
08001594 T __aeabi_uldivmod
20000080 b __bss_begin_guard
20000128 B __bss_end__
20000124 b __bss_end_guard
0800041c D __bss_regions_array_end
0800040c D __bss_regions_array_start
20000080 B __bss_start__
20000000 d __data_begin_guard
20000080 D __data_end__
2000007c d __data_end_guard
0800040c D __data_regions_array_end
080003f4 D __data_regions_array_start
20000000 D __data_start__
08001898 T __errno
080024f8 D __etext
080024f8 R __exidx_end
080024f0 R __exidx_start
0800041c d __fini_array_end
0800041c d __fini_array_start
0800041c d __init_array_end
0800041c d __init_array_start
08001100 W __initialize_args
08001448 T __initialize_hardware
080012e4 W __initialize_hardware_early
08000000 T __isr_vectors
20000120 B __lock___malloc_recursive_mutex
2000fc00 A __Main_Stack_Limit
00000400 A __Main_Stack_Size
20000118 B __malloc_free_list
0800223c T __malloc_lock
2000011c B __malloc_sbrk_start
08002248 T __malloc_unlock
0800041c d __preinit_array_end
0800041c d __preinit_array_start
08002264 T __retarget_lock_acquire_recursive
08002266 T __retarget_lock_release_recursive
08001928 T __ssputs_r
20010000 T __stack
080015c4 T __udivmoddi4
08000000 A __vectors_start
08000000 A __vectors_start__
20000128 B _ebss
20000080 D _edata
20000128 B _end_noinit
20010000 A _estack
080024f8 D _etext
080010b8 W _exit
08002000 T _free_r
20000128 B _Heap_Begin
2000fc00 A _Heap_Limit
20000018 D _impure_ptr
080020d4 T _malloc_r
08002254 T _malloc_usable_size_r
00000100 A _Minimum_Stack_Size
20000128 B _noinit
08001be0 T _printf_common
08001cbc T _printf_i
080021bc T _realloc_r
080010bc T _sbrk
0800221c T _sbrk_r
20000080 B _sbss
20000000 D _sdata
080024f8 A _sidata
08000194 W _start
080019e0 T _svfiprintf_r
080019e0 T _svfprintf_r
08001110 t _trace_write_semihosting_debug
080018b4 T _vsniprintf_r
080018b4 T _vsnprintf_r
080003f0 W ADC_IRQHandler
08002444 T AHBPrescTable
2000000c d argv.1
08001458 T assert_failed
08001494 T blink_led_init
08001480 T blink_led_off
0800146c T blink_led_on
20000094 b buf.0
08000344 W BusFault_Handler
08000358 W BusFault_Handler_C
20000088 b current_heap_end.0
080003d8 W DebugMon_Handler
080003f0 W Default_Handler
080003f0 W DMA1_Stream0_IRQHandler
080003f0 W DMA1_Stream1_IRQHandler
080003f0 W DMA1_Stream2_IRQHandler
080003f0 W DMA1_Stream3_IRQHandler
080003f0 W DMA1_Stream4_IRQHandler
080003f0 W DMA1_Stream5_IRQHandler
080003f0 W DMA1_Stream6_IRQHandler
080003f0 W DMA1_Stream7_IRQHandler
080003f0 W DMA2_Stream0_IRQHandler
080003f0 W DMA2_Stream1_IRQHandler
080003f0 W DMA2_Stream2_IRQHandler
080003f0 W DMA2_Stream3_IRQHandler
080003f0 W DMA2_Stream4_IRQHandler
080003f0 W DMA2_Stream5_IRQHandler
080003f0 W DMA2_Stream6_IRQHandler
080003f0 W DMA2_Stream7_IRQHandler
080011d0 T dumpExceptionStack
2000008c B errno
080003f0 W EXTI0_IRQHandler
080003f0 W EXTI1_IRQHandler
080003f0 W EXTI15_10_IRQHandler
080003f0 W EXTI2_IRQHandler
080003f0 W EXTI3_IRQHandler
080003f0 W EXTI4_IRQHandler
080003f0 W EXTI9_5_IRQHandler
080003f0 W FLASH_IRQHandler
080003f0 W FPU_IRQHandler
080004b8 W HAL_GetTick
080005f0 T HAL_GPIO_Init
08000894 T HAL_GPIO_WritePin
080004a0 W HAL_IncTick
0800046c T HAL_Init
08000420 W HAL_InitTick
08001524 T HAL_MspInit
08000500 T HAL_NVIC_SetPriority
080004c4 T HAL_NVIC_SetPriorityGrouping
08000e90 T HAL_RCC_ClockConfig
080010ac T HAL_RCC_GetHCLKFreq
08000dbc W HAL_RCC_GetSysClockFreq
080008cc W HAL_RCC_OscConfig
080005b4 T HAL_SYSTICK_CLKSourceConfig
0800058c T HAL_SYSTICK_Config
080002ce W HardFault_Handler
080002e2 W HardFault_Handler_C
080003f0 W I2C1_ER_IRQHandler
080003f0 W I2C1_EV_IRQHandler
080003f0 W I2C2_ER_IRQHandler
080003f0 W I2C2_EV_IRQHandler
080003f0 W I2C3_ER_IRQHandler
080003f0 W I2C3_EV_IRQHandler
2000001c d impure_data
080012c4 T isSemihosting
080014cc T main
08001f10 T memchr
08001fb0 T memcpy
08000340 W MemManage_Handler
08001fcc T memmove
20000090 b name.0
080002ca W NMI_Handler
080003f0 W OTG_FS_IRQHandler
080003f0 W OTG_FS_WKUP_IRQHandler
080003dc W PendSV_Handler
080003f0 W PVD_IRQHandler
080003f0 W RCC_IRQHandler
080002c4 T Reset_Handler
080003f0 W RTC_Alarm_IRQHandler
080003f0 W RTC_WKUP_IRQHandler
08002094 t sbrk_aligned
080003f0 W SDIO_IRQHandler
080003f0 W SPI1_IRQHandler
080003f0 W SPI2_IRQHandler
080003f0 W SPI3_IRQHandler
080003f0 W SPI4_IRQHandler
080018a4 T strlen
080003d4 W SVC_Handler
080013ac W SystemClock_Config
20000014 D SystemCoreClock
0800130c T SystemCoreClockUpdate
080012fc T SystemInit
08001588 T SysTick_Handler
080003f0 W TAMP_STAMP_IRQHandler
080003f0 W TIM1_BRK_TIM9_IRQHandler
080003f0 W TIM1_CC_IRQHandler
080003f0 W TIM1_TRG_COM_TIM11_IRQHandler
080003f0 W TIM1_UP_TIM10_IRQHandler
080003f0 W TIM2_IRQHandler
080003f0 W TIM3_IRQHandler
080003f0 W TIM4_IRQHandler
080003f0 W TIM5_IRQHandler
20000114 B timer_delayCount
08001560 T timer_sleep
08001528 T timer_start
08001574 T timer_tick
0800117c T trace_printf
080011b0 T trace_puts
08001172 T trace_write
0800038c W UsageFault_Handler
080003a0 W UsageFault_Handler_C
080003f0 W USART1_IRQHandler
080003f0 W USART2_IRQHandler
080003f0 W USART6_IRQHandler
20000084 B uwTick
20000004 D uwTickFreq
20000008 D uwTickPrio
0800190c T vsniprintf
0800190c T vsnprintf
080003f0 W WWDG_IRQHandler
Самый обычный просмотрщик стандартного hex-файла. Открываем в блокноте этот файл и читаем первую строчку:
:020000040800F2
выделенное - и есть адрес (его старшие байты) начала размещения данных.
Возможно, но лучше через nm (обычный тоже пойдёт) сравнить два бинарника для ардуины и stm32. Там видна разница в адресах, и видно что адреса вписаны в бинарник при компиляции.:020000040800F2
выделенное - и есть адрес (его старшие байты) начала размещения данных.
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Что вы хотите получить отображением флэш на ОЗУ вообще не понятно...
Может быть, псевдоОС с выполнением пользовательских "программ"?
Re: Зачем stm32 требует самостоятельно настраивать startup.s
[uquote="ddr4",url="/forum/viewtopic.php?p=4278866#p4278866"]Почему было использовать физические адреса ОЗУ и записывать во флеш, а не по виртуальному адресу.
Зачем для отображения флэш использовать ОЗУ? Его и так мало в контроллере, обычно даже меньше чем флэш. ОЗУ используется для данных, а таблица векторов прерываний, обычно, только для чтения. Если уж хочется "на лету" менять что-то в таблице векторов прерываний, то в вашем контроллере можно перенести её в ОЗУ с помощью регистра VTOR. Что вы хотите получить отображением флэш на ОЗУ вообще не понятно...[/uquote]
Было непонятно зачем использовать адресное пространство большее чем ОЗУ. Но может быть действительно так удобнее всё держать в одном адресном пространстве и читать из флеша как из ОЗУ, чем использовать интерфейс вроде файла или EEPROM.
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Потому что 32 бита позволяют адресовать 4 ГБ.ddr4 писал(а):Было непонятно зачем использовать адресное пространство большее чем ОЗУ.
К некоторым моделям STM32 можно подключать внешнюю память на сотни МБ которая доступна из этого адресного пространства.
Удобнее. Например передаешь данные в функцию по указателю и не важно они во флеше или в ОЗУ. В AVR так не получится.ddr4 писал(а):Но может быть действительно так удобнее всё держать в одном адресном пространстве
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Зачем stm32 требует самостоятельно настраивать startup.s
В AVR так не получится.
А мужики то опять не в курсе 1. Можно вот так код в Compiler explorer. Как так получается предлагаю самому подумать.
2. В IAR есть модификатор __generic для указателей, которые могут указывать как на RAM, так и на flash. Они чуть медленнее обычных работают, но работают.
Спойлер
Код: Выделить всё
void char2lcd(char x) {volatile char tmp=x; }
void print(const char __generic *str)
{
while(*str) char2lcd(*str++);
}
__flash char str1[] = "FLASH string";
char str2[] = "SRAM string";
int main()
{
print(str1);
print(str2);
}
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Это не совсем то о чем я пишу. Здесь компилятор учитывает где расположены данные. В случае адресного пространства как у STM32 в этом нет необходимости.
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Хотелось бы очистить стандартный ld-script Эклипса от очень полезных, но непонятных секций.
Вот например секции ниже, мне для uart_print ("Hello world.") - примера не потребуются?
Также непонятно назначение секции .inits, в некоторых примерах её нет. Можно ли удалить, чтобы глаза не мозолила?
Также в Экплипсе секция .rodata находится внутри секции .text, а в других примерах .rodata самостоятельная секция. Что лучше?
Также непонятно зачем нужны разделы типа .bss_CCMRAM (NOLOAD) и .noinit_CCMRAM (NOLOAD) - вторичные неинициализированные секции данных ? Можно ли удалить ?
Вот например секции ниже, мне для uart_print ("Hello world.") - примера не потребуются?
Спойлер
Код: Выделить всё
/*
* Used for validation only, do not allocate anything here!
*
* This is just to check that there is enough RAM left for the Main
* stack. It should generate an error if it's full.
*/
._check_stack : ALIGN(4)
{
. = . + _Minimum_Stack_Size ;
} >RAM
/*
* The FLASH Bank1.
* The C or assembly source must explicitly place the code
* or data there using the "section" attribute.
*/
.b1text : ALIGN(4)
{
*(.b1text) /* remaining code */
*(.b1rodata) /* read-only data (constants) */
*(.b1rodata.*)
} >FLASHB1
/*
* The EXTMEM.
* The C or assembly source must explicitly place the code or data there
* using the "section" attribute.
*/
/* EXTMEM Bank0 */
.eb0text : ALIGN(4)
{
*(.eb0text) /* remaining code */
*(.eb0rodata) /* read-only data (constants) */
*(.eb0rodata.*)
} >EXTMEMB0
/* EXTMEM Bank1 */
.eb1text : ALIGN(4)
{
*(.eb1text) /* remaining code */
*(.eb1rodata) /* read-only data (constants) */
*(.eb1rodata.*)
} >EXTMEMB1
/* EXTMEM Bank2 */
.eb2text : ALIGN(4)
{
*(.eb2text) /* remaining code */
*(.eb2rodata) /* read-only data (constants) */
*(.eb2rodata.*)
} >EXTMEMB2
/* EXTMEM Bank0 */
.eb3text : ALIGN(4)
{
*(.eb3text) /* remaining code */
*(.eb3rodata) /* read-only data (constants) */
*(.eb3rodata.*)
} >EXTMEMB3
Также непонятно назначение секции .inits, в некоторых примерах её нет. Можно ли удалить, чтобы глаза не мозолила?
Спойлер
Код: Выделить всё
.inits : ALIGN(4)
{
/*
* Memory regions initialisation arrays.
*
* Thee are two kinds of arrays for each RAM region, one for
* data and one for bss. Each is iterrated at startup and the
* region initialisation is performed.
*
* The data array includes:
* - from (LOADADDR())
* - region_begin (ADDR())
* - region_end (ADDR()+SIZEOF())
*
* The bss array includes:
* - region_begin (ADDR())
* - region_end (ADDR()+SIZEOF())
*
* WARNING: It is mandatory that the regions are word aligned,
* since the initialisation code works only on words.
*/
__data_regions_array_start = .;
LONG(LOADADDR(.data));
LONG(ADDR(.data));
LONG(ADDR(.data)+SIZEOF(.data));
LONG(LOADADDR(.data_CCMRAM));
LONG(ADDR(.data_CCMRAM));
LONG(ADDR(.data_CCMRAM)+SIZEOF(.data_CCMRAM));
__data_regions_array_end = .;
__bss_regions_array_start = .;
LONG(ADDR(.bss));
LONG(ADDR(.bss)+SIZEOF(.bss));
LONG(ADDR(.bss_CCMRAM));
LONG(ADDR(.bss_CCMRAM)+SIZEOF(.bss_CCMRAM));
__bss_regions_array_end = .;
/* End of memory regions initialisation arrays. */
/*
* These are the old initialisation sections, intended to contain
* naked code, with the prologue/epilogue added by crti.o/crtn.o
* when linking with startup files. The standalone startup code
* currently does not run these, better use the init arrays below.
*/
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
/*
* The preinit code, i.e. an array of pointers to initialisation
* functions to be performed before constructors.
*/
PROVIDE_HIDDEN (__preinit_array_start = .);
/*
* Used to run the SystemInit() before anything else.
*/
KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*))
/*
* Used for other platform inits.
*/
KEEP(*(.preinit_array_platform .preinit_array_platform.*))
/*
* The application inits. If you need to enforce some order in
* execution, create new sections, as before.
*/
KEEP(*(.preinit_array .preinit_array.*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/*
* The init code, i.e. an array of pointers to static constructors.
*/
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/*
* The fini code, i.e. an array of pointers to static destructors.
*/
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
Также в Экплипсе секция .rodata находится внутри секции .text, а в других примерах .rodata самостоятельная секция. Что лучше?
Также непонятно зачем нужны разделы типа .bss_CCMRAM (NOLOAD) и .noinit_CCMRAM (NOLOAD) - вторичные неинициализированные секции данных ? Можно ли удалить ?
Спойлер
Код: Выделить всё
/* The secondary uninitialised data section. */
.bss_CCMRAM (NOLOAD) : ALIGN(4)
{
*(.bss.CCMRAM .bss.CCMRAM.*)
} > CCMRAM
.noinit_CCMRAM (NOLOAD) : ALIGN(4)
{
*(.noinit.CCMRAM .noinit.CCMRAM.*)
} > CCMRAMRe: Зачем stm32 требует самостоятельно настраивать startup.s
Чем мешают эти секции?ddr4 писал(а):Хотелось бы очистить стандартный ld-script Эклипса от очень полезных, но непонятных секций.
Они не влияют ни на размер прошивки, ни на скорость ее работы.
Если нет необходимости, не изменяйте ld файл.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Хотелось бы очистить стандартный ld-script Эклипса от очень полезных, но непонятных секций.
На какой помойке вы его нашли? Возьмите нормальный скрипт и не мучайтесь.Re: Зачем stm32 требует самостоятельно настраивать startup.s
VladislavS писал(а):
На какой помойке вы его нашли? Возьмите нормальный скрипт и не мучайтесь.
Вложение: STM32F401CB_flash.zip
Это стандартный скрипт для блинк проекта в Эклипсе.
Спасибо за скрипт.
А ниже в нём, это пользовательские секции? то есть не обязательные?
Спойлер
Код: Выделить всё
.preinit_array :
{ PROVIDE(__preinit_array_start = .);
KEEP(*(.preinit_array*))
PROVIDE(__preinit_array_end = .);
} > FLASH
.init_array :
{ PROVIDE(__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array*))
PROVIDE(__init_array_end = .);
} > FLASH
.fini_array :
{ PROVIDE(__fini_array_start = .);
KEEP(*(.fini_array*))
KEEP(*(SORT(.fini_array.*)))
PROVIDE(__fini_array_end = .);
} > FLASH
.reserved_for_stack (NOLOAD) :
{ . = ALIGN(4);
PROVIDE(__reserved_for_stack_start__ = .);
KEEP(*(.reserved_for_stack))
. = ALIGN(4);
PROVIDE(__reserved_for_stack_end__ = .);
} > SRAM
А как на счёт такого скрипта, без malloc и С++ ?
Спойлер
Код: Выделить всё
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256k
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64k
}
GROUP(
libgcc.a
libg.a
libc.a
libm.a
libnosys.a
)
__stack = ORIGIN(RAM) + LENGTH(RAM);
SECTIONS
{
. = ORIGIN(FLASH);
.isr_vectors : ALIGN(4)
{
FILL(0xFF)
__vectors_start__ = ABSOLUTE(.);
KEEP(*(.vectors))
*(.after_vectors .after_vectors.*)
} > FLASH
/*
* Start of text.
*/
_text = .;
.text : ALIGN(4)
{
*(.text)
*(.text.*)
*(.glue_7t)
*(.glue_7)
*(.gcc*)
} > FLASH
/*
* Arm section unwinding.
* If removed may cause random crashes.
*/
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
/*
* Arm stack unwinding.
* If removed may cause random crashes.
*/
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
/*
* Read-only data. Consts should also be here.
*/
.rodata : ALIGN(4)
{
. = ALIGN(4);
__rodata_start__ = .;
*(.rodata)
*(.rodata.*)
. = ALIGN(4);
__rodata_end__ = .;
} > FLASH
/*
* End of text.
*/
_etext = .;
/*
* Data section.
*/
.data : ALIGN(4)
{
FILL(0xFF)
. = ALIGN(4);
PROVIDE(__textdata__ = LOADADDR(.data));
PROVIDE(__data_start__ = .);
*(.data)
*(.data.*)
*(.ramtext)
. = ALIGN(4);
PROVIDE(__data_end__ = .);
} > RAM AT > FLASH
/*
* BSS section.
*/
.bss (NOLOAD) : ALIGN(4)
{
. = ALIGN(4);
PROVIDE(_bss_start = .);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
PROVIDE(_bss_end = .);
__bss_end__ = .;
PROVIDE(end = .);
} > RAM
.noinit (NOLOAD) : ALIGN(4)
{
__noinit_start__ = .;
*(.noinit .noinit.*)
. = ALIGN(4) ;
__noinit_end__ = .;
} > RAM
}
В чём, в данном контексте, отличие SRAM от RAM ?
Кстати если я заменю все (в том числе в .isr_vertors ) "> FLASH" на "> SRAM" это будет работать?
Последний раз редактировалось ddr4 Сб авг 27, 2022 14:49:29, всего редактировалось 1 раз.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Зачем stm32 требует самостоятельно настраивать startup.s
А ниже в нём, это пользовательские секции? то есть не обязательные?
Эти секции создаёт компилятор. В них содержится информация, необходимая стартовому коду для инициализации глобального окружения. Посмотрите .map файл, они там есть.Откуда у вас такое маниакальное желание что-то удалить, даже не понимая зачем это нужно? Всё что вам нужно сделать с этим скриптом - поставить правильный размер FLASH и SRAM для вашего контроллера. Если в скрипте описаны какие-то незадействованные в коде секции, то их всё равно не будет в итоговой прошивке. Это всего лишь правила, по которым линкер размещает их в адресном пространстве, при их наличии в коде. Они жрать не просят. Ничего лишнего в загруженном мной скрипте нет, займитесь уже программированием.
Добавлено after 1 minute 58 seconds:
В чём, в данном контексте, отличие SRAM от RAM ?
Ни в чём, воспринимайте это как имя области памяти, примерно как имя переменной в программе. Можете назвать как хотите, чтобы даже враг не догадался что это Добавлено after 3 minutes 13 seconds:
Кстати если я заменю все (в том числе в .isr_vertors ) "> FLASH" на "> SRAM" это будет работать?
Будет. При отладке программы в SRAM так и делают. Посмотрите приложенный скрипт и сравните с тем что я первым выложил. Вот этот настроен на загрузку кода для отладки в SRAM.Добавлено after 3 minutes 49 seconds:
А как на счёт такого скрипта, без malloc и С++ ?
Ответьте на простой вопрос - ЗАЧЕМ? Зачем вы пытаетесь не рассказать линкеру что делать с "кучей", если она появится в коде? Эти строки в скрипте жрать просят?Re: Зачем stm32 требует самостоятельно настраивать startup.s
Чем мешают эти секции?
Если нет необходимости, не изменяйте ld файл.
Тем что я эти секции не использую, зачем они мне? К тому же эти не используемые секции завязаны на стартап, в котором есть переменные этих секций. Если нет необходимости, не изменяйте ld файл.
Они не влияют ни на размер прошивки, ни на скорость ее работы.
То есть если я удалю множество неиспользуемых секций, а в остальных заменю >FLASH на >RAM, скорость запуска приложения не изменится?У меня нет такого файла.VladislavS писал(а): Посмотрите .map файл, они там есть.
Чтобы оставить только то что нужно, раз STM32 в отличии от AVR-gcc предоставляет возможность управления запуском, то значить это нормально удалять всё что не нужно. Пытаюсь упростить код по максимуму. Для меня этот Blink с кучей файлов выглядит сложно. "Хеллоу Ворлд" будет ещё сложней.VladislavS писал(а):Откуда у вас такое маниакальное желание что-то удалить, даже не понимая зачем это нужно?
Да всё заменено на SRAM, то есть получается в случае замены FLASH на RAM, при запуске программы секции размещаются в оперативке, а до этого размещались во FLASH ?VladislavS писал(а):При отладке программы в SRAM так и делают. Посмотрите приложенный скрипт и сравните с тем что я первым выложил. Вот этот настроен на загрузку кода для отладки в SRAM.
[uquote="ddr4",url="/forum/viewtopic.php?p=4279145#p4279145"]А как на счёт такого скрипта, без malloc и С++ ?
Ответьте на простой вопрос - ЗАЧЕМ? Зачем вы пытаетесь не рассказать линкеру что делать с "кучей", если она появится в коде? Эти строки в скрипте жрать просят?[/uquote]Если у меня в коде нет malloc(), надеюсь в этой куче обёрток её тоже нет. Поэтому мне куча и не нужна. В Арудине я malloc() не использовал, то и здесь не требуется.- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Тем что я эти секции не использую, зачем они мне? К тому же эти не используемые секции завязаны на стартап, в котором есть переменные этих секций.
Они нужны не вам, а линкеру. Чтобы он правильно собрал вашу программу. То есть если я удалю множество неиспользуемых секций, а в остальных заменю >FLASH на >RAM, скорость запуска приложения не изменится?
Что такое в вашем понимании скрость запуска приложения? При включении код лежит в флэш и с первых же тактов начинает работать c Reset_Handler. Это и есть приложение. Где тут скорость запуска измерить. А изменится то, что оно либо не соберётся, либо не будет работать.У меня нет такого файла.VladislavS писал(а): Посмотрите .map файл, они там есть.
Чтобы оставить только то что нужно, раз STM32 в отличии от AVR-gcc предоставляет возможность управления запуском, то значить это нормально удалять всё что не нужно. Пытаюсь упростить код по максимуму. Для меня этот Blink с кучей файлов выглядит сложно. "Хеллоу Ворлд" будет ещё сложней.
Ну так и ковыряйте программу, чего вы до линкерскрипта то докопались? Он лишь задаёт правила размещения того что есть в коде. Всё что есть в коде должно быть размещено в памяти. Чего нет, того и так нет. Линкерскрипт вообще никак не влияет на упрощение программы.Да всё заменено на SRAM, то есть получается в случае замены FLASH на RAM, при запуске программы секции размещаются в оперативке, а до этого размещались во FLASH ?
Да. Только вы должны понимать, что сама по себе программа в оперативке не появится. Кто-то или что-то должны её туда перед запуском поместить.Если у меня в коде нет malloc(), надеюсь в этой куче обёрток её тоже нет. Поэтому мне куча и не нужна. В Арудине я malloc() не использовал, то и здесь не требуется.
Ну и не используйте дальше. От того что вы упомянете её в скрипте линкера она в коде не появится.- GARMIN
- Держит паяльник хвостом
- Сообщения: 952
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Зачем stm32 требует самостоятельно настраивать startup.s
У меня в проектах вообще нет ассемблерного стартапа. И ничего, IAR прекрасно работает с сишным самописным стартапом.
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Я же не знаю как оно в реальности запускается, возможно в линкере указывается куда МК (операционная система) должна разместить секции программы после её запуска. На деле МК размещает секции по адресам в адресном пространстве, желательно чтобы МК размещал секции в ОЗУ, так как во-первых ОЗУ быстрей FLASH'a, а значит скорость программы возрастает, а во-вторых FLASH имеет ограниченный ресурс на число записей. То есть МК с размещением секций в ОЗУ проживёт дольше.VladislavS писал(а):Что такое в вашем понимании скрость запуска приложения? При включении код лежит в флэш и с первых же тактов начинает работать c Reset_Handler. Это и есть приложение.
Но видимо указание линкеру разместить секцию в >RAM, ещё не является гарантией что она будет находится именно в ОЗУ ..? Так как нельзя сказать точно на какое устройство отражается кусок адресного пространства.
Спасибо. Действительно интересная информация.VladislavS писал(а):Он создаётся при компиляции при указании соответствующего ключа. Вот это, в отличии от ковыряния скриптов, стоит сделать. Там много интересной информации.
VladislavS писал(а):Да. Только вы должны понимать, что сама по себе программа в оперативке не появится. Кто-то или что-то должны её туда перед запуском поместить.
В коде стартапа секция данных копируется по адресу (не факт что ОЗУ), а секция bss зануляется. Остальные секции возможно размещает сам МК, может у него есть какие-то внутренние механизмы?
В коде целый файл sbrk.c под подготовку кучи, + в .map-файле heap'a навалено. Вроде оно всё не мешает, но когда этого всего "не мешает" - много, оно как-то начинает мешать.VladislavS писал(а):Ну и не используйте дальше. От того что вы упомянете её в скрипте линкера она в коде не появится.
Последний раз редактировалось ddr4 Сб авг 27, 2022 17:54:56, всего редактировалось 1 раз.
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Вот вы подключили библиотеку с функциями, струкурами, дефайнами и др. и почти все их не используете. Будете выпиливать не задействованные и без разницы что компиль это сам может сделать?ddr4 писал(а):Тем что я эти секции не использую, зачем они мне?
С секциями тоже самое. Если не используются, они не попадут в прошивку (при адекватных ключах компиля и линкера). А если используются, прошивку не соберете.
Если секции действительно не используются то просто зря потратите время, т. к. они все равно в прошивку не попадут (повторюсь, при правильных ключах компиля и линкера).ddr4 писал(а):То есть если я удалю множество неиспользуемых секций
Загружать прошивку как планируете? Обычно прошивку помещают в ОЗУ при отладке (ее загружает отладчик) или необходимости полностью переписать флешь.ddr4 писал(а):а в остальных заменю >FLASH на >RAM, скорость запуска приложения не изменится?
Создается при компиляции.ddr4 писал(а):У меня нет такого файла.
Нормально это когда этим занимается компиль вместе с линкером. Но вы упорно хотите выполнять их работу!ddr4 писал(а):значить это нормально удалять всё что не нужно.
Какая разница сколько файлов в проекте?ddr4 писал(а):Для меня этот Blink с кучей файлов выглядит сложно. "Хеллоу Ворлд" будет ещё сложней.
То есть строками не пользовались, print в любом виде не использовали, классы динамически не создавали и много чего другого не делали что выделяло память из кучи?ddr4 писал(а):В Арудине я malloc() не использовал
- AVI-crak
- Прорезались зубы
- Сообщения: 202
- Зарегистрирован: Сб янв 09, 2016 15:51:17
- Контактная информация:
Re: Зачем stm32 требует самостоятельно настраивать startup.s
VladislavS писал(а):Они нужны не вам, а линкеру.
С секциями init_array - даже у меня вопросы имеются.
Применительно к ARM, потому как для компов может быть всё иначе.
Для собирательных секций data, rodata, bss, text - есть чёткое определение в доках GCC, чего и в каком качестве туда помещается. Для остальных секций выполняется простое условие, имя секции должно совпадать с именем объекта (функция, переменная, чистая/грязная память, константы и вектора).
Секции array - тоже собирательные, потому как объектов с похожим названием нет ни в одном проекте, и даже в самом GCC.
Однако точного описания в доках GCC нету. (прям именно там, на сайте GCC). Отчего у меня лично возникает ощущение что секцию забыли удалить. Без неё код собирается, и даже не меняет свой состав на бинарном уровне.
Есть вариант что оно висит (или раньше было там) на уровне спецификаций (*.specs) - код подключаемый вне желания программиста. Изначально спецификации были предназначены для того чтобы у всех всё было одинаково. Но случилась неприятность, и бардак возник за забором - чипов и их модификаций развелось как собак не резаных. Писать спеки на каждый чих ARM зоопарка - желающих не нашлось. Отчего настройки спустились на пользовательский уровень, а в *.specs осталась заглушка.
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Если не нравится что-то, просто поочередно удаляйте секцию за секцией и смотрите, когда при очередном компилировании ошибки полезут. Заодним и разберетесь, что для чего там надобно.
Re: Зачем stm32 требует самостоятельно настраивать startup.s
Мурик писал(а):Вот вы подключили библиотеку с функциями, струкурами, дефайнами и др. и почти все их не используете. Будете выпиливать не задействованные и без разницы что компиль это сам может сделать?
С секциями тоже самое. Если не используются, они не попадут в прошивку (при адекватных ключах компиля и линкера). А если используются, прошивку не соберете.
Во-первых библиотека на то и библиотека что скрывает от её пользователя всю реализацию, например это стандартная библиотека и она прикомпиливается при сборке и лежит в библах/компилятора, а не в файлах проекта. Когда флеша не хватает, то из библиотеки берётся одна функция, без подключения хедера зависимого от других хедеров. Иногда это экономит и память и флеш.
Мурик писал(а):Если секции действительно не используются то просто зря потратите время, т. к. они все равно в прошивку не попадут (повторюсь, при правильных ключах компиля и линкера). ... Какая разница сколько файлов в проекте?
Возможно это сложно понять, но мне не хочется видеть лишнего кода при вхождении в новую тему. И чем его меньше (при сохранении читаемости - неассемблер) тем лучше.
Мурик писал(а):Загружать прошивку как планируете? Обычно прошивку помещают в ОЗУ при отладке (ее загружает отладчик) или необходимости полностью переписать флешь.
Пока не знаю, хотел сначала с эмулятором поиграться, а после уже через uart-ttl через сериал. Говорят в F4 есть встроенный загрузчик он это позволяет.
Динамически создавал структуры malloc(), но память быстро кончилась пришлось от этого быстро отказаться ). printf() заменить самодельный uart_print(). Иначе всё в 2 кБ не впихнуть.Мурик писал(а):То есть строками не пользовались, print в любом виде не использовали, классы динамически не создавали и много чего другого не делали что выделяло память из кучи?
Последний раз редактировалось ddr4 Сб авг 27, 2022 18:27:32, всего редактировалось 1 раз.