Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба Доброго! FLASH память в F4 серии STM контроллеров, да и в F7 или H7 имеет особую структуру: страница имеют не одинаковый размер. Первые страницы могут иметь маленький размер, а последние по 128 или 256 кБ. Предположим, что в одной из страниц я намереваюсь хранить пользовательские настройки. Первую страницу я не могу занять, т.к. с нее начинается старт программы (при стандартной конфигурации загрузки), а последние слишком большие для хранения нескольких переменных. Отсюда возникает вопрос, как указать линковщику, в LD скрипте полагаю, чтобы он обошел, например, вторую и третью страницу при сборке? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 29 февраля Опубликовано 29 февраля · Жалоба . = . + 128; Пропуск 128 байт. https://ftp.gnu.org/pub/old-gnu/Manuals/ld-2.9.1/html_node/ld_10.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pendejo 0 29 февраля Опубликовано 29 февраля (изменено) · Жалоба 14 минут назад, makc сказал: . = . + 128; Так как отступ будет от уже какого-то кода, то необходимо предварительное выравнивание: . = ALIGN(8); /* Заменить на свое значение */ . = . + 128; Изменено 29 февраля пользователем pendejo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 29 февраля Опубликовано 29 февраля · Жалоба 3 минуты назад, pendejo сказал: Так как отступ будет от уже какого-то кода, то необходимо предварительное выравнивание: Поскольку речь о принципе (как), а не о конкретной реализации (что), то дополнять можно бесконечно, суть от этого не изменится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба А нельзя определить 2 региона FLASH1 (rx) : ORIGIN = 0x8000000, LENGTH = 16K FLASH2 (rx) : ORIGIN = 0x8008000, LENGTH = 480K а потом указать, что секцию .text разместить в этих 2 регионах .text : { ..... } >FLASH1, FLASH2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pendejo 0 29 февраля Опубликовано 29 февраля · Жалоба 2 минуты назад, makc сказал: Поскольку речь о принципе (как), а не о конкретной реализации (что), то дополнять можно бесконечно, суть от этого не изменится. Просто помог автору избежать создания следующей темы "Почему программа не работает, вроде все сделал правильно". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 29 февраля Опубликовано 29 февраля · Жалоба Без информации о проекте автора и его ld-скрипта это всё тщетно, всех проблем умозрительно не решить. PS: вообще подобное манипулирование адресами не очень хорошо, куда правильнее было бы объявить и определить в проекте структуру настроек нужного размера с правилами выравнивания на границу сектора флеша и определить её в отдельную секцию с помощью соответствующих атрибутов gcc, а уже в ld- скрипте положить её в нужное место (по порядку). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля (изменено) · Жалоба 13 минут назад, makc сказал: PS: вообще подобное манипулирование адресами не очень хорошо, куда правильнее было бы объявить и определить в проекте структуру настроек нужного размера с правилами выравнивания на границу сектора флеша и определить её в отдельную секцию с помощью соответствующих атрибутов gcc, а уже в ld- скрипте положить её в нужное место (по порядку). Т.е. сделать перекрытие регионов? FLASH занимает все пространство, а SETTINGS внутри региона FLASH Можно разместить таблицу векторов в FLASH1, а .text и все остальное во FLASH2. Но регион FLASH1 получается недоиспользован. заполнить его еще чем нибудь вручную, например: Initialized data и постоянно за этим следить? хотелось бы автоматизировать Изменено 29 февраля пользователем Ivan. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 29 февраля Опубликовано 29 февраля · Жалоба 31 минуту назад, Ivan. сказал: Т.е. сделать перекрытие регионов? FLASH занимает все пространство, а SETTINGS внутри региона FLASH Есть области памяти (регионы), а есть секции. Секции размещаются в регионах. Я предлагаю следующее: разместить в регионе FLASH последовательно три секции: .init - адрес точки входа и, возможно, таблица векторов прерываний; .configuration - секция со структурой данных вашей конфигурации, выровненная на границу минимального стираемого блока флеша; .text - код, включая точку входа и т.д. ... - всё остальное. В этом случае всё будет ровно так, как вы хотите. Разрыв будет (пропадёт место), только между секциями .init и .configuration. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба 12 минут назад, makc сказал: .configuration - секция со структурой данных вашей конфигурации, выровненная на границу минимального стираемого блока флеша; Выровнять можно, а как указать конкретный адрес? если секция .init займет больше 16К - .configuration сдвинется уже в следующий сектор. Если он продолжит двигаться, то дойдет до сектора большего размера, но знать об это ничего не будет. И когда я сотру сектор с настройками, то уж точно создавай новую тему. Во-вторых, если в релизе 1 - секция настроек находилась в секторе 2, а в следующем релизе настройки сдвинулись из-за увеличения секции .init, то хана всем настройкам. В-третьих в линковку попадет секция настроек и будет каждый раз стираться при перезаливке. Уж лучше тогда как я писал создать 2 региона и указать в каком регионе что разместить. тогда линковщик выдаст ошибку, есть в регион под .init не влезли данные и я буду об этом знать. секция настроек никуда самостоятельно не сдвинется и стираться не будет. 25 минут назад, makc сказал: Разрыв будет (пропадёт место) И в Вашем и в моем случае разрыв будет. По этому я и ищу способ не выбрасывать ~16К на выравнивание. вектора занимают 400Б и init 40Б, а остальное на выравнивание. Я хочу, чтобы линковщик по максимуму разместил данные в первом секторе, а потом перескочил на третий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 29 февраля Опубликовано 29 февраля · Жалоба 2 минуты назад, Ivan. сказал: Выровнять можно, а как указать конкретный адрес? если секция .init займет больше 16К - .configuration сдвинется уже в следующий сектор. . = <константа>; Почитайте ссылку, которую я вам привёл выше. 2 минуты назад, Ivan. сказал: если секция .init займет больше 16К - .configuration сдвинется уже в следующий сектор. Это же ваш проект, откуда там может взяться 16K? Всё в ваших руках. 2 минуты назад, Ivan. сказал: И в Вашем и в моем случае разрыв будет. По этому я и ищу способ не выбрасывать ~16К на выравнивание. вектора занимают 400Б и init 40Б, а остальное на выравнивание. Я хочу, чтобы линковщик по максимуму разместил данные в первом секторе, а потом перескочил на третий. Минимизируйте и фиксируйте размер секции .init: опишите её на ассемблере и всё будет фиксировано на 100%. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба 10 минут назад, makc сказал: . = <константа>; Спасибо, что-то я пропустил Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 62 29 февраля Опубликовано 29 февраля · Жалоба On 2/29/2024 at 7:49 AM, Ivan. said: А нельзя определить 2 региона Я вот так делаю Spoiler /* Specify the memory areas */ MEMORY { ISR_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K SETTINGS_FLASH (rx) : ORIGIN = 0x08004000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 96K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(8); _image_start = ABSOLUTE(.); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(8); } >ISR_FLASH .settings : { . = ALIGN(2048); _settings = .; KEEP(*(.settings)) KEEP(*(.settings*)) . = ALIGN(2048); } >SETTINGS_FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(8); *(.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(8); _etext = .; /* define a global symbols at end of code */ } >FLASH Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 222 29 февраля Опубликовано 29 февраля · Жалоба 6 минут назад, dimka76 сказал: Я вот так делаю Здесь нет озвученной ТС фиксации адреса блока параметров. Он может меняться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 29 февраля Опубликовано 29 февраля · Жалоба 9 минут назад, dimka76 сказал: Я вот так делаю То же, что и я предложил: 2 часа назад, Ivan. сказал: Можно разместить таблицу векторов в FLASH1, а .text и все остальное во FLASH2. Но регион FLASH1 получается недоиспользован. заполнить его еще чем нибудь вручную, например: Initialized data и постоянно за этим следить? хотелось бы автоматизировать 3 минуты назад, makc сказал: Здесь нет озвученной ТС фиксации адреса блока параметров. Он может меняться. Все определено: 10 минут назад, dimka76 сказал: SETTINGS_FLASH (rx) : ORIGIN = 0x08004000, LENGTH = 16K Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться