Перейти к содержанию
    

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

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

. = . + 128;

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

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

 

Изменено пользователем pendejo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

Изменено пользователем Ivan.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

 

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

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

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...