Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Re: Arduino и энергонезависимая память

Чт сен 03, 2020 22:42:06

jcxz писал(а):Просто писать последовательно в сектор и всё. И все его байты будут изнашиваться равномерно.

После N записей все сектора будут записаны.

1111111 1111111 1111111 1111111
1111111 1111111 1111111 1111111
1111111 1111111 1111111 1111111
1111111 1111111 1111111 1111111


Как AVR узнает какой сектор записан последним (сектор со свежими данными) не зная номера сектора ?

jcxz писал(а):Но можно и вашим методом, только номер сектора указывать номером самого старшего 0-го бита. Т.е. шаги:
1. шапка == FFFFFFFF
2. шапка == FFFFFFFE
3. шапка == FFFFFFFC
4. шапка == FFFFFFF8
5. шапка == FFFFFFF0

Номером самого младшего 0-го бита... или номером самого старшего 7-го бита... не принципиально))
"шапка" всё рано будет изнашиваться.
Надо сделать по другому. :roll:

А может просто к данным добавить порядковый номер данных ? Тогда AVR узнает какой сектор записан последним (сектор со свежими данными) по самому старшему номеру пакета данных.
:roll:

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 02:36:59

Как AVR узнает какой сектор записан последним (сектор со свежими данными) не зная номера сектора ?
Всегда должен быть как минимум один стёртый сектор перед головой записи. По нему и узнаем. Я уже выше описывал свой алгоритм. См: https://radiokot.ru/forum/viewtopic.php ... 5#p3887015

"шапка" всё рано будет изнашиваться.
Ну и что? Она будет изнашиваться с той же скоростью, что и область данных.

А может просто к данным добавить порядковый номер данных ? Тогда AVR узнает какой сектор записан последним (сектор со свежими данными) по самому старшему номеру пакета данных.
Все эти номера пакетов и пр. - очень неустойчивы к внезапным сбоям питания, перезагрузкам и пр. А также требуют предварительного стирания всей области кольца перед первым использованием.
Мой алгоритм: 1) свободен от этих недостатков; 2) кодонезависим; 3) обеспечивает равномерный износ; 4) позволяет писать в кольцо пакеты разного размера и формата; 5) позволяет автоматически инициализировать область кольца с изначально произвольным содержимым (предварительное стирание не требуется). :)

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 07:09:00

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

Всё это решается одно только контрольной суммой, которая пишется последней.

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 11:55:08

Всё это решается одно только контрольной суммой, которая пишется последней.
Если нужно в кольцо писать пакеты разного размера, то одной КС тут ничего не решить. Например - писали структуру с настройками прибора одного размера, а потом оказалось, что в новой версии ПО её нужно увеличить. :dont_know:

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 12:00:33

При таких изменениях можно предусмотреть разовую "конвертацию" при смене прошивки. Размер структуры всё еще по сути фиксирован. Вот с динамическим размером данных чуть сложнее будет. И вот тут именно решать надо уже пакетом с заголовком - где размер будет и порядковый номер + КС записаны.

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 13:44:44

Мне надо писать в AVR пакеты фиксированной длины (длина пакета равна размеру сектора EEPROM).
Внезапные сбои питания меня не пугают. У меня автоматическая верификация (после каждой записи) и CRC-16.
jcxz писал(а):Ну и что? Она будет изнашиваться с той же скоростью, что и область данных.

Нет не будет.
Данные равномерно записываются по всем секторам в разные ячейки... а пашка переписывается каждый раз в одни и те же ячейки. Поэтому первая сдохнит шапка.
jcxz писал(а):Всегда должен быть как минимум один стёртый сектор перед головой записи. По нему и узнаем. Я уже выше описывал свой алгоритм. См: https://radiokot.ru/forum/viewtopic.php ... 5#p3887015

Ничего не понял... Чем Ваш "червяк" отличается от моего "червяка" ?

Вот мой "червяк" (писал выше):

1. Разбиваем EEPROM на сектора:

FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

2. Записываем данные 1111111 в нулевой сектор:

1111111 FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

3. Записываем новые данные 1111111 в новый сектор, а старый сектор стираем FFFFFFFF:

FFFFFFFF 1111111 FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

4. Записываем новые данные 1111111 в новый сектор, а старый сектор стираем FFFFFFFF:

FFFFFFFF FFFFFFFF 1111111 FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

5. Записываем новые данные 1111111 в новый сектор, а старый сектор стираем FFFFFFFF:

FFFFFFFF FFFFFFFF FFFFFFFF 1111111
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

6. И т.д. ))

Один недостаток - за оцин цикл каждый сектор по два раза записываем (точнее сначала записываем данные 111111 потом стираем данные FFFFFFF). В данном случае Чтение и Стирание - это одно и то же.
При этом износ EEPROM в два раза больше...

Или в AVR есть "секретная кнопка", о которой я не знаю, которая позволяет стирать EEPROM (FFFFFF....) так чтобы ячейки не изнашивались ?

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 15:30:37

При таких изменениях можно предусмотреть разовую "конвертацию" при смене прошивки.
Это не всегда возможно и небезопасно.

Размер структуры всё еще по сути фиксирован. Вот с динамическим размером данных чуть сложнее будет. И вот тут именно решать надо уже пакетом с заголовком - где размер будет и порядковый номер + КС записаны.
В моём алгоритме хранения всё уже решено: писать можно пакеты произвольной длины, в произвольном порядке. :)

Добавлено after 3 minutes 4 seconds:
jcxz писал(а):Ну и что? Она будет изнашиваться с той же скоростью, что и область данных.

Нет не будет.
Данные равномерно записываются по всем секторам в разные ячейки... а пашка переписывается каждый раз в одни и те же ячейки.
Похоже вы не поняли того, что я предлагал для оптимизации вашего алгоритма... :dont_know:
А предлагал я на каждую одну запись данных делать одну запись одного бита в "шапке". И износ будет одинаков.

Добавлено after 7 minutes 44 seconds:
Чем Ваш "червяк" отличается от моего "червяка" ?
Тем что у меня нет фиксированного размера записываемого кадра, прибитого гвоздями. У меня можно записать сначала например пакет размером 5 байт, а потом в то же кольцо записать кадр размером 1000 байт.
Да и мой алгоритм легко ложится не только на EEPROM с байтовым доступом, но и на чипы FLASH с размером секторов стирания ==256КБ и страниц записи==512байт. И он устойчив к сбоям питания.
Подумайте - что будет с вашим алгоритмом, если блок данных вы записали, а "шапку" модифицировать не успели - и тут произошёл сбой питания. :facepalm:

Добавлено after 1 minute 44 seconds:
Чтение и Стирание - это одно и то же.
При этом износ EEPROM в два раза больше...
Для флеши - запись бита с его последующим стиранием это один цикл износа. А не 2.

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 16:12:37

В моём алгоритме хранения всё уже решено: писать можно пакеты произвольной длины, в произвольном порядке.

Кроме контроля целостности данных. Именно для этого я предлагал КС добавить еще куда-нибудь в пакет )

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 17:40:48

Кроме контроля целостности данных. Именно для этого я предлагал КС добавить еще куда-нибудь в пакет )
Оно у меня есть. :) Тока не КС, а CRC32.
Есть некая структура с данными:
struct {
enum {VERSION = ...};
u8 version;
...
u32 crc;
};
Длину в ней хранить не нужно.
Эту структуру я кодирую так, чтобы в результирующем блоке данных не было байт, совпадающих со стёртым состоянием флешь (это может быть 0xFF или 0x00 - зависит от флеши). Обычно для этого использую COBS-протокол (если стёртая флешь ==0xFF, то результирующий COBS-кадр нужно затем ещё проинвертировать). Но можно и что-то типа SLIP использовать.
Теперь - можно легко отличить данные во флешь, от пустого места. Кадры между собой отделяю друг от друга как минимум одним стёртым байтом.
При чтении - ищу границы кадра (по байтам ==0xFF), декодирую (COBS), проверяю CRC и общий формат кадра.

PS: А в некоторых, особенно важных случаях, даже не CRC32 использую, а HASH256. :)

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 22:33:19

jcxz писал(а):на каждую одну запись данных делать одну запись одного бита в "шапке". И износ будет одинаков.

1. шапка == FFFFFFFF
2. шапка == FFFFFFFE
3. шапка == FFFFFFFC
4. шапка == FFFFFFF8
5. шапка == FFFFFFF0
...
Тут я вижу как изнашивается одна ячейка... которая сдохнит первой.
jcxz писал(а):Подумайте - что будет с вашим алгоритмом, если блок данных вы записали, а "шапку" модифицировать не успели - и тут произошёл сбой питания.

Для этого есть CRC.

Запись:
02 (адресс "шапка") + 111111 (Data) = CRC.

Если "шапку" модифицировать не успели, то:

Чтение:
01 (адресс "шапка") + 111111 (Data) = ошибка CRC !!!!!!!!
jcxz писал(а):запись бита с его последующим стиранием это один цикл износа. А не 2.

Это как это ? :shock:

Если я два раза подряд пушу в одну ячейку 01 и 02, то это один цикл износа ? Почему ?

Re: Arduino и энергонезависимая память

Пт сен 04, 2020 23:56:31

Или в AVR есть "секретная кнопка", о которой я не знаю, которая позволяет стирать EEPROM (FFFFFF....) так чтобы ячейки не изнашивались ?

Как я уже писал ранее, что процедура записи, что процедура стирания, обе эти процедуры изнашивают ячейку. Это обусловлено тем, что для того чтобы загнать или удалить заряд со структуры ячейки, необходимо приложить достаточный ток, который постепенно и изнашивает данную структуру. Не взирая на то, что некоторые тут незнайки категорически против. Поэтому в технической документации написано так: Запись/Стирание – столько-то раз.
Как известно, все стёртые ячейки не содержат заряд, а значит и не пропускают ток – таким образом при чтении читаются как лог 1. Когда производится запись (внесение заряда), то структура начинает пропускать ток, тем самым и читается как лог 0. По этой причине пустые ячейки EEPROM всегда читаются как 0хFF, а записанные как 0х00. EEPROM в AVR разбит на байты и при перезаписи байта производится два действия: Первое действие стирает весь байт (снимая заряд). Второе, вносит заряд в нужные биты. Тем самым получаем износ и при стирании и при записи. Справедливости ради нужно заметить, что не все ячейки байта при этом одинаково получили износ. Те которые после стирания остались без заряда на один цикл остались свежее чем те, которые получили заряд. Таким образом подход экономии износа EEPROM заключается в следующем – как можно чаще избегать двойных действий Стирание затем Запись. Нужно просто уяснить, что стирание это установка всех бит в 1, а операция запись изменяет значение с 1 в 0.

Добавлено after 31 minute 7 seconds:
Тут я вижу как изнашивается одна ячейка... которая сдохнит первой.

Нет, это не так… «он хоть и услышал звон, но не знает где он»… другими словами мысль верная, только нужно понять почему… а понимание должно наступить когда прочтёшь внимательно информацию ранее изложенную в данном посте.

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 00:30:51

Вывод отсюда только один - надо исключить функцию Стирание (после каждой записи). Оставить только функцию Запись.

Ну значит будем писать пакетами))

00 (счётчик пакетов 00...FF) + 111111 (Data) + CRC.

Запись:
1. Стираем EEPROM:

FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

2. Записываем пакет номер 00 в нулевой сектор:

001111111111111111111111111122
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

3. Записываем пакет номер 01 в первый сектор:

001111111111111111111111111122
011111111111111111111111111122
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

...

4. Записываем пакет номер 03 в третий сектор:

001111111111111111111111111122
011111111111111111111111111122
021111111111111111111111111122
031111111111111111111111111122

...

5. Записываем пакет номер 05 в первый сектор:

041111111111111111111111111122
051111111111111111111111111122
021111111111111111111111111122
031111111111111111111111111122

Чтение:
6. Ищем пакет с самым большим номером пакета.

7. Последний записанный пакет - 051111111111111111111111111122

...

8. Когда счётчик пакетов будет равен FF, переходим к пункту 1. ))

Итого: Износ всех ячеек EEPROM равномерный.

P.S.
Если надо писать пакеты разной длины добавляем в пакет Len:
00 (счётчик пакетов 00...FF) + 08 (Len 00...FF) + 111111 (Data) + CRC.
Мне не надо))
:tea:

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 00:44:21

jcxz писал(а):запись бита с его последующим стиранием это один цикл износа. А не 2.

Это как это ? :shock:

Если я два раза подряд пушу в одну ячейку 01 и 02, то это один цикл износа ? Почему ?

Не обращай внимание… программисты как и электрики поверхностно разбираются в физике полупроводников. :) Это естественно касается не всех... но в большинстве это так.

Вот на твоём примере и посчитаем сколько износов… если записать байт 0х01 в пустую «ячейку» то получим один износ. А если затем перезаписать туда 0х02, то получим в сумме уже три износа. Так как переход с 0 в 1 вынуждает вначале произвести стирание всего байта, а уже затем новую запись. Вот другой пример: Записываем в пустую «ячейку» 0х03 – получаем один износ. Затем перезаписываем туда 0х01 или 0х02 и получаем ещё только один износ. В сумме только два в место трёх как в первом примере. Вот на таком подходе и реализуют экономию износа. Так как во втором примере не производилась процедура стирания.

Добавлено after 3 minutes 15 seconds:
Вывод отсюда только один - надо исключить функцию Стирание (после каждой записи). Оставить только функцию Запись.

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

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 01:25:26

Суть я уловил.
Я не электрик и не программист. У меня широкий профиль))
Но писать по одному биту в ячейку - это не удобно. Это уже извращение какое-то))

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 01:37:24

Суть я уловил.
Я не электрик и не программист. У меня широкий профиль))
Но писать по одному биту в ячейку - это не удобно. Это уже извращение какое-то))

Я программист, но не embedded. После 10го сообщения перестал улавливать суть и просто прокрутил тему до конца. Кольцевой буфер понятно, но оптимизация в 2 раза по числу операций стирания не очень ))

Добавлено after 8 minutes 52 seconds:
Вывод отсюда только один - надо исключить функцию Стирание (после каждой записи). Оставить только функцию Запись.


Еще вариант первый сектор оставить как указатель на сектор. И не стирать его, а дописывать нулевые биты. Только нужно использовать иную систему счисления. Не 00, 01, 02, 03, а FF и далее по спадающей, но не вычитанием единицы.
Типа изначально
1111 1111 - указатель на первую ячейку с данными
1111 1110 - вторая
1111 1100 - третья
1111 1000 - четвертая
...
0000 0000 - восьмая

В EEPROM придется выделить 1/8 памяти под индекс и таким образом его прописывать. Много битовой магии ))

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 12:37:45

Тока не КС, а CRC32.

CRC32 и есть КС.

Добавлено after 41 minute 15 seconds:
Не взирая на то, что некоторые тут незнайки категорически против. Поэтому в технической документации написано так: Запись/Стирание – столько-то раз.

Что будет, если миллионы раз подряд "стирать" ячейку, ничего в неё не записывая?

А если затем перезаписать туда 0х02, то получим в сумме уже три износа. Так как переход с 0 в 1 вынуждает вначале произвести стирание всего байта, а уже затем новую запись.

Вряд ли Microchip согласиться с вами. Подтвердите это чем-нибудь?

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 14:13:35

Много битовой магии ))

Магии не много...

1111 1111 = (<<0) - флаги - номер сектора.
1111 1110 = (<<1) - флаги - номер сектора.
1111 1100 = (<<1) - флаги - номер сектора.
1111 1000 = (<<1) - флаги - номер сектора.
...
0000 0000 = (<<1) - флаги - номер сектора.

Но не удобно всё это...))

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 14:43:28

Подтвердите это чем-нибудь?

Не вижу в этом смысла.

Re: Arduino и энергонезависимая память

Сб сен 05, 2020 15:26:45

Что будет, если миллионы раз подряд "стирать" ячейку, ничего в неё не записывая?

увольнение "погромиста"

Re: Arduino и энергонезависимая память

Вс сен 06, 2020 11:01:50

Подтвердите это чем-нибудь?

Не вижу в этом смысла.

А лучше бы видели. Вы ошибаетесь:
http://ww1.microchip.com/downloads/en/a ... 01019a.pdf

The term “data changes” is occasionally used in place
of “write cycle” or “erase/write cycle.” A data change
will occur when an auto-erase cycle is initiated, and a
second data change will occur upon the write cycle,
therefore, an “erase/write cycle” is equivalent to two
“data changes.”

То, что вы называете 2мя операциями - в терминах Microchip называется "data change". А "erase/write cycle" при этом уже включает в себя 2 "data change" - очистка (erase) ячейки и запись в неё новых данных. С точки зрения расхода ресурса именно это считается за одну операцию в терминологии производителя.

Добавлено after 1 minute 33 seconds:
Что будет, если миллионы раз подряд "стирать" ячейку, ничего в неё не записывая?

увольнение "погромиста"

Это был чисто теоретический, а не практический вопрос.
Ответить