Обновить

Размещение глобальных констант по фиксированным адресам

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели8.6K
Всего голосов 9: ↑6 и ↓3+7
Комментарии19

Комментарии 19

Не лучше выделить пару страниц под простую фс и заливать данные подобного рода уже после прошивки? Таким образом при проверке целостности прошивки у вас будут одинаковые контрольные суммы для каждого экземпляра устройства, что может быть критично в контроле при серийном производстве? И так же можно отдельно контролировать целостность данных в фс, отдельно хранить "слепки" фс для каждого устройства при необходимости восстановления/разбора инцидентов, легче организовать шифрование данных.

Да. Это лучше. Называется NVRAM.

NVRAM для микроконтроллеров / Хабр https://share.google/PdklZbkBffAkOMTkp

Если есть решение лучше, зачем танцы с бубном вокруг худшего?

Фиксированные адреса в купе с TunerPRO -
это простое паллиативное решение для тех, кто в силу своей некомпетентности не может запустить в прошивке полноценный NVRAM.

Как будто тот же LittleFS поднять все ещё проще, и работать будет одинаково в любом инструментарии. Разве что файл линковщика желательно все же поправить для выделения секции. Я честно не могу себе представить сценария, где-нужно так заморачиваться с хранением констант, разве, что флеша прямо совсем не хватает.

Да. В mik32 flash как раз мало: 8к байт.

На работе активно используем этот приём с компоновкой настроек через секцию линковщика, кстати это успешно реализуется и в Keil, IAR, даже в MSVC. Но тут есть нюансы. 1. Константу придётся помечать как volatile так как компилятор вполне может встроить значение константы вместо фактического чтения из ПЗУ. 2. Не гарантируется фиксированный порядок расположения констант в секции. Например если добавляется один новый uint8_t, то он может попасть где то по середине так как с учётом выравнивания линковщик старается плотнее расположить данные.

Константу придётся помечать как volatile так как компилятор вполне может встроить значение константы вместо фактического чтения из ПЗУ. 

Если в GCC объявить глобально
const volatile uint8_t val = 10;
то переменная val окажется в RAM памяти.

С GCC плотно не работал, но звучит сомнительно. Если вы явно указываете секцию, то символ там и будет. Именно такое поведение было на компиляторах указанных выше.

если секцию явно не указывать, то
const volatile uint8_t val = 10;
переменная val окажется в RAM памяти.

Вчера проверил. Не работает.
Да, переменная в самом деле уходит в Flash, но компилятор всё равно печать константы заменяет на константную строку. Даже для const volatile

Не гарантируется фиксированный порядок расположения констант в секции. Например если добавляется один новый uint8_t, то он может попасть где то по середине так как с учётом выравнивания линковщик старается плотнее расположить данные.

Тогда заворачиваем все эти переменные в структуру.

Я был очень удивлён, что вы этого не сделали в статье (заполировав это дело #pragma pack).

А в чем практическая необходимость такого решения?

Поздравляю вы научились пользоваться линкером и атрибутом для указания секций

Спасибо.

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

Нужна инструкция.

objcopy --update-section .name=newdata.bin fmw.elf

Подставьте свои имена

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации