Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: сохранение данных во flash stm32f105/107
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
super_puper
хочу сохранять данные, вроде и нашел примеры как записывать и считывать каму не жалко выкидывайте свои.. но вот как определить какая область не будет использоваться? для памяти программ или как-то искуственно её ограничить в IARe
Golikov A.
последние.

Все компиляторы и среды позволяют ограничить объем используемой флэш. Обычно в конце отводят сектор другой, и туда все пишут. Удобно тем что сохраненное не теряется даже при перепрошивке основной программы.

хотя учитывая объем флэш памяти современных АРМов, а также уровень вашего вопроса, вы можете писать в последний адрес флэш вообще ничего не делая, ваша программа туда просто не попадет. Вы столько не напишите покаsm.gif...
ViKo
Цитата(Golikov A. @ May 24 2013, 11:14) *
...вы можете писать в последний адрес флэш вообще ничего не делая, ваша программа туда просто не попадет. Вы столько не напишете покаsm.gif...

А когда напишет, то уже не влезет sm.gif Так что... "пишите", пока не "написали"... sm.gif
uriy
у stm есть пример на оффсайте. Название что-то типа eeprom emulator.
super_puper
ну так как мне ограничить область используемой ияром памяти для программы? примеров где не ограничивают итак полно. вот файл ицфник тут что то исправить надо наверное..
CODE
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/


define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];

define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };

initialize by copy { readwrite };
do not initialize { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };

Golikov A.
перевидите на русский вот этот кусочек, пожалуйста

/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF;
super_puper
да это понятно что в этих строчках я просто вместо 0х08.... искал программу в 0х8... регионах памяти и не мог найти)
непонятно почему такой диапазон установлен большой ведь флеш всего 256к мне кажется надо поменять на __ICFEDIT_region_ROM_end__ = 0x0803FFFF;//(256k) а далее по даташиту идет резервед
Golikov A.
ну процов то много разных, у этого 256, а есть и с 64 и с 16. В будущем 512 и мегабайт появятся... потому так универсально с запасиком и сделали.

Вам надо еще уменьшить не 256, а (256 - область настроек), и еще жетагу или тому через что вы заливаете прогу тоже надо сказать, чтобы не стирало всю флэш, а последние пару секторов оставляло, чтобы настройки не терялись.
super_puper
кинте кто нибудь пример записи во флэш?( что то не получается...
Golikov A.
не забудьте стереть сначала страницу-сектор в которую пишите.
А потом учитывайте что некоторые процессоры пишут только блоками, не меньше не больше...
AHTOXA
Цитата(super_puper @ May 29 2013, 14:58) *
кинте кто нибудь пример записи во флэш?( что то не получается...

Вот тут кидал.
super_puper
AHTOXA, спасибо но я по ссылке ничего не понял( непривычный там си..
я попробовал вот такой пример как везде предлагают:

CODE
define FLASH_KEY1 ((uint32_t)0x45670123) // ключи для снятия защиты памяти
#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
#define FLASH_PAGE_SIZE ((uint16_t)0x400) // размер страницы 1 кб
#define WRITE_START_ADDR ((uint32_t)0x08003800) // запись с 15го килобайта

//-----------------------стирание

void Erase_flash (u16 adr)
{
u16 dst = WRITE_START_ADDR + adr; // вычисление места записи

FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;

FLASH->CR |= FLASH_CR_PER; /* Page erase */
FLASH->AR = dst;
FLASH->CR|= FLASH_CR_STRT; /* Start erase */
while ((FLASH->SR & FLASH_SR_BSY) != 0 ); /* Wait end of eraze */
FLASH->CR &= ~FLASH_CR_PER; /* Page erase end */

FLASH->CR |= FLASH_CR_LOCK; /* Lock the flash back */
}

//-----------------------запись

void Write_flash (u16 Data, u16 adr)
{
u16 dst = WRITE_START_ADDR + adr;

FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;

FLASH->CR |= FLASH_CR_PG;
while ((FLASH->SR & FLASH_SR_BSY) != 0 );
*(__IO uint16_t*)dst = (uint16_t)Data;
while ((FLASH->SR & FLASH_SR_BSY) != 0 );
FLASH->CR &= ~FLASH_CR_PG;

FLASH->CR |= FLASH_CR_LOCK; /* Lock the flash back */
}


у меня вылетает в бесконечное прерывание проц(
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}

частота 72 мегагерца от HSE кварца 25мег
флэш с двумя пропусками настроенна:
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);

вот так в майне запись делаю:
Erase_flash (1);
Write_flash (3030, 1);

вот так ограничил память программ
define symbol __ICFEDIT_region_ROM_end__ = 0x08003000;//было 0x080FFFFF

но виснет! что делать?(
Golikov A.
есть вариант прочитать в мануале что вызывает это прерывание и проверить... или это не вариант?
super_puper
в каком мануале это описано не подскажите? да и так вроде понятно это прерывание всегда когда ошибка какая то в ходе выполнения программы.
Golikov A.
именно потому что и так понятно, отсюда и вопросы.


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

Как минимум можно правильно обработать прерывание и выйти из него...

думаю в референц мануале должно быть полюбому (хотя бы кратко), ну и в специализированном по прерываниям уже детально...
super_puper
где взять файлы eeprom.h и eeprom.c которые описываются в AN2594 Application note EEPROM emulation in STM32F10x microcontrollers странно что дока есть а файлов нет на сайте ст(
Gunner
QUOTE (super_puper @ Jun 5 2013, 05:35) *
где взять файлы eeprom.h и eeprom.c которые описываются в AN2594 Application note EEPROM emulation in STM32F10x microcontrollers странно что дока есть а файлов нет на сайте ст(

Это?
http://www.st.com/web/en/catalog/tools/PF257846

super_puper
оо спасибо большое как вы нашли? я поразному в поиске пробовал слова вводить..
а ничего что у меня stm32f107 а тут EEPROM emulation in STM32F101xx and STM32F103xx microcontrollers ?
scifi
Цитата(super_puper @ Jun 5 2013, 10:05) *
а ничего что у меня stm32f107 а тут EEPROM emulation in STM32F101xx and STM32F103xx microcontrollers ?

Ничего. Разница была бы между STM32F1xx и STM32F2xx. А внутри одного семейства флэш устроена одинаково.
nanorobot
Цитата(scifi @ Jun 5 2013, 12:25) *
Ничего. Разница была бы между STM32F1xx и STM32F2xx. А внутри одного семейства флэш устроена одинаково.


Экзампл ихний сперва обескураживает.. Поначалу неясно зачем там VirtAdrTab, и как сохранить более чем 3 переменных. От VirtAdrTab следует отказаться, а в качестве виртуальных адресов использовать VarIdx (требуется минимальная правка eeprom.c) . А в качестве NB_OF_VAR задефайнить sizeof() сохраняемой структуры переменных.
super_puper
я не понял как вы переделали я изменил количество переменных до 256 а было 3
#define NumbOfVar ((uint8_t)0xFF)// резервирую 256 переменных в виртуал еепром

и в майне создаю массив виртуальных 256 адресов
for (u8 mm=0;mm<255;mm++){VirtAddVarTab[mm]=mm;}
nanorobot
Цитата(super_puper @ Jun 7 2013, 09:20) *
я не понял как вы переделали я изменил количество переменных до 256 а было 3
#define NumbOfVar ((uint8_t)0xFF)// резервирую 256 переменных в виртуал еепром

и в майне создаю массив виртуальных 256 адресов
for (u8 mm=0;mm<255;mm++){VirtAddVarTab[mm]=mm;}


А чем виртуальные адреса принципиально отличаются от их индекса (mm - у Вас. более того они равны: VirtAddVarTab[mm]=mm ). В примере были адреса из четырех одинаковых цифр, чисто для удобства наблюдения в ихних иллюстрациях, либо под отладчиком. Уберите лишнее промежуточное звено - используйте в качестве адреса сам индекс (mm) - они ведь тоже уникальны: 0..255. Оно, конечно, и так будет работать, только к чему лишние навороты, ровно ничего не дающие..
super_puper
а ну да верно.. как это я не заметил.. сейчас пишу без массива напрямую и имя функций укоротил все работает:
EE_Write(60000, 12345);
EE_Read(60000, Read_data);
example=Read_data[0];

непонятно почему они сделали что переменную можно вывести только в первый элемент массива.. а не в переменную например. приходится лишнюю строчку писать : example=Read_data[0];

теперь получается у меня 65535 2х байтных данных могу записать.. итого 131070 байт ..
Golikov A.
что-то мне подсказывает что если кто-то почитает книжку по С, то для него сделают вывод куда угодно...
EE_Read(60000, (void *)&example);
EE_Read(60000, (char *)&example);
EE_Read(60000, (int *)&example);

только надо про выравнивание помнить...
super_puper
спасибо работает)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.