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

Энергонезависимая Память AVR

Гость Br.Misha

Привет!

В ДШ на атмегу написано, что еепром можно перезаписывать 100000 раз. Это касается каждой ячейки отдельно или нет?

Почему спрашиваю? Просто хочу сделать девайс, который будет работать много лет и много раз будет перезаписана. У атмеги8 512 байт, всего мне нужно около 15 байт. Принцип такой: 16 байт используются для хранения даных и 4 байта для хранения счетчика записей. После каждой записи я буду увеличивать счетчик на 1 и когда дойдет до 100000, то буду записывать даные и счетчик в следующие 20 байт, получается, циклов записи будет около 2 милионов (для атмега8). Как вам идея?

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


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

4 байта для хранения счетчика записей. После каждой записи я буду увеличивать счетчик на 1 и когда дойдет до 100000, то буду записывать даные и счетчик в следующие 20 байт, получается, циклов записи будет около 2 милионов (для атмега8). Как вам идея?

 

Так наверное будет работать, только зачем для счетчика до 100000 использовать 4 байта, когда достаточно 3-х: 2^24 = 16777216? Ну это так, для экономии памяти :)

100000 раз применительно к каждому биту, я считаю.

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


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

Делал так:

 

//----------------------------------------------------------------------------

//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
Бездумное оформление кода

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


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

Как вам идея?

Лучше не ждать когда накрутит 100000, а просто каждую запись писать в следующие n-байт. Напр сделать массив из 20-ти записей по 16 байт, писать вначале 0-ю запись, потом 1-ю ..... 19-ю, опять 0-ю и так покругу. Счетчик в этом случаем может быть 1 байтным и хранить только sequence (порядковый номер) записи. Т.о. вы не только увеличите ресурс в 20 раз но и добъетесь отказоустойчивости, т.к. при отказе любой из записей вы может прочитать предыдущую.

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


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

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

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


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

Только надо еще как то узнать о том что произошел отказ...
Узнавать-то вроде и не надо. Номер последней записи обновляется _после_ записи данных.

Всё само-собой получается.

Производитель гарантирует 100тыс циклов записи, так что наворачивать еще что-либо сверх рекомендованного в аппноте ИМХО не резонно.

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


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

Лучше не ждать когда накрутит 100000, а просто каждую запись писать в следующие n-байт.

100%

Счетчик в этом случаем может быть 1 байтным и хранить только sequence (порядковый номер) записи.

Не согласен! Если просто хранить номер записи то младший бит будет меняться с каждым увеличением.

 

Думаю что в качестве указателя желательно применить :

a: "бегущий" бит ноль(единица) в байте (увеличение ресурса в 8 раз);

б: "бегущий" байт 00H(FFH) в массиве X[n] (увеличение ресурса в n раз).

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


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

сделать массив из 20-ти записей по 16 байт, писать вначале 0-ю запись, потом 1-ю ..... 19-ю, опять 0-ю и так покругу. Счетчик в этом случаем может быть 1 байтным и хранить только sequence (порядковый номер) записи.

И по возможности не располагать его с 0 адреса в еепром. Вроде даже где-то в апликухах об этом говорилось: в AVR при неблагоприятном стечении обстоятельств значение в нулевой ячейке может быть утеряно.

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


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

И по возможности не располагать его с 0 адреса в еепром. Вроде даже где-то в апликухах об этом говорилось: в AVR при неблагоприятном стечении обстоятельств значение в нулевой ячейке может быть утеряно.

Ни фигасе! Вот бы найти документальное подтверждение этому.

 

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


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

Ни фигасе! Вот бы найти документальное подтверждение этому.

Если найдешь Errata на старые AVR (к примеру At90S2313), то там такое было. Если reset проходил во время записи EEPROM, то адрес записи слетал в 0 и портилась нулевая ячейка.

 

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


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

И по возможности не располагать его с 0 адреса в еепром.
старая байка, уже давно не актуальная

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


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

старая байка, уже давно не актуальная

Для рабочего режима - может быть. Однако при отладке с помощью JTAGICE II довольно часто портится именно 0 ячейка EEPROM. С чем это связано - неизвестно. Возможно, с процессом заливки новой программы? Естественно, программирование EEPROM при этом запрещено. Портится именно 0 ячейка, далее - все в порядке...

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


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

старая байка, уже давно не актуальная

тем не менее IAR при стандартных настройках 0-ую ячейку ЕЕПРОМ не пользует.

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


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

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

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

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

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

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

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

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

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

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