реклама на сайте
подробности

 
 
> Энергонезависимая Память AVR
Br.Misha
сообщение Feb 27 2011, 12:27
Сообщение #1


Местный
***

Группа: Validating
Сообщений: 253
Регистрация: 21-12-08
Пользователь №: 42 646



Привет!
В ДШ на атмегу написано, что еепром можно перезаписывать 100000 раз. Это касается каждой ячейки отдельно или нет?
Почему спрашиваю? Просто хочу сделать девайс, который будет работать много лет и много раз будет перезаписана. У атмеги8 512 байт, всего мне нужно около 15 байт. Принцип такой: 16 байт используются для хранения даных и 4 байта для хранения счетчика записей. После каждой записи я буду увеличивать счетчик на 1 и когда дойдет до 100000, то буду записывать даные и счетчик в следующие 20 байт, получается, циклов записи будет около 2 милионов (для атмега8). Как вам идея?
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 45)
alexunder
сообщение Feb 27 2011, 12:38
Сообщение #2


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? Ну это так, для экономии памяти sm.gif
100000 раз применительно к каждому биту, я считаю.


--------------------
А у тебя SQUID, и значит, мы умрем.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Feb 27 2011, 12:53
Сообщение #3


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



[PDF] AVR101: High Endurance EEPROM Storage
Go to the top of the page
 
+Quote Post
Леонид Иванович
сообщение Feb 27 2011, 14:15
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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
Причина редактирования: Бездумное оформление кода


--------------------
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 1 2011, 12:54
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Br.Misha @ Feb 27 2011, 14:27) *
Как вам идея?

Лучше не ждать когда накрутит 100000, а просто каждую запись писать в следующие n-байт. Напр сделать массив из 20-ти записей по 16 байт, писать вначале 0-ю запись, потом 1-ю ..... 19-ю, опять 0-ю и так покругу. Счетчик в этом случаем может быть 1 байтным и хранить только sequence (порядковый номер) записи. Т.о. вы не только увеличите ресурс в 20 раз но и добъетесь отказоустойчивости, т.к. при отказе любой из записей вы может прочитать предыдущую.
Go to the top of the page
 
+Quote Post
GDI
сообщение Mar 1 2011, 14:10
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



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


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 1 2011, 14:29
Сообщение #7


неотягощённый злом
******

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



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


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 1 2011, 15:01
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 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 раз).
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Mar 1 2011, 15:21
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



Цитата
4 байта для хранения счетчика записей
хватит и 2х
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 1 2011, 15:30
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



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

И по возможности не располагать его с 0 адреса в еепром. Вроде даже где-то в апликухах об этом говорилось: в AVR при неблагоприятном стечении обстоятельств значение в нулевой ячейке может быть утеряно.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 1 2011, 15:34
Сообщение #11


Гуру
******

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



Цитата(Dimoza @ Mar 1 2011, 19:30) *
И по возможности не располагать его с 0 адреса в еепром. Вроде даже где-то в апликухах об этом говорилось: в AVR при неблагоприятном стечении обстоятельств значение в нулевой ячейке может быть утеряно.

Ни фигасе! Вот бы найти документальное подтверждение этому.
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Mar 1 2011, 17:12
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



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

Если найдешь Errata на старые AVR (к примеру At90S2313), то там такое было. Если reset проходил во время записи EEPROM, то адрес записи слетал в 0 и портилась нулевая ячейка.
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Mar 1 2011, 17:53
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



Цитата
И по возможности не располагать его с 0 адреса в еепром.
старая байка, уже давно не актуальная
Go to the top of the page
 
+Quote Post
sgs
сообщение Mar 2 2011, 07:34
Сообщение #14


Участник
*

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



Цитата(ukpyr @ Mar 1 2011, 21:53) *
старая байка, уже давно не актуальная

Для рабочего режима - может быть. Однако при отладке с помощью JTAGICE II довольно часто портится именно 0 ячейка EEPROM. С чем это связано - неизвестно. Возможно, с процессом заливки новой программы? Естественно, программирование EEPROM при этом запрещено. Портится именно 0 ячейка, далее - все в порядке...
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Mar 2 2011, 10:03
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(ukpyr @ Mar 1 2011, 20:53) *
старая байка, уже давно не актуальная

тем не менее IAR при стандартных настройках 0-ую ячейку ЕЕПРОМ не пользует.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 2 2011, 12:06
Сообщение #16


неотягощённый злом
******

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



image-craft тоже не использует по-инерции
avr-gcc использует и лично я не испытываю в связи с этим никаких затруднений.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Petka
сообщение Mar 2 2011, 17:44
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(demiurg_spb @ Mar 2 2011, 15:06) *
....
avr-gcc использует и лично я не испытываю в связи с этим никаких затруднений.

avr-gcc вообще не распределяет eeprom память. Как понимать "avr-gcc использует"?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 3 2011, 10:06
Сообщение #18


неотягощённый злом
******

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



Цитата(Petka @ Mar 2 2011, 20:44) *
avr-gcc вообще не распределяет eeprom память. Как понимать "avr-gcc использует"?

Хорошо. Под avr-gcc я имел ввиду весь тулчейн, точно так же как и CV, ICC и IAR.

Линкер помещает в отдельную секцию данные с атрибутом EEMEM,
а потом утилита objcopy выкусывает её в отдельный файл - образ прошивки eeprom памяти.
И в результате, по умолчанию, данные в eeprom располагаются начиная с нулевого адреса.

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

Поправьте или дополните меня если считаете нужным.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 3 2011, 16:20
Сообщение #19


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zombi @ Mar 1 2011, 17:01) *
Если просто хранить номер записи то младший бит будет меняться с каждым увеличением.

Во-первых вы немного ошибаетесь - можно подобрать количество записей так, что изменения в младшем бите будут очень редкими.
Например, если записи всего две, то младший бит в sequence ячейках практически никогда меняться не будет, т.к. в 0-ю запись попадут все четные sequence, в 1-ю - все нечетные.

Во-вторых - даже если младший бит будет меняться постоянно, ну и что? Мы же пишем всегда в новые n-байт, т.е. ячеек с sequence'ом будет столько же сколько и записей, наработка на отказ - все те же n * 100000, где n - размерность массива записей.

Ниже пример реализации алгоритма, правда здесь в качестве хранилища используется флеш (проц SAM7):

Код
void js_LoadConfig(void)
{
    U8 *p = (U8 *)(CONFIG_START_FLASH_ADDRESS);
    U8 last_seq = *p;
    U8 *pLastConfig = p;
    U8 buf[sizeof(jsContext.Cfg)];
    PJS_CONFIG pCfg = (PJS_CONFIG)buf;
    int i;

    for (i = 0; i < CONFIG_MIRROR_PAGE_COUNT; i++)
    {
        p += FLASH_PAGE_SIZE_BYTES;
        if (((U8)(last_seq + 1)) == *p)
        {
            last_seq = *p;
            pLastConfig = p;
        }
        else
        {
            p = pLastConfig;
            break;
        }
    }
    // at this point p - points to the address with the most fresh config record
    memcpy( buf, p, sizeof(buf));
    jsContext.LastLocation = (U32)p;
    jsContext.Cfg.Sequence = *p;

    // check CRC of the record
    if ( CRC16( buf, sizeof(buf) != 0 )
    {
        printf("CRC error exp=%2x, cur=%2x, flash_addr=%x, seq=%d\n", hCRC, pCfg->CRC, (U32)p, *p);
        printf("The configuration has NOT been applied!\n" );
        printf("or there is no previously saved configuration.\n");
        // store defaults
        js_StoreConfig();
    }
    else
    {
        // CRC is ok, applying new settings
        memcpy( &jsContext.Cfg, pCfg, sizeof(jsContext.Cfg));
        printf("Configuration applied, seq_%x\n", *p);
    }
}


void js_StoreConfig(void)
{
    jsContext.Cfg.Sequence += 1;
    jsContext.LastLocation += FLASH_PAGE_SIZE_BYTES;
    if (jsContext.LastLocation > CONFIG_LAST_FLASH_CELL_ADDRESS)
        jsContext.LastLocation = CONFIG_START_FLASH_ADDRESS;

    jsContext.Cfg.CRC = CRC16( (U8 *)&jsContext.Cfg, sizeof(jsContext.Cfg) - 2);
    iap_PageWrite( jsContext.LastLocation, (U32 *)&jsContext.Cfg, sizeof(jsContext.Cfg) );

    printf("configuration stored, L(%x), Sq(%x), (%d)bytes\n", jsContext.LastLocation, jsContext.Cfg.Sequence, sizeof(jsContext.Cfg));
}


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

2 moderator: просьба тэг [ code ] на [ codebox ] не менять, пасиба.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 3 2011, 16:43
Сообщение #20


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



А всё-таки, EEPROM в AVR страничной организации, или же нет?
В документации, правда, в разделе записи в EEPROM с программатора, указан страничный обмен: к примеру, страница - 8 байт, и минимально адресуемый элемент - 1 байт.
Ежели оно минимально адресуемо байтом, то какой смысл считать в них биты, ибо стирание\запись всё равно для всех восьми? А если из МК при записи в EEPROM одного байта переписывается вся страница, про принципу read-modify-write, то всё и того хуже...
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 3 2011, 16:47
Сообщение #21


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(SysRq @ Mar 3 2011, 18:43) *
А всё-таки, EEPROM в AVR страничной организации, или же нет?

Всегда был байтовой насколько помню. - можно стирать/записать произвольный байт.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 3 2011, 16:58
Сообщение #22


Гуру
******

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



To defunct.
Я не могу понять что такое это sequence, где оное хранится и какова его размерность?
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 3 2011, 17:00
Сообщение #23


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(defunct @ Mar 3 2011, 19:47) *
Всегда был байтовой насколько помню. - можно стирать/записать произвольный байт.
Тогда нет смысла мудрить с отдельными битами, ибо для всего байта erase\write выполняется. Нет write-only команды.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 3 2011, 17:13
Сообщение #24


Гуру
******

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



Цитата(SysRq @ Mar 3 2011, 20:00) *
Тогда нет смысла мудрить с отдельными битами, ибо для всего байта erase\write выполняется. Нет write-only команды.

Осталось только выяснить : приводит ли к исчепанию ресурса стирание(запись значения FFH) в ячейку которая и до того была FFH
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Mar 3 2011, 22:06
Сообщение #25


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



Цитата
Осталось только выяснить : приводит ли к исчепанию ресурса стирание(запись значения FFH) в ячейку которая и до того была FFH
Полезно перед записью каждого байта проверять на равенство записанному. Уменьшается износ и часто сильно ускоряется обновление параметров. В одном проекте не хватало заряда конденсатора для сохранения в EEPROM после пропадания питания (больше 0.5сек), добавил проверку - успевало записать за десятки миллисекунд.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 3 2011, 22:21
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zombi @ Mar 3 2011, 19:58) *
Я не могу понять что такое это sequence, где оное хранится и какова его размерность?

Хранится в каждой записи. Размерность должна быть такой, чтобы максимальное значение sequence было больше числа возможных записей, тогда всегда можно достоверно определить наиболее свежую.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 4 2011, 11:00
Сообщение #27


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (aaarrr @ Mar 4 2011, 00:21) *
Размерность должна быть такой, чтобы максимальное значение sequence было больше числа возможных записей, тогда всегда можно достоверно определить наиболее свежую.
Может быть и небольшой размерности, но период записываемых в него значений должен быть некратен количеству копий записей. Тогда по сбою последовательности легко находится место налезания головы буфера на хвост.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 4 2011, 15:02
Сообщение #28


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zombi @ Mar 3 2011, 18:58) *
что такое это sequence, где оное хранится и какова его размерность?

Sequence это первый байт структуры Cfg (она вся пишется во флеш, последние ее два байта - CRC16).
Структура Cfg - пишется покругу во флеш, при каждой записи sequence увеличивается на 1. При старте девайса - последовательно вычитываются записи начиная с нулевой, там где обнаруживается разница
Код
sn[i+1] - sn[ i ] != 1
(т.е. следующий Sequence отличается от текущего не на единицу), и будет i - номер искомой самой свежей записи.

Цитата(SysRq @ Mar 3 2011, 19:00) *
Тогда нет смысла мудрить с отдельными битами, ибо для всего байта erase\write выполняется. Нет write-only команды.

Я и не предлагал laughing.gif
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2011, 11:34
Сообщение #29


Гуру
******

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



Цитата(aaarrr @ Mar 4 2011, 01:21) *
Хранится в каждой записи. Размерность должна быть такой, чтобы максимальное значение sequence было больше числа возможных записей, тогда всегда можно достоверно определить наиболее свежую.

Цитата(defunct @ Mar 4 2011, 18:02) *
Sequence это первый байт структуры Cfg (она вся пишется во флеш, последние ее два байта - CRC16).

Спасибо! Разобрался. Действительно очень красиво все получается.
beer.gif

Цитата(ukpyr @ Mar 4 2011, 01:06) *
Цитата(zombi @ Mar 3 2011, 20:13) *

Осталось только выяснить : приводит ли к исчепанию ресурса стирание(запись значения FFH) в ячейку которая и до того была FFH

Полезно перед записью каждого байта проверять на равенство записанному. Уменьшается износ и часто сильно ускоряется обновление параметров. В одном проекте не хватало заряда конденсатора для сохранения в EEPROM после пропадания питания (больше 0.5сек), добавил проверку - успевало записать за десятки миллисекунд.

Т.е. получается что время на запись "тогоже самого" тратится по любому, а вот приводит ли это к износу еепром?
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 5 2011, 12:29
Сообщение #30


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(zombi @ Mar 5 2011, 14:34) *
Т.е. получается что время на запись "тогоже самого" тратится по любому, а вот приводит ли это к износу еепром?
Убивается, ждём-с. Сейчас 1'248'000 циклов выполнено, пока жива...

(Хм, в программке вроде бы не наврал нигде.. в один и тот же адрес пишу 0xFF в количестве 992 штук, затем 8 значений с единичкой в разных разрядах, и в обоих случаях читаю и проверяю совпало ли, и циклы считаю.)

Код (ATMega128; здесь USB - мост на UART), на проверку, может ошибка где?
CODE
#include <stdio.h>

static char str[100];

#define EEPROM_ADDRESS_TO_DESTROY 4094U

uint32_t cycles_;
uint16_t cycles_1000_;

void show_cycles(uint8_t is_failed)
{
if(is_failed)
{
sprintf(str, "\r\nFAILED ON: %ld", cycles_);
}
else
{
sprintf(str, "\r\nCURRENT: %ld", cycles_);
}

for(uint8_t i = 0; i < 100; i++)
{
if(str[i]) USB_TransmitByte(str[i]);
else break;
}
}

void eeprom_write_no_check(uint16_t address, uint8_t data)
{
while(EECR & _BV(EEWE));

EEAR = address;

EEDR = data;

ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
EECR |= _BV(EEMWE);
EECR |= _BV(EEWE);
}
}

uint8_t eeprom_read_no_check(uint16_t address)
{
while(EECR & _BV(EEWE));

EEAR = address;

EECR |= _BV(EERE);

return EEDR;
}


__attribute__((OS_main)) int main(void)
{
USB_Initialize();

sei();

for(;;)
{
eeprom_write_no_check(EEPROM_ADDRESS_TO_DESTROY, 0xFF);

++cycles_;
++cycles_1000_;

if(eeprom_read_no_check(EEPROM_ADDRESS_TO_DESTROY) != 0xFF)
{
show_cycles(TRUE);

for(;;);
}

if(cycles_1000_ == 1000)
{
cycles_1000_ = 0;

show_cycles(FALSE);

for(uint8_t data = 1; data; data <<= 1)
{
eeprom_write_no_check(EEPROM_ADDRESS_TO_DESTROY, data);

++cycles_;
++cycles_1000_;

if(eeprom_read_no_check(EEPROM_ADDRESS_TO_DESTROY) != data)
{
show_cycles(TRUE);

for(;;);
}
}
}

if(USB_IsDataReceived())
{
if(USB_ReceiveByte() == '?')
{
show_cycles(FALSE);
}
}
}

return 0;
}

Если в коде ошибок нет, то поставлю писать что-нить отличное от 0xFF, проверим далее...

Сообщение отредактировал SysRq - Mar 5 2011, 15:03
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2011, 13:00
Сообщение #31


Гуру
******

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



Цитата(SysRq @ Mar 5 2011, 15:29) *
Убивается, ждём-с. Сейчас 305 тысяч циклов выполнено, пока жива...

(Хм, в программке вроде бы не наврал нигде.. в один и тот же адрес пишу 0xFF в количестве 992 штук, затем 8 значений с единичкой в разных разрядах, и в обоих случаях читаю и проверяю совпало ли, и циклы считаю.)

Ого, 305.000 ! Оч. интересно! Ждемс!
Но мне кажется что для проверки работоспособности надо бы через некоторое количество циклов (к примеру 10.000 ~ 100.000) попробывать записать инверсные данные
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 5 2011, 13:54
Сообщение #32


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(zombi @ Mar 5 2011, 16:00) *
Но мне кажется что для проверки работоспособности надо бы через некоторое количество циклов (к примеру 10.000 ~ 100.000) попробывать записать инверсные данные
Примерно так и делаю, посмотрите код выше.
Если одинаковые значения не пишутся, то сейчас всего тысяч 6 циклов... 05.gif
Go to the top of the page
 
+Quote Post
314
сообщение Mar 5 2011, 14:55
Сообщение #33


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 17-08-07
Пользователь №: 29 855



Почему-то всегда казалось, что тип флеш, использованный в АВР, убивается только записью нулей... laughing.gif
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 5 2011, 16:23
Сообщение #34


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Выключил на 1'800'000. Изменил в исходнике 0xFF на 0x00, адрес на 1 вниз, перешил, запустил. Ждём, убьётся ли записью нулей...
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2011, 20:23
Сообщение #35


Гуру
******

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



Цитата(SysRq @ Mar 5 2011, 16:54) *
Примерно так и делаю, посмотрите код выше.
Если одинаковые значения не пишутся, то сейчас всего тысяч 6 циклов... 05.gif

Ага, вроде правильно все.

Цитата(SysRq @ Mar 5 2011, 19:23) *
Выключил на 1'800'000. Изменил в исходнике 0xFF на 0x00, адрес на 1 вниз, перешил, запустил. Ждём, убьётся ли записью нулей...

Наверное можно предположить что ограничение 100.000 циклов это максимальное количество изменеий каждого БИТА еепром.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 5 2011, 20:34
Сообщение #36


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(zombi @ Mar 5 2011, 23:23) *
Наверное можно предположить что ограничение 100.000 циклов это максимальное количество изменеий каждого БИТА еепром.
Запись 0x00 я остановил на ~800 тысячах, не дождался. Запись чередования 0xFF\0x00 остановил на 401 тысяче, ибо уже не верил что оно пишет в EEPROM вообще.
Сейчас посмотрел - таки, пишет! Запустил заново, добавив ещё запись 0x55 в EEDR _перед_ чтением...
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2011, 22:47
Сообщение #37


Гуру
******

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



Цитата(SysRq @ Mar 5 2011, 23:34) *
Запись 0x00 я остановил на ~800 тысячах, не дождался. Запись чередования 0xFF\0x00 остановил на 401 тысяче, ибо уже не верил что оно пишет в EEPROM вообще.
Сейчас посмотрел - таки, пишет! Запустил заново, добавив ещё запись 0x55 в EEDR _перед_ чтением...

400.000 это уже слишком! А проц какой?
В понедельник тоже буду попробывать на 162-й атмеге.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 6 2011, 06:24
Сообщение #38


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Результат записи 0x00 (по приведённому выше алгоритму): убилось на 3'238'008 цикле laughing.gif
CODE
// ...
CURRENT: 3236000
CURRENT: 3237000
CURRENT: 3238000
FAILED ON: 3238008

// Перезапуск по питанию

CURRENT: 1000
FAILED ON: 1008

// Перезапуск по питанию

CURRENT: 1000
CURRENT: 2000
CURRENT: 3000
CURRENT: 4000
CURRENT: 5000
WRITTEN: 36 // Проверка записи всё в тот же адрес
READ: 36 // Результат чтения
WRITTEN: 34
READ: 34
WRITTEN: 30
READ: 30
CURRENT: 6000
CURRENT: 7000
CURRENT: 8000
CURRENT: 9000
FAILED ON: 9008
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 6 2011, 08:14
Сообщение #39


Гуру
******

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



Цитата(SysRq @ Mar 6 2011, 09:24) *
Результат записи 0x00 (по приведённому выше алгоритму): убилось на 3'238'008 цикле laughing.gif

Т.е. получается что на износ влияет любой процесс записи?
И абсолютно без разницы что было в ячейке до него.
Но 3'238'008 циклов! Этож какой запас прочности!!! В 32 раза!

P.S. а убития записью 0хFF возможно просто не дождались.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 6 2011, 15:02
Сообщение #40


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Результат записи постоянно меняющегося значения: убилось на 3'327'762 цикле.
CODE
// ...
CURRENT: 3326000
CURRENT: 3327000
FAILED ON: 3327762

// перезапуск

// ...
CURRENT: 99000
CURRENT: 100000
FAILED ON: 100889

// перезапуск

// ...
CURRENT: 101000
CURRENT: 102000
FAILED ON: 102918


--

Собстно, выводы:
а) страничной организации нет, ибо я убивал соседние адреса в рамках возможной страницы;
б) убивается, похоже, именно записью нуля: см. поведение после перезапуска в логах.

PS: ATMega128-16AU @ 14.7456 @ комнатная температура.

Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 6 2011, 15:48
Сообщение #41


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zombi @ Mar 6 2011, 11:14) *
Но 3'238'008 циклов! Этож какой запас прочности!!! В 32 раза!

Не забывайте, что эксперимент проведен в тепличных условиях. 100K гарантируется для любых.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 14 2011, 09:41
Сообщение #42


Гуру
******

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



Провел эксперимент с ATmega162-16AU @ 5V @ 16MHz @ t комнатная.
Чередующиеся записи 0х55 - 0xAA по постоянному адресу.
Убилось после выполнения 3.146.000 записей.
Работоспособность ячейки проверялась (после каждых 2.000 записей 0х55 / 0хAA) записью бегущего нуля и единицы.
Перезапуск с соседним адресом - результат примерно тотже (>3.000.000).
В обоих случаях ячейки убились полностью (один из разрядов постоянно в нуле).
Go to the top of the page
 
+Quote Post
Juk1976
сообщение Mar 16 2011, 21:59
Сообщение #43


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 1-08-05
Из: Украина Винница
Пользователь №: 7 258



Народ!!!
Да не мучайте себя.
Используйте FRAMку и будет вам счастье.
Вот делов-то.

Сообщение отредактировал Juk1976 - Mar 16 2011, 22:08
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 16 2011, 22:34
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Juk1976 @ Mar 17 2011, 00:59) *
Используйте FRAMку и будет вам счастье.
Вот делов-то.

Ну а если бюджет не позволяет?
Go to the top of the page
 
+Quote Post
314
сообщение Mar 17 2011, 06:33
Сообщение #45


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 17-08-07
Пользователь №: 29 855



At24cXX - I2C- dip8 - 0.2-0.3$ более 1е6 записи/стирания
Go to the top of the page
 
+Quote Post
nand7
сообщение Mar 17 2011, 07:56
Сообщение #46





Группа: Новичок
Сообщений: 7
Регистрация: 25-04-06
Пользователь №: 16 452



Попробуйте провести эксперимент на температуре 125 или 100С, например. Дойдет ли хотя бы до 200тыс?
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 02:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01843 секунд с 7
ELECTRONIX ©2004-2016