Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема в работе с flash-памятью меги
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Len_OK
Ребята помогите разобраться с такой проблемкой!Мне нужно хранить во флеше данные и по мере их изменения перезаписывать.Написала процедурки, проверила размещение во флеше- всё верно, только после перезаписи подвисает
KRS
А eeprom не хватает?
Len_OK
Цитата(KRS @ Feb 15 2008, 13:16) *
А eeprom не хватает?

Мне просто поставлено задание, записать во флеш!Потому что из еепром слетали данные
bloodden
Писать во флеш можно ТОЛЬКО из области бутлоадера.
aesok
Цитата(Len_OK @ Feb 15 2008, 12:30) *
Мне просто поставлено задание, записать во флеш!Потому что из еепром слетали данные


Как часто надо обновлять данные?

Анатолий.
KRS
Цитата(Len_OK @ Feb 15 2008, 12:30) *
Мне просто поставлено задание, записать во флеш!Потому что из еепром слетали данные

Обычно это происходит если некорректно написаны функции записи (особенно если используются прерывания). Если контроллеры старые нельзя использховать 0 адрес.
А так что то мне лично не попадались случаи когда еепром слетал.
Когда флеш слетал попадались.
Len_OK
Цитата(bloodden @ Feb 15 2008, 13:35) *
Писать во флеш можно ТОЛЬКО из области бутлоадера.

В том то и дело, что процедуры записи размещаю в бутлоадере.Во флешку данные записываются, но после я не могу ничего больше выполнить, на некоторое время МК подвисает.

Я работаю с ключами, мне нужно их считывать и запоминать.Как часто будут обновляться ключи-этого мне неизвестно.

2 KRS
Значит еепром надёжней чем флешка?


#pragma location = "loader"
void read_fash_to_temp_buf(unsigned char *temp_buf,unsigned char NumPage)
{
unsigned const char __flash *flash_adr;
unsigned char i;
flash_adr=&flash_buf_read[NumPage][0];
for(i=0;i<64;i++)
{
*temp_buf = __load_program_memory(flash_adr);
temp_buf++;
flash_adr++;
}
}


#pragma location = "loader"
void erase_flash_page(unsigned char NumPage)
{
unsigned const char __flash *flash_adr;
flash_adr=&flash_buf_read[NumPage][0];
_ENABLE_RWW_SECTION();
_WAIT_FOR_SPM();
while(EECR&(1<<1));
_PAGE_ERASE(flash_adr);
}

#pragma location = "loader"
void update_flash_page(unsigned char *temp_buf,unsigned char NumPage)

{
unsigned const char __flash *flash_adr;
unsigned char Buf_Adres = 0;
flash_adr=&flash_buf_read[NumPage][0];

do
{ fl_data=*(temp_buf+Buf_Adres+1);
fl_data<<=8;
fl_data|=*(temp_buf+Buf_Adres);
_FILL_TEMP_WORD(Buf_Adres,fl_data);
Buf_Adres+=2;
} while (Buf_Adres<64);


_WAIT_FOR_SPM();
while(EECR&(1<<1));
_PAGE_ERASE(flash_adr);
_WAIT_FOR_SPM();
_PAGE_WRITE(flash_adr);
}


Вот так я работаю с флешкой, может написано что-то криво?Просто это первый мой прект..может чего и не так пишу
GDI
У еепром больше циклов перезаписи 100000 против 10000 у флешь, еепром может "слететь" если производится запись и в этот момент выключается питание, но это решается включеним BOD, и еще, у атмела есть апноут на тему хранения во флеши переменных.
KRS
Цитата(Len_OK @ Feb 15 2008, 12:44) *
2 KRS
Значит еепром надёжней чем флешка?

Да тут много факторов.
У Атмела флешь может слетать если супервизора на ресете нет и начнет глючить питание или помехи путсить по питанию и ресету. Бывало такое.

В еепром циклов записи намного больше.

Цитата(Len_OK @ Feb 15 2008, 12:44) *
В том то и дело, что процедуры записи размещаю в бутлоадере.Во флешку данные записываются, но после я не могу ничего больше выполнить, на некоторое время МК подвисает.

А вы не забвываете потом разрешить RWW секцию
Код
;re-enable the RWW section
ldi spmcsrval, (1<<RWWSRE) | (1<<SPMEN)
call Do_spm


Но у меня в коде бутлоадера стоит вообще в цикле пока не разрешится.
Почему я так делал не помню.
Код
; enable RWW section
Enable:
      ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
      rcall Do_spm
#ifdef SPMCRN
      in r16, SPMCR
#else
      lds r16, SPMCSR
#endif      
      sbrc r16, RWWSB
      rjmp Enable




Цитата(Len_OK @ Feb 15 2008, 12:49) *
#pragma location = "loader"
void erase_flash_page(unsigned char NumPage)
{
unsigned const char __flash *flash_adr;
flash_adr=&flash_buf_read[NumPage][0];
_ENABLE_RWW_SECTION();
_WAIT_FOR_SPM();
while(EECR&(1<<1));
_PAGE_ERASE(flash_adr);
}

#pragma location = "loader"
void update_flash_page(unsigned char *temp_buf,unsigned char NumPage)

{
unsigned const char __flash *flash_adr;
unsigned char Buf_Adres = 0;
flash_adr=&flash_buf_read[NumPage][0];

do
{ fl_data=*(temp_buf+Buf_Adres+1);
fl_data<<=8;
fl_data|=*(temp_buf+Buf_Adres);
_FILL_TEMP_WORD(Buf_Adres,fl_data);
Buf_Adres+=2;
} while (Buf_Adres<64);
_WAIT_FOR_SPM();
while(EECR&(1<<1));
_PAGE_ERASE(flash_adr);
_WAIT_FOR_SPM();
_PAGE_WRITE(flash_adr);
}



У меня _ENABLE_RWW_SECTION();
стоит в цикле только в конце после стирания и записи

Код
PUBLIC PageWrite

PageWrite:
; page erase
      ldi spmcrval, (1<<PGERS) | (1<<SPMEN)
      rcall Do_spm

; fill page buffer
      ldi ......
      ldi ......
Fill:
      ld r0, ..........
              ld r1, ...........
      ldi spmcrval, (1<<SPMEN)
      rcall Do_spm
              ..........
      subi ...., 2
      brne Fill

; write page
              ..........
      ldi spmcrval, (1<<PGWRT) | (1<<SPMEN)
      rcall Do_spm
      
; enable RWW section
Enable:
      ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
      rcall Do_spm
#ifdef SPMCRN
      in r16, SPMCR
#else
      lds r16, SPMCSR
#endif      
      sbrc r16, RWWSB
      rjmp Enable
      
; check porgrammed page
      .................................
      ret
Igor26
А на какое время подвисает? Не забывайте, что для записи блока во FLASH нужно время. Если пишите много блоков подряд, то и время "подвисания" существенно возрастет.
Len_OK
я по времени не проверяла, но прилично, быть может даже на несколько минут, после чего я всё же вычитываю из флешки данные
KRS
Цитата(Len_OK @ Feb 15 2008, 14:00) *
я по времени не проверяла, но прилично, быть может даже на несколько минут, после чего я всё же вычитываю из флешки данные

А исходники
_PAGE_WRITE()
_WAIT_FOR_SPM()
....
Скорее всего у вас после записи страницы нет еще одного вызова _ENABLE_RWW_SECTION()
Igor26
Цитата(Len_OK @ Feb 15 2008, 14:00) *
но прилично, быть может даже на несколько минут

Да многовато.
А как происходит возврат из секции бутлоадера? Т.е. туда ли передается управление по окончании работы подпрограмм в секции бутлоадера?

2KRS
Цитата
_PAGE_WRITE()
_WAIT_FOR_SPM()


#define _WAIT_FOR_SPM() while( SPMCR_REG & (1<<SPMEN) );

#define _PAGE_WRITE(addr) __AddrToZByteToSPMCR_SPM( (void __flash *) (addr), 0x05 )
Это ИАРовские штучки и взяты из апнота AVR109, как я понял.
KRS
Цитата(Igor26 @ Feb 15 2008, 15:28) *
2KRS
#define _WAIT_FOR_SPM() while( SPMCR_REG & (1<<SPMEN) );

#define _PAGE_WRITE(addr) __AddrToZByteToSPMCR_SPM( (void __flash *) (addr), 0x05 )
Это ИАРовские штучки и взяты из апнота AVR109, как я понял.

А ну тогда точно после записи страницы не хватает
_ENABLE_RWW_SECTION();
_WAIT_FOR_SPM();
Igor26
Цитата(KRS @ Feb 15 2008, 16:34) *
А ну тогда точно после записи страницы не хватает
_ENABLE_RWW_SECTION();
_WAIT_FOR_SPM();

Мой фрагмент записи блока выглятит так:
//*******************************
//*Запись блока во Flash-память *
//*******************************
void SaveBlockFlash(unsigned int NumberBlock)
{
__disable_interrupt();
.
.
.
.

#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
_PAGE_WRITE(TempAdress);
#pragma diag_default=Pe1053 // Back to default.
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION();
__enable_interrupt();
}
всё по AVR109! Служит верой и правдой.
Len_OK
огромное спасибо ребята!!!!
Igor26
Цитата(Len_OK @ Feb 18 2008, 14:04) *
огромное спасибо ребята!!!!

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