реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> как записать параметр во Flash МК?
NikP
сообщение May 10 2017, 08:03
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 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. Может есть другие варианты решения данной задачи?

Go to the top of the page
 
+Quote Post
Олег Гаврильченк...
сообщение May 10 2017, 09:07
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
esaulenka
сообщение May 10 2017, 16:49
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 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


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
HardEgor
сообщение May 10 2017, 18:19
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925



Цитата(NikP @ May 10 2017, 15:03) *
В процессе разработки появилась идея сохранять параметры (состояние перед выключением устройства) во Flash контроллера. Контроллер Миландровский 1986ВЕ1Т (аналог STM - F103).
В описании МК сказано, что при работе с Flash МК программа из неё выполняться не может, значит надо поместить некий обработчик( загрузчик ) в оперативку , записать то что надо, и снова отдавать управление основной программе.

Ничего такого не надо.
Надо просто подпрограмму записи во Flash разместить в RAM, в Keil это ключевое слово _RAMFUNC.. И при её вызове из основной программы запретить прерывания. При возврате - прерывания разрешить.
Примеры можно посмотреть в SPL( в файле MDR32F9Qx_eeprom.c) , который можно скачать здесь
Go to the top of the page
 
+Quote Post
ivan24190
сообщение May 10 2017, 18:49
Сообщение #5


Участник
*

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



NikP, либо можно создать отдельный файл например, "RamFunc.c", в котором написать функцию записи данных во Flash, а потом правой кнопкой мыши по этому файлу в дереве проекта: выбрать поле < Options for File "RamFunc.c" >, и в открывшемся окне найти метку < Memory Assignment > под которой три поля, нужно выбрать поле < Code / Const > и уже в нем выставить месторасположение данной функции в RAM, например, IRAM1 [0x20000000-0x20001FFFF].
Затем все скомпилировать. При вызове данной функции она будет исполняться из RAM.
Go to the top of the page
 
+Quote Post
NikP
сообщение May 15 2017, 07:05
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Всем большое спасибо за дельные советы!
Go to the top of the page
 
+Quote Post
linuxbergi
сообщение May 27 2017, 05:54
Сообщение #7





Группа: Участник
Сообщений: 12
Регистрация: 15-05-17
Пользователь №: 97 085



Что-то я не понял. Зачем SRAM? Пиши в свободную флэш из программы, там имеется контроллер внутренней флэш, у него регисты флаги, записывай читай.
Go to the top of the page
 
+Quote Post
etoja
сообщение Aug 18 2017, 05:51
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



Программа программирования флеш-памяти Миландра должна выполняться в ОЗУ.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 18 2017, 06:21
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



А как код функции попадет в ОЗУ? Что и когда скопирует этот код из флэш-памяти? Я с таким делом не сталкивался, интересуюсь. Может, компилятор сам сделает? После сброса.
Go to the top of the page
 
+Quote Post
Kibi
сообщение Aug 18 2017, 08:17
Сообщение #10


Участник
*

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



Ну к примеру __ramfunc void flash_write(unsigned int address, unsigned int *pBuffer,unsigned int command)
ключевое слово __ramfunc говорит о том, что линкер разместит функцию в RAM, по адресу рам.
Фактически в рам нужно разместить только запись команды в регистр работы с флешем и ожидания снятия флага записи.
Go to the top of the page
 
+Quote Post
adnega
сообщение Aug 18 2017, 10:39
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 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") ));
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 02:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01435 секунд с 7
ELECTRONIX ©2004-2016