Jump to content
    

Как зарезервировать страницу памяти в середине кода

Доброго!
FLASH память в F4 серии STM контроллеров, да и в F7 или H7 имеет особую структуру: страница имеют не одинаковый размер. Первые страницы могут иметь маленький размер, а последние по 128 или 256 кБ.
Предположим, что в одной из страниц я намереваюсь хранить пользовательские настройки. Первую страницу я не могу занять, т.к. с нее начинается старт программы (при стандартной конфигурации загрузки), а последние слишком большие для хранения нескольких переменных.
Отсюда возникает вопрос, как указать линковщику, в LD скрипте полагаю, чтобы он обошел, например, вторую и третью страницу при сборке?

Share this post


Link to post
Share on other sites

 

14 минут назад, makc сказал:

. = . + 128;

Так как отступ будет от уже какого-то кода, то необходимо предварительное выравнивание:

. = ALIGN(8); /* Заменить на свое значение */
. = . + 128;

 

Edited by pendejo

Share this post


Link to post
Share on other sites

3 минуты назад, pendejo сказал:

Так как отступ будет от уже какого-то кода, то необходимо предварительное выравнивание:

Поскольку речь о принципе (как), а не о конкретной реализации (что), то дополнять можно бесконечно, суть от этого не изменится.

Share this post


Link to post
Share on other sites

А нельзя определить 2 региона
  FLASH1  (rx)    : ORIGIN = 0x8000000,   LENGTH = 16K
  FLASH2  (rx)    : ORIGIN = 0x8008000,   LENGTH = 480K

а потом указать, что секцию .text разместить в этих 2 регионах
  .text :
  {
.....
  } >FLASH1, FLASH2

Share this post


Link to post
Share on other sites

2 минуты назад, makc сказал:

Поскольку речь о принципе (как), а не о конкретной реализации (что), то дополнять можно бесконечно, суть от этого не изменится.

Просто помог автору избежать создания следующей темы "Почему программа не работает, вроде все сделал правильно".

Share this post


Link to post
Share on other sites

Без информации о проекте автора и его ld-скрипта это всё тщетно, всех проблем умозрительно не решить.

PS: вообще подобное манипулирование адресами не очень хорошо, куда правильнее было бы объявить и определить в проекте структуру настроек нужного размера с правилами выравнивания на границу сектора флеша и определить её в отдельную секцию с помощью соответствующих атрибутов gcc, а уже в ld- скрипте положить её в нужное место (по порядку).

Share this post


Link to post
Share on other sites

13 минут назад, makc сказал:

PS: вообще подобное манипулирование адресами не очень хорошо, куда правильнее было бы объявить и определить в проекте структуру настроек нужного размера с правилами выравнивания на границу сектора флеша и определить её в отдельную секцию с помощью соответствующих атрибутов gcc, а уже в ld- скрипте положить её в нужное место (по порядку).

Т.е. сделать перекрытие регионов? 
FLASH занимает все пространство, а SETTINGS внутри региона FLASH

Можно разместить таблицу векторов в FLASH1, а .text и все остальное во FLASH2. Но регион FLASH1 получается недоиспользован.
заполнить его еще чем нибудь вручную, например: Initialized data и постоянно за этим следить? хотелось бы автоматизировать

Edited by Ivan.

Share this post


Link to post
Share on other sites

31 минуту назад, Ivan. сказал:

Т.е. сделать перекрытие регионов? 
FLASH занимает все пространство, а SETTINGS внутри региона FLASH

Есть области памяти (регионы), а есть секции. Секции размещаются в регионах. Я предлагаю следующее: разместить в регионе FLASH последовательно три секции:
.init - адрес точки входа и, возможно, таблица векторов прерываний;
.configuration - секция со структурой данных вашей конфигурации, выровненная на границу минимального стираемого блока флеша;
.text - код, включая точку входа и т.д.
... - всё остальное.

В этом случае всё будет ровно так, как вы хотите. Разрыв будет (пропадёт место), только между секциями .init и .configuration.

Share this post


Link to post
Share on other sites

12 минут назад, makc сказал:

.configuration - секция со структурой данных вашей конфигурации, выровненная на границу минимального стираемого блока флеша;

Выровнять можно, а как указать конкретный адрес? если секция .init займет больше 16К - .configuration сдвинется уже в следующий сектор.
Если он продолжит двигаться, то дойдет до сектора большего размера, но знать об это ничего не будет. И когда я сотру сектор с настройками, то уж точно создавай новую тему.
Во-вторых, если в релизе 1 - секция настроек находилась в секторе 2, а в следующем релизе настройки сдвинулись из-за увеличения секции .init, то хана всем настройкам.
В-третьих в линковку попадет секция настроек и будет каждый раз стираться при перезаливке.

Уж лучше тогда как я писал создать 2 региона и указать в каком регионе что разместить. тогда линковщик выдаст ошибку, есть в регион под .init не влезли данные и я буду об этом знать.
секция настроек никуда самостоятельно не сдвинется и стираться не будет.
 

25 минут назад, makc сказал:

Разрыв будет (пропадёт место)

И в Вашем и в моем случае разрыв будет. По этому я и ищу способ не выбрасывать ~16К на выравнивание. вектора занимают 400Б и init 40Б, а остальное на выравнивание.
Я хочу, чтобы линковщик по максимуму разместил данные в первом секторе, а потом перескочил на третий.

Share this post


Link to post
Share on other sites

2 минуты назад, Ivan. сказал:

Выровнять можно, а как указать конкретный адрес? если секция .init займет больше 16К - .configuration сдвинется уже в следующий сектор.

. = <константа>;

Почитайте ссылку, которую я вам привёл выше.

2 минуты назад, Ivan. сказал:

если секция .init займет больше 16К - .configuration сдвинется уже в следующий сектор.

Это же ваш проект, откуда там может взяться 16K? Всё в ваших руках.

2 минуты назад, Ivan. сказал:

И в Вашем и в моем случае разрыв будет. По этому я и ищу способ не выбрасывать ~16К на выравнивание. вектора занимают 400Б и init 40Б, а остальное на выравнивание.
Я хочу, чтобы линковщик по максимуму разместил данные в первом секторе, а потом перескочил на третий.

Минимизируйте и фиксируйте размер секции .init: опишите её на ассемблере и всё будет фиксировано на 100%.

Share this post


Link to post
Share on other sites

10 минут назад, makc сказал:

. = <константа>;

Спасибо, что-то я пропустил

Share this post


Link to post
Share on other sites

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

 

 

Share this post


Link to post
Share on other sites

6 минут назад, dimka76 сказал:

Я вот так делаю

Здесь нет озвученной ТС фиксации адреса блока параметров. Он может меняться.

Share this post


Link to post
Share on other sites

9 минут назад, dimka76 сказал:

Я вот так делаю

То же, что и я предложил:

2 часа назад, Ivan. сказал:

Можно разместить таблицу векторов в FLASH1, а .text и все остальное во FLASH2. Но регион FLASH1 получается недоиспользован.
заполнить его еще чем нибудь вручную, например: Initialized data и постоянно за этим следить? хотелось бы автоматизировать

 

3 минуты назад, makc сказал:

Здесь нет озвученной ТС фиксации адреса блока параметров. Он может меняться.

Все определено:

10 минут назад, dimka76 сказал:
SETTINGS_FLASH (rx)	: ORIGIN = 0x08004000, LENGTH = 16K

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...