Цитата(RiseOfDeath @ Oct 19 2015, 14:00)

Сосбтвенно что я хочу:
Я использую встроенную нанду для хранения настроек и хочу чтобы при программировании контроллера в него сразу, вместе с программой, зашивались настройки по-умолчанию. (читать и писать программа умеет, но надо чтобы вместо стандартных 0xff в нужной области памяти "изначально" были какие-то определенные значения)
Я предполагаю что мне надо как-то получить на выходе из программы такой hex, чтобы после программирования им контроллера, помимо собственно программы, в жестко заданной области памяти, был тот самый "набор двоичных данных".
Мне кажется, Вашу задачу надо переформулировать так: в программе имеются константы настройки, которые необходимо менять в процессе работы. Эти константы есть часть кода, поэтому говорить о хранении настроек в области "свободной" памяти, как бы вне программы, неверно, т.к. настройки есть часть программного кода в рамках занимаемой памяти.
В принципе, все достаточно просто:
1. Настройка - это есть константа во флэше, объявленная в рамках исходного кода, например:
Код
const float MyCoeff = 5.5;
Очевидно, что 5.5 - это значение по-умолчанию, которое и будет " грузиться" во флэш вместе с программой во время записи/обновления кода. Вот Вам и зашивка настроек по-умолчанию. Также очевидно, что использование настройки в коде есть ни что иное как просто использование имени константы в выражениях.
2. Т.к. предполагается менять значение константы, ее нельзя смешивать с исполняемым кодом, а надо разместить где-то отдельно, чтобы безболезненно переписывать флэш и не завалить код. Это проистекает из принципа работы флэша с постраничными стираниями/записью. Для этого константу для начала надо поместить в известную секцию:
Код
const float MyCoeff __attribute__((section("MYSETTINGS"), used)) = 5.5;
Так нужно поступить со всеми подобными константами-настройками. Компоновщик соберет затем все такие константы в одну секцию.
3. Теперь надо поработать ручками и модифицировать файл скаттера (скрипта компоновщика). Например,
Код
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
;
; Assume 64Flash
;
LR_IROM1 0x08000000 0x00010000 { ; load region size_region
ER_IROM1 0x08000000 0x00010000 {; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00002000 {; RW data
.ANY (+RW +ZI)
}
}
;
; In-flash rewritable params, size 1K, must be 1K aligned (page size of used CPU)
;
LR_IROM3 (0x08000000 + (0x00010000-0x400)) 0x400 ; load region size_region
{
ER_IROM3 (0x08000000 + (0x00010000-0x400)) 0x400 ; load address = execution address
{
*(MYSETTINGS)
}
}
Здесь дано указание компоновщику создать загружаемый регион LR_IROM3 размером в 1К (это размер страницы в STM32F051), а в нем - подрегион ER_IROM3, в котором и соберутся все настройки. Использована последняя страница флэша. Если посмотреть карту памяти готовой программы, можно разместить страницу настроек и непосредственно (но выровненно на страницу!) за "основным" кодом, указав нужные адреса, но лично мне последняя страница нравится больше.
4. Для модификации значений из кода программы надо, очевидно, прочитать всю страницу в буфер, модифицировать значение настройки в буфере по смещению и записать страницу назад по месту.
Смещение будет ((int)&MyCoeff)%0x400. Базовый адрес всей страницы можно вычислить из любой настройки в странице как ((int)&MyCoeff)/0x400*0x400. Это все, конечно, при условии, что все настройки помещаются в одну страницу. Для объемных настроек, пересекающих границы страниц (структуры), нужны соответствующие многостраничные алгоритмы записи во флэш. Или можно выровнять все настройки так, чтобы они никогда не пересекали страницу. Есть еще интересная возможность у компоновщика генерировать константы, доступные в программе. Например, базовый адрес региона можно получить как (void *)&Load$$LR$$LR_IROM3$$Base, а длину региона как (int)&Load$$LR$$LR_IROM3$$Length.
5. Если на образ ELF "натравить" утилиту fromelf.exe как
Код
fromelf.exe --i32 myproject.axf --output myproject.hex
то будет создан ПОДКАТАЛОГ myproject.hex, в котором появятся два файла с именами ER_IROM1 и ER_IROM3 и без расширений. На самом деле это *.HEX файлы. В файле ER_IROM3 собраны все настройки.
6. Внешняя программа, которая хочет модифицировать такой файл, должна, конечно, знать, по какому смещению какая переменная находится. Это нетривиальная задача, особенно по мере развития программы, версий, и т.п. Можно предложить путь дескрипторов или меток. Например, метки всегда четырехбуквенные:
Код
const char myLabel __attribute__((section("MYSETTINGS"), used)) = "MYCO";
const float MyCoeff __attribute__((section("MYSETTINGS"), used)) = 5.5;
Внешняя программа может найти строку MYCO и знать, что после нее идет MyCoeff.
Сообщение отредактировал KnightIgor - Oct 27 2015, 14:27