C Embedded. Как правильно распределять память и создавать вокруг нее память внутри STM32?

Я создаю систему с STM32, которая использует устройство, которое необходимо откалибровать (данные могут храниться в одном 32-битном регистре). Поскольку я все еще создаю и обновляю код, в идеале мне бы хотелось, чтобы регион оставался в том же месте, чтобы каждый раз, когда я собираю и включаю его, не приходилось перекалибровывать его. Очевидно, что MCU не инициализирует значения в этой области, учитывая данные калибровки.

Прямо сейчас я только что выбрал удаленный адрес внутри флэш-региона и надеюсь, что компилятор не перепишет его. Он работает отлично, но кажется, что есть правильный способ заблокировать память со стороны компилятора.

Обычно вы настраиваете это через специальный сегмент в своем скрипте компоновщика, а затем либо загружаете значения по умолчанию вместе с программой, либо иным образом устанавливаете для него значение «no init» и сохраняете предыдущие значения - которые будут записаны загрузчиком или аналогичным во время выполнения. . В идеале это должна быть EEPROM или флэш-память, чтобы вам не приходилось стирать большую ее часть каждый раз, когда вы обновляете значение. И чтобы не пришлось прибегать к злым ухищрениям вроде выполнения алгоритма прошивки из ОЗУ, потому что код во флеше не может выполняться, пока программа перепрограммируется.

Lundin 01.07.2024 10:54

Непонятно, о чем вы спрашиваете. Предположительно, эти калибровочные данные должны быть энергонезависимыми? Для этого вы можете использовать «резервные регистры», если они есть в вашем конкретном STM32, но для этого вам также потребуется резервная батарея — они энергонезависимы только в том смысле, что имеют независимый источник питания. В противном случае внешний EEPROM. Сохранение таких данных на встроенной флэш-памяти возможно, но неэффективно — вам обязательно придется посвятить этому целую флэш-страницу. Разделы без инициализации применимы только к SRAM, и они не являются энергонезависимыми — данные будут потеряны при отключении питания.

Clifford 01.07.2024 11:31

Также обратите внимание, что ваш вопрос мало специфичен для встроенного C, управления памятью или даже stm32cubeide - не спамьте теги. Это все зависит от вашего конкретного оборудования в отношении емкости NV-хранилища и схемы электропитания. Вы не уточнили это.

Clifford 01.07.2024 11:35

«Компилятор» ничего не записывает — поведение, о котором вы говорите, является делом компоновщика. Использование флэш-памяти для этого проблематично, и хотя она доступна для записи слов, она допускает стирание страниц. Большинство деталей STM32 имеют страницы большого размера и переменной длины. Меньшие части могут иметь страницы одинакового размера, но даже в этом случае они, скорее всего, будут иметь размер 2 КБ или более.

Clifford 01.07.2024 11:39

Я думаю, что некоторые детали STM32 имеют эмуляцию EEPROM. Опять же, вам нужно быть конкретным. Запись «переменных» данных во Flash далеко не идеальна.

Clifford 01.07.2024 11:41

@Клиффорд, извините - это похоже на один из тех вопросов, которые находятся между EE и переполнением стека. Я действительно ищу способ настроить энергонезависимую область памяти на моей флэш-памяти STM32, используя мою IDE (IDE-куб). Я думаю, что конкретные регионы адресов зависят от аппаратного обеспечения, но я не уверен, как правильно записать это в программу, кроме простого выбора неиспользуемого адреса и надежды на лучшее, как я сейчас.

ezra_vdj 01.07.2024 15:12

Совет, не зависящий от микроконтроллера: размещение калибровочных данных на одной из последних страниц флэш-памяти может быть осуществимо, если вы каким-то образом можете гарантировать, что ваши образы обновления программного обеспечения никогда не будут достаточно большими, чтобы перезаписать эти страницы. У вас также должна быть резервная копия (или две) на отдельных флэш-страницах, целостность которых обеспечивается контрольными суммами или ECC. Если когда-либо произойдет переворот битов в какой-либо из этих калибровочных данных, вы либо захотите исправить ее, либо пометить ее как плохую (никогда ей нельзя доверять) и использовать одну из избыточных копий.

Andy J 01.07.2024 15:17

Что ж, если вам необходимо сделать это таким образом, очевидно, что выбор произвольного адреса неприемлем. Ответ заключается в том, чтобы зарезервировать пространство с помощью сценария компоновщика, либо пропустив его, либо явно создав именованный регион. Однако я говорю, что это вряд ли будет приемлемым решением. Все возможные методы обычно включают энергонезависимое хранилище, которое не отображается в памяти или не находится в обычной памяти, видимой компоновщику.

Clifford 01.07.2024 15:41

@AndyJ, учитывая, что флэш-страницы в конце флэш-памяти на STM32 состоят из больших частей размером до 128 КБ, это может быть непрактичным советом. Поскольку флэш-память, которую вы предлагаете, также является памятью кода, любая возможность «битового переворота» имеет гораздо более широкие последствия, чем просто эти данные - это не является практическим соображением. Более вероятный сценарий — сбой питания во время операции стирания или записи.

Clifford 01.07.2024 15:43

В любом случае, если вам нужен лучший совет, вам нужно конкретно указать MCU и плату, которую вы используете. На самом деле это проблема XY. Вы спрашиваете, как сделать что-то, что, вероятно, не является лучшим решением реальной проблемы, а именно: как хранить данные калибровки. Также было бы полезно понять, когда выполняется калибровка.

Clifford 01.07.2024 15:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
10
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Очень простой процесс. Сначала в файле компоновщика (.ld) создается область памяти:

MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 24K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 128K
  CALIBRATION (rx) : ORIGIN = 0x0801FFE0,   LENGTH = 8 /* new 8 byte section */
}

Затем в разделе разделов несколькими строками ниже я добавил:

.calibration (NOLOAD) :
  {
    . = ALIGN(4);
    KEEP(*(.calibration))
    . = ALIGN(4);
  } >CALIBRATION

Ключевой частью является NOLOAD, который гарантирует, что значения внутри не инициализируются при запуске.

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

volatile uint32_t *calibration_value = (uint32_t *)0x0801FFE0; // create pointer at address
InitialCalib = *calibration_value; // use deferenced pointer to access data

Вам следует избегать магического числа в коде. Определите символ в скрипте компоновщика с помощью PRODIVE: sourceware.org/binutils/docs/ld/PROVIDE.html см. также: sourceware.org/binutils/docs/ld/REGION_005fALIAS.html

harper 02.07.2024 08:21

Другие вопросы по теме