Перейти к содержанию
    

как записать параметр во Flash МК?

 

В процессе разработки появилась идея сохранять параметры (состояние перед выключением устройства) во Flash контроллера. Контроллер Миландровский 1986ВЕ1Т (аналог STM - F103).

В описании МК сказано, что при работе с Flash МК программа из неё выполняться не может, значит надо поместить некий обработчик( загрузчик ) в оперативку , записать то что надо, и снова отдавать управление основной программе.

Из описания МК я понял, что основная программа размещается с адреса 0х00000000 по 0х00100000, а для загрузчика можно использовать адреса 0х20100000 по 0х20104000.

 

К сожалению, программист из меня , мягко говоря, чуть ниже среднего. Поэтому просьба подсказать следующее:

1. Как можно в Кейле скомпилировать модуль (загрузчик), который можно целиком записать в нужную область SRAM? ( Сделать его как функцию?)

2. Как этот модуль загрузить в нужную область памяти ? ( конкретно - с адреса 0х20100000) и запустить его?

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

4. Может есть другие варианты решения данной задачи?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте. Я, к сожалению, не работал с МК Миландр, деталей их устройства я не знаю. Но я программирую микроконтроллеры STM ARM ST32F4x и STM32F1x. И для них я я решал ту же задачу, записывал настройки во Flash память. Я опишу, как я делал это у себя. Flash память МК поделена на сектора разного размера(16, 32, 64 Кбайт) Стереть можно только сектор целиком. В Reference Manual не ясно написано, должна ли программа при записи во flash выполняться из SRAM или просто из другого Flash сектора. Я посмотрел примеры от ST, в них в SRAM ничего не записывалось и процедура стирания Flash была записана просто в другой Flash сектор. Я так и делаю у себя и это работает.

То есть, если я стираю/записываю сектор 10, то программа может выполнятся из Flash, но не в секторе 10.

Вот пример того, как я стираю/записываю flash у себя в STM32F4x

 

/**
* @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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но я программирую микроконтроллеры STM

А я тут как-то атмегу вспоминал. Интерфейс программирования атмеги похож на миландровский примерно так же, как и STM'овский - никак.

 

А в данном случае надо определиться с терминологией, слегка почитать документацию и чуть-чуть погуглить.

 

Загрузчик, или bootloader - программа, стартующая при запуске процессора. В нормальном режиме просто запускает основную программу, в режиме обновления получает откуда-то извне и перезаписывает основную программу.

 

А тут нужно просто написать свои функции стирания и записи страницы флеши (последовательность действий расписана в документации), поместить их в ОЗУ (да, присвоив им нужные атрибуты и отредактировав скаттер; дальше кейл всё сделает сам).

Ну и саму структуру с настройками надо придумать. И методику предусмотреть на случай "мы включились, а в прошлый раз вместо настроек какой-то мусор записался".

 

И ещё можно вот сюда подсматривать: http://forum.milandr.ru/viewtopic.php?f=34...tart=300#p11419

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В процессе разработки появилась идея сохранять параметры (состояние перед выключением устройства) во Flash контроллера. Контроллер Миландровский 1986ВЕ1Т (аналог STM - F103).

В описании МК сказано, что при работе с Flash МК программа из неё выполняться не может, значит надо поместить некий обработчик( загрузчик ) в оперативку , записать то что надо, и снова отдавать управление основной программе.

Ничего такого не надо.

Надо просто подпрограмму записи во Flash разместить в RAM, в Keil это ключевое слово _RAMFUNC.. И при её вызове из основной программы запретить прерывания. При возврате - прерывания разрешить.

Примеры можно посмотреть в SPL( в файле MDR32F9Qx_eeprom.c) , который можно скачать здесь

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

NikP, либо можно создать отдельный файл например, "RamFunc.c", в котором написать функцию записи данных во Flash, а потом правой кнопкой мыши по этому файлу в дереве проекта: выбрать поле < Options for File "RamFunc.c" >, и в открывшемся окне найти метку < Memory Assignment > под которой три поля, нужно выбрать поле < Code / Const > и уже в нем выставить месторасположение данной функции в RAM, например, IRAM1 [0x20000000-0x20001FFFF].

Затем все скомпилировать. При вызове данной функции она будет исполняться из RAM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Программа программирования флеш-памяти Миландра должна выполняться в ОЗУ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как код функции попадет в ОЗУ? Что и когда скопирует этот код из флэш-памяти? Я с таким делом не сталкивался, интересуюсь. Может, компилятор сам сделает? После сброса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну к примеру __ramfunc void flash_write(unsigned int address, unsigned int *pBuffer,unsigned int command)

ключевое слово __ramfunc говорит о том, что линкер разместит функцию в RAM, по адресу рам.

Фактически в рам нужно разместить только запись команды в регистр работы с флешем и ожидания снятия флага записи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как код функции попадет в ОЗУ? Что и когда скопирует этот код из флэш-памяти? Я с таким делом не сталкивался, интересуюсь. Может, компилятор сам сделает? После сброса.

Компилятор и линкер все сделают с необходимыми адресами.

Перед вызовом 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") ));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...