|
|
  |
как записать параметр во Flash МК? |
|
|
|
May 10 2017, 08:03
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944

|
В процессе разработки появилась идея сохранять параметры (состояние перед выключением устройства) во Flash контроллера. Контроллер Миландровский 1986ВЕ1Т (аналог STM - F103). В описании МК сказано, что при работе с Flash МК программа из неё выполняться не может, значит надо поместить некий обработчик( загрузчик ) в оперативку , записать то что надо, и снова отдавать управление основной программе. Из описания МК я понял, что основная программа размещается с адреса 0х00000000 по 0х00100000, а для загрузчика можно использовать адреса 0х20100000 по 0х20104000.
К сожалению, программист из меня , мягко говоря, чуть ниже среднего. Поэтому просьба подсказать следующее: 1. Как можно в Кейле скомпилировать модуль (загрузчик), который можно целиком записать в нужную область SRAM? ( Сделать его как функцию?) 2. Как этот модуль загрузить в нужную область памяти ? ( конкретно - с адреса 0х20100000) и запустить его? 3. Как из модуля передать управление основной программе? 4. Может есть другие варианты решения данной задачи?
|
|
|
|
|
May 10 2017, 09:07
|

Частый гость
 
Группа: Участник
Сообщений: 177
Регистрация: 10-02-15
Пользователь №: 85 052

|
Здравствуйте. Я, к сожалению, не работал с МК Миландр, деталей их устройства я не знаю. Но я программирую микроконтроллеры STM ARM ST32F4x и STM32F1x. И для них я я решал ту же задачу, записывал настройки во Flash память. Я опишу, как я делал это у себя. Flash память МК поделена на сектора разного размера(16, 32, 64 Кбайт) Стереть можно только сектор целиком. В Reference Manual не ясно написано, должна ли программа при записи во flash выполняться из SRAM или просто из другого Flash сектора. Я посмотрел примеры от ST, в них в SRAM ничего не записывалось и процедура стирания Flash была записана просто в другой Flash сектор. Я так и делаю у себя и это работает. То есть, если я стираю/записываю сектор 10, то программа может выполнятся из Flash, но не в секторе 10. Вот пример того, как я стираю/записываю flash у себя в STM32F4x CODE /** * @brief Запись блока во flash * @dst Адрес назначения(куда копировать) * @src Адрес источника(откуда копировать) * @num Кол-во байт для копирования * @retval dst */ void* flash_memcpy(void* dst, void* src, int num) { int i; irq_disable(); FLASH_Unlock(); for(i = 0; i < num; i++) { FLASH_ProgramByte((uint32_t)(dst) + i, ((uint8_t*)src)[i]); FLASH_WaitForLastOperation(); } FLASH_Lock(); irq_enable(); return dst; }
/** * @brief Стереть содержимое flash-памяти */ void flash_erase(void) { irq_disable(); FLASH_Unlock(); FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3); FLASH_Lock(); irq_enable(); }
Если же Вам все же нужно выполнять программу из SRAM, то в Keil проще всего воспользоваться функциональностью scatter/loader, например, как описано вот здесь. http://www.keil.com/support/docs/3723.htm
|
|
|
|
|
May 10 2017, 16:49
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(Олег Гаврильченко @ May 10 2017, 12:07)  Но я программирую микроконтроллеры STM А я тут как-то атмегу вспоминал. Интерфейс программирования атмеги похож на миландровский примерно так же, как и STM'овский - никак. А в данном случае надо определиться с терминологией, слегка почитать документацию и чуть-чуть погуглить. Загрузчик, или bootloader - программа, стартующая при запуске процессора. В нормальном режиме просто запускает основную программу, в режиме обновления получает откуда-то извне и перезаписывает основную программу. А тут нужно просто написать свои функции стирания и записи страницы флеши (последовательность действий расписана в документации), поместить их в ОЗУ (да, присвоив им нужные атрибуты и отредактировав скаттер; дальше кейл всё сделает сам). Ну и саму структуру с настройками надо придумать. И методику предусмотреть на случай "мы включились, а в прошлый раз вместо настроек какой-то мусор записался". И ещё можно вот сюда подсматривать: http://forum.milandr.ru/viewtopic.php?f=34...tart=300#p11419
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
May 10 2017, 18:49
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 25-08-15
Из: Рыбное
Пользователь №: 88 141

|
NikP, либо можно создать отдельный файл например, "RamFunc.c", в котором написать функцию записи данных во Flash, а потом правой кнопкой мыши по этому файлу в дереве проекта: выбрать поле < Options for File "RamFunc.c" >, и в открывшемся окне найти метку < Memory Assignment > под которой три поля, нужно выбрать поле < Code / Const > и уже в нем выставить месторасположение данной функции в RAM, например, IRAM1 [0x20000000-0x20001FFFF]. Затем все скомпилировать. При вызове данной функции она будет исполняться из RAM.
|
|
|
|
|
May 27 2017, 05:54
|
Группа: Участник
Сообщений: 12
Регистрация: 15-05-17
Пользователь №: 97 085

|
Что-то я не понял. Зачем SRAM? Пиши в свободную флэш из программы, там имеется контроллер внутренней флэш, у него регисты флаги, записывай читай.
|
|
|
|
|
Aug 18 2017, 08:17
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 11-03-08
Пользователь №: 35 811

|
Ну к примеру __ramfunc void flash_write(unsigned int address, unsigned int *pBuffer,unsigned int command) ключевое слово __ramfunc говорит о том, что линкер разместит функцию в RAM, по адресу рам. Фактически в рам нужно разместить только запись команды в регистр работы с флешем и ожидания снятия флага записи.
|
|
|
|
|
Aug 18 2017, 10:39
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(ViKo @ Aug 18 2017, 09:21)  А как код функции попадет в ОЗУ? Что и когда скопирует этот код из флэш-памяти? Я с таким делом не сталкивался, интересуюсь. Может, компилятор сам сделает? После сброса. Компилятор и линкер все сделают с необходимыми адресами. Перед вызовом main делается инициализация переменных (data и bss). В этот момент подготовленный для ОЗУ код скопируется из flash по нужным адресам ОЗУ. Для этого в скрипте линкера дополняем секцию data Код .data : AT ( _sidata ) { . = ALIGN(4); _sdata = .; *(.data) *(.data.*) *(.ramfunc) . = ALIGN(4); _edata = .; } >RAM А ОЗУ-шные функции описываем так (для gcc) Код void ram_table_save(void) __attribute__(( section(".ramfunc") ));
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|