dimka76 62 29 февраля Опубликовано 29 февраля · Жалоба On 2/29/2024 at 10:11 AM, makc said: Здесь нет озвученной ТС фиксации адреса блока параметров. Он может меняться. Я эту идею вообще не понял ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 29 февраля Опубликовано 29 февраля · Жалоба Только что, Ivan. сказал: Все определено: Да, точно, я не посмотрел на карту всей памяти, т.к. сам никогда не бью регионы таким образом. У меня карта регионов отражает физическую структуру памяти МК, а не логическое распределение. Только что, dimka76 сказал: Я эту идею вообще не понял ))) Его идея у вас уже реализована. Так что в принципе есть консенсус. 🙂 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба Пока так и сделал. Жаль, что нельзя сделать так: 2 часа назад, Ivan. сказал: .text : { ..... } >FLASH1, FLASH2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 62 29 февраля Опубликовано 29 февраля · Жалоба On 2/29/2024 at 10:22 AM, Ivan. said: Пока так и сделал. Жаль, что нельзя сделать так: Если вы хотите кружануть и по максимому использовать первую секцию памяти, то можно указать куда линковать конкретные объектные файлы или даже отдельные функции. Например так в коде void SysTick_Handler(void) __attribute__((section(".isr_vector"))); Или так в LD файле .isr_vector : { . = ALIGN(8); _image_start = ABSOLUTE(.); KEEP(*(.isr_vector)) /* Startup code */ stm32f30x_it.o(*) /* размещаем объектный файл в секции isr_vector */ . = ALIGN(8); } >ISR_FLASH Сам не пробовал, взял из AN4296 Application note от STM Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба 2 часа назад, Ivan. сказал: заполнить его еще чем нибудь вручную, например: Initialized data и постоянно за этим следить Так и сделал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_3m 9 29 февраля Опубликовано 29 февраля · Жалоба 3 часа назад, Ivan. сказал: И в Вашем и в моем случае разрыв будет. По этому я и ищу способ не выбрасывать ~16К на выравнивание. вектора занимают 400Б и init 40Б, а остальное на выравнивание. Я хочу, чтобы линковщик по максимуму разместил данные в первом секторе, а потом перескочил на третий. GNU LD не умеет работать с регионами в которых есть "дырки". На это тикет уже лет 10 висит, разработчикам похер. Либо заполняйте вручную либо будет потеряно место. IAR - умеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 44 29 февраля Опубликовано 29 февраля · Жалоба Покажу, как это сделано у меня. STM32F4. Раскладка флэша: 16К - векторы; 32К (16К+16К) - байт-код программы пользователя; 16К - параметры програграммы пользователя по умолчанию; 64К - резерв; всё остальное программа МК. Скрипт линковщика: Spoiler /** ****************************************************************************** * @file LinkerScript.ld * @author Auto-generated by STM32CubeIDE * Abstract : Linker script for Discovery-F446xx Board embedding STM32F446xx * device from stm32f4 series 512Kbytes FLASH * 128Kbytes RAM * * Set heap size, stack size and stack location according * to application requirements. * * Set memory bank area and size if external memory is used ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2020 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x800; /* required amount of heap */ _Min_Stack_Size = 2K; /* required amount of stack */ /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K BKPSRAM (xrw) : ORIGIN = 0x40024000, LENGTH = 4K SECTOR_0 (rx) : ORIGIN = 0x08000000, LENGTH = 16K SECTOR_1_2 (rx) : ORIGIN = 0x08004000, LENGTH = 32K SECTOR_3 (rx) : ORIGIN = 0x0800C000, LENGTH = 16K SECTOR_4 (rx) : ORIGIN = 0x08010000, LENGTH = 64K /* Reserved */ SECTOR_5_7 (rx) : ORIGIN = 0x08020000, LENGTH = 384K } /* Sections */ SECTIONS { .bkpsram : { . = ALIGN(1); KEEP(*(.bkpsram)) . = ALIGN(4); } >BKPSRAM /* The startup code into "FLASH" Rom type memory */ .isr_vector_FLASH : { . = ALIGN(4); KEEP(*(.isr_vector_FLASH)) /* Startup code */ . = ALIGN(4); } >SECTOR_0 .plc_params : { . = ALIGN(2); KEEP (*(.plc_params)) /*. = ALIGN(2);*/ } >SECTOR_1_2 .plc_prog : { /*. = ALIGN(2);*/ KEEP (*(.plc_prog)) . = ALIGN(2); } >SECTOR_1_2 .plc_D8xxx : { . = ALIGN(2); KEEP (*(.plc_D8xxx)) . = ALIGN(2); } >SECTOR_1_2 .plc_data_regs : { . = ALIGN(2); KEEP (*(.plc_data_regs)) . = ALIGN(2); } >SECTOR_3 /* The program code and other data into "FLASH" Rom type memory */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >SECTOR_5_7 /* Constant data into "FLASH" Rom type memory */ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >SECTOR_5_7 .ARM.extab : { . = ALIGN(4); *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); } >SECTOR_5_7 .ARM : { . = ALIGN(4); __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; . = ALIGN(4); } >SECTOR_5_7 .preinit_array : { . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); } >SECTOR_5_7 .init_array : { . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); } >SECTOR_5_7 .fini_array : { . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >SECTOR_5_7 _sidata = LOADADDR(.data); /* Initialized data sections into "RAM" Ram type memory */ .isr_vector_RAM : { . = ALIGN(4); KEEP(*(.isr_vector_RAM)) PROVIDE_HIDDEN ( __isr_vector_RAM = .); . = ALIGN(4); } >RAM .data : { . = 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 AT> SECTOR_5_7 /* Uninitialized data section into "RAM" Ram type memory */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss section */ _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 /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } Размещение данных по этим областям: Spoiler ..... const uint8 __PLC_params[ SIZE_BYTE_PARAMS ] \ __attribute__ ( (section( ".plc_params" ), used ) ) = { //MAX_STEP / 1000, 0x00, // 00 0x0000 -- SIZE IN STEP 16000 0x02, 0x00, // 00 0x0000 -- SIZE IN STEP 16000 0x00, 0x00, // 02 -- 0x00, 0x00, // 04 -- 0x00, 0x00, // 06 -- 0x20, 0x20, // 08 0x0008 -- PASSWORD 0 0x20, 0x20, // 10 -- PASSWORD 1 0x20, 0x20, // 12 -- PASSWORD 2 0x20, 0x20, // 14 -- PASSWORD 3 'S', 'K', // 16 0x0010 -- PLC NAME 0 '2', 'N', // 18 -- PLC NAME 1 '-', 'F', // 20 -- PLC NAME 2 '4', '6', // 22 -- PLC NAME 3 '6', 0, // 24 -- PLC NAME 4 0, 0, // 26 -- PLC NAME 5 0, 0, // 28 -- PLC NAME 6 0, 0, // 30 -- PLC NAME 7 0, 0, // 32 -- PLC NAME 8 0, 0, // 34 -- PLC NAME 9 0, 0, // 36 -- PLC NAME A 0, 0, // 38 -- PLC NAME B 0, 0, // 40 -- PLC NAME C 0, 0, // 42 -- PLC NAME D 0, 0, // 44 -- PLC NAME E 0, 0, // 46 -- PLC NAME F 0x00,0x08, // 48 0x0030 -- M Latch Start 0 0xFF,0x0B, // 50 -- M Latch End 1023 0x00,0x00, // 52 -- S Latch Start 0 0xE7,0x03, // 54 -- S Latch End 999 0x00,0x0E, // 56 -- C16 Latch Start / 0xC7,0x0E, // 58 -- C16 Latch End / 0xC8,0x0E, // 60 -- C32 Latch Start / 0xFF,0x0E, // 62 -- C32 Latch End / 0x00,0x00, // 64 0x0040 -- D Latch Start / 0xFE,0x03, // 66 -- D Latch End / 0x00,0x00, // 68 -- 0x00,0x00, // 70 -- 0x00,0x00, // 72 -- File register address 0x00,0x00, // 74 -- File register capaity blocks 0x00,0x00, // 76 -- Comments address 0x00,0x00, // 78 -- Comments capaity blocks 0x00,0x00, // 80 0x0050 -- 0x80 ( RUN X007 -- X000 ) 0x40 -- PLC system 1/2 0x00,0x00, // 82 -- 0x00,0x00, // 84 -- 0x00,0x00, // 86 -- 0x00,0x00, // 88 -- 0x00,0x00, // 90 -- }; const uint16 __PLC_prog[ 16000 ] \ __attribute__ ( (section( ".plc_prog" ), used ) ) = { 0x2800, 0xC801, 0x001C, // -|M0|-(M1)- 0xFFFF, // ----[FEND]- 0x000F // -----[END]- }; const uint16 __PLC_simple_programm[] \ = { 0x2800, 0xC801, 0x001C, // -|M0|-(M1)- 0xFFFF, // ----[FEND]- 0x000F // -----[END]- }; ..... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 29 февраля Опубликовано 29 февраля · Жалоба 6 часов назад, Ivan. сказал: а потом указать, что секцию .text разместить в этих 2 регионах .text : { ..... } >FLASH1, FLASH2 Зачем? Какой смысл? У вас уже код так вырос, что нет места во флешь? Тогда лучше просто включить оптимизацию по размеру. Это даст гораздо бОльший выигрыш, чем жалкие 16КБ. Размазывание .text по нескольким несвязанным регионам в общем случае снижает эффективность кода (снижает скорость его выполнения). А скорость выполнения более важный фактор, чем размер кода (в наше время). Поэтому лучше оставить младший сектор полупустым. Ну или разместить в нём какие-то const-данные большого размера (если таковые имеются). Так же часто первый(-ые) сектор(-а) оставляют для bootloader-а (даже если пока у вас его нет). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_3m 9 29 февраля Опубликовано 29 февраля · Жалоба 5 минут назад, jcxz сказал: Размазывание .text по нескольким несвязанным регионам в общем случае снижает эффективность кода (снижает скорость его выполнения). Данное измышление необходимо обосновать. Пока оно выглядит высосанным из пальца даже если приплести влияние ART акселератора. В большой программе функции как правило лежат не в порядке их вызова при исполнении так что в любом случае будет обращение не в линейном порядке адресов. Цитата А скорость выполнения более важный фактор, чем размер кода (в наше время). Это кому как. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба 22 минуты назад, jcxz сказал: Зачем? Какой смысл? У вас уже код так вырос, что нет места во флешь? Да на самом деле нет, просто хотел идеальный вариант. Вообще к концу разработки в первый сектор ляжет Boot, а App уже куда угодно. 12 минут назад, _3m сказал: А скорость выполнения более важный фактор, чем размер кода (в наше время). Приоритет: 1. Надежность 2. Читаемость исходника 3. Скорость / объем (на выбор) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 29 февраля Опубликовано 29 февраля · Жалоба 3 часа назад, _3m сказал: Данное измышление необходимо обосновать. Пока оно выглядит высосанным из пальца даже если приплести влияние ART акселератора. Если вы не знакомы с системой команд ARM, то что-то обосновывать вам бесполезно. А если знакомы - то обосновывать не нужно, так как и сами понимаете причину. PS: Дальность переходов в системе команд ограничена разрядностью смещений (в соответствующих инструкциях CPU). Чем дальше переходы - тем более тяжёлые команды переходов будут использованы. А в некоторых случаях даже переходы будут осуществляться через специальные промежуточные вставки кода (когда расстояний перехода не хватает). Соответственно такой код будет выполняться медленнее и будет тяжелее. Это во-первых, во-вторых: дальность адресации .const-данных, адресуемых через PC (в ARM-коде таких данных много), тоже ограничена разрядностью смещений в коде команд. Чем данные дальше от PC, тем (в среднем) больше и более тяжёлых команд нужно для их адресации. А при указании .text : { } >FLASH1, FLASH2 как компоновщик раскидает код - неизвестно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 29 февраля Опубликовано 29 февраля · Жалоба + вызов функций из другого региона памяти, как правило, будет идти через виниры, и нафига оно надо? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 29 февраля Опубликовано 29 февраля · Жалоба 29 минут назад, Arlleex сказал: + вызов функций из другого региона памяти, как правило, будет идти через виниры, и нафига оно надо? Я об этом писал: 2 часа назад, jcxz сказал: А в некоторых случаях даже переходы будут осуществляться через специальные промежуточные вставки кода (когда расстояний перехода не хватает) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 29 февраля Опубликовано 29 февраля · Жалоба 13 часов назад, Ivan. сказал: Первые страницы могут иметь маленький размер, а последние по 128 или 256 кБ. Простите, что со своим самоваром встреваю, но в первой странице-двух располагаю загрузчик, позволяющий передавать заказчику зашифрованный образ обновленной прошивки и заливать его через имеющийся интерфейс (а не тот, который решили использовать ST), далее еще один маленький сектор на настройки и все остальное под рабочую программу, ей уже все равно, какого размера сектора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 29 февраля Опубликовано 29 февраля · Жалоба Аффтар, припаяй к свободным ногам I2C EEPROM-ку и не занимайся ерундой)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться