|
|
  |
Энергонезависимая Память AVR |
|
|
|
Feb 27 2011, 12:38
|

unexpected token
   
Группа: Свой
Сообщений: 899
Регистрация: 31-08-06
Из: Мехелен, Брюссель
Пользователь №: 19 987

|
Цитата(Br.Misha @ Feb 27 2011, 15:27)  4 байта для хранения счетчика записей. После каждой записи я буду увеличивать счетчик на 1 и когда дойдет до 100000, то буду записывать даные и счетчик в следующие 20 байт, получается, циклов записи будет около 2 милионов (для атмега8). Как вам идея? Так наверное будет работать, только зачем для счетчика до 100000 использовать 4 байта, когда достаточно 3-х: 2^24 = 16777216? Ну это так, для экономии памяти  100000 раз применительно к каждому биту, я считаю.
--------------------
А у тебя SQUID, и значит, мы умрем.
|
|
|
|
|
Feb 27 2011, 14:15
|

Местный
  
Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986

|
Делал так: CODE //----------------------------------------------------------------------------
//Eeprom support module
//----------------------------------------------------------------------------
#include <Main.h> #include <Eeprom.h>
//------------------------------ Constants: ----------------------------------
#define RBUFF 100 //EEPROM ring buffer size #define RSIG 0xDA //record header signature
//------------------------------ Variables: ----------------------------------
typedef struct { char Sig; //record header signature bool On; //On flag int Val; //stored value } EVal;
__no_init __eeprom int EData[EE_N]; //EEPROM data array __no_init __eeprom EVal EVals[RBUFF]; //EEPROM ring buffer
static char EePnt = 0; //pointer to currently used record
//-------------------------- Read EEPROM data: -------------------------------
int Eeprom_Read(char a) { return(EData[a]); //read parameter }
//-------------------------- Write EEPROM data: -------------------------------
void Eeprom_Write(char a, int d) { if(EData[a] != d) //if parameter changed { EData[a] = d; //write parameter __watchdog_reset(); //watchdog reset } }
//-------------------------- Read V from EEPROM: -----------------------------
int Eeprom_ReadV(bool *on) { EePnt = RBUFF; //set incorrect pointer value for(char i = 0; i < RBUFF; i++) //search signature in ring buffer if(EVals[i].Sig == RSIG) //if signature found { EePnt = i; //initialize pointer break; } if(EePnt == RBUFF) //if pointer incorrect (signature not found) { EePnt = 0; //set pointer to first array record *on = 0; //supply off return(0); //return V = 0 } *on = EVals[EePnt].On; //read on flag return(EVals[EePnt].Val); //read V }
//--------------------------- Write V to EEPROM: -----------------------------
void Eeprom_WriteV(int v, bool on) { char NewPnt = EePnt; //save previous pointer value if(NewPnt++ == RBUFF) //advance pointer NewPnt = 0; //roll-up pointer EVals[NewPnt].On = on; //save on flag EVals[NewPnt].Val = v; //save V EVals[NewPnt].Sig = RSIG; //save signature at new location EVals[EePnt].Sig = 0xFF; //clear signature at old location __watchdog_reset(); //watchdog reset EePnt = NewPnt; //save new pointer value }
//----------------------------------------------------------------------------
Сообщение отредактировал IgorKossak - Feb 27 2011, 15:21
Причина редактирования: Бездумное оформление кода
--------------------
|
|
|
|
|
Mar 1 2011, 14:29
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(GDI @ Mar 1 2011, 17:10)  Только надо еще как то узнать о том что произошел отказ... Узнавать-то вроде и не надо. Номер последней записи обновляется _после_ записи данных. Всё само-собой получается. Производитель гарантирует 100тыс циклов записи, так что наворачивать еще что-либо сверх рекомендованного в аппноте ИМХО не резонно.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 1 2011, 15:01
|

Гуру
     
Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106

|
Цитата(defunct @ Mar 1 2011, 16:54)  Лучше не ждать когда накрутит 100000, а просто каждую запись писать в следующие n-байт. 100% Цитата(defunct @ Mar 1 2011, 16:54)  Счетчик в этом случаем может быть 1 байтным и хранить только sequence (порядковый номер) записи. Не согласен! Если просто хранить номер записи то младший бит будет меняться с каждым увеличением. Думаю что в качестве указателя желательно применить : a: "бегущий" бит ноль(единица) в байте (увеличение ресурса в 8 раз); б: "бегущий" байт 00H(FFH) в массиве X[n] (увеличение ресурса в n раз).
|
|
|
|
|
Mar 1 2011, 15:30
|
Частый гость
 
Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701

|
Цитата(defunct @ Mar 1 2011, 15:54)  сделать массив из 20-ти записей по 16 байт, писать вначале 0-ю запись, потом 1-ю ..... 19-ю, опять 0-ю и так покругу. Счетчик в этом случаем может быть 1 байтным и хранить только sequence (порядковый номер) записи. И по возможности не располагать его с 0 адреса в еепром. Вроде даже где-то в апликухах об этом говорилось: в AVR при неблагоприятном стечении обстоятельств значение в нулевой ячейке может быть утеряно.
|
|
|
|
|
Mar 2 2011, 07:34
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 25-01-06
Из: Самара
Пользователь №: 13 578

|
Цитата(ukpyr @ Mar 1 2011, 21:53)  старая байка, уже давно не актуальная Для рабочего режима - может быть. Однако при отладке с помощью JTAGICE II довольно часто портится именно 0 ячейка EEPROM. С чем это связано - неизвестно. Возможно, с процессом заливки новой программы? Естественно, программирование EEPROM при этом запрещено. Портится именно 0 ячейка, далее - все в порядке...
|
|
|
|
|
Mar 2 2011, 10:03
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(ukpyr @ Mar 1 2011, 20:53)  старая байка, уже давно не актуальная тем не менее IAR при стандартных настройках 0-ую ячейку ЕЕПРОМ не пользует.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|