Как стать автором
Обновить

Комментарии 33

А на С++ можно сделать, чтобы запись была очень юзерфрендли, без знания секторов и адресов EEPROM

myCounter.Set(newValue);

тут вот описал https://habr.com/ru/post/561678/

Спасибо за ссылку, очень интересная статья!)

Это не так обычно делается. Просто счетчики износа оборудования считают от нуля и ведут в ОЗУ. И каждые минут десять или ещё как-то по желанию добавляют к основным счётчикам в ПЗУ. Для задач бизнеса и для любых других технических это более чем достаточно. Погрешность при сбросе конечно есть, но это мизерная погрешность для реально эксплуатируемого изделия.
EEPROM (раньше по крайней мере) ещё жрала при записи много, да и экзотика это в эпоху ARM.
также встречается тамперная память — небольшая оперативка в контроллерах под напряжением батарейки часов. Туда можно.
А для жадных извращенцев, как я, могу рекомендовать писать в память программ. Там 10 000 циклов. Тоже хорошо.
НЛО прилетело и опубликовало эту надпись здесь

Производитель память программ в даташите называет EEPROM PROGRAM областью. И контроллер Flash-памяти программ называет MDR_EEPROM. Есть определенная путаница в формулировках, конечно.

Судя по отечественному контроллеру и задаче подсчёта ресурса, автор делает что-то для военки. А туда засунуть батарейку, думаю, будет не так просто. Я для подобной задачи очень хотел применить 1666РЕ014 — её можно перезаписывать бесконечно практически. Но в список МОП она так и не попала (говорят, там кристалл импортный).

Еще можно записывать накопленные данные в EEPROM по приходу power down event, технически обеспечив достаточное для записи время работы контроллера после выключения питания. Делал так в одном любительском проекте.

Ага, вешаешь на питание конденсатор микрофарад на 500, и заводишь внешнее питание на прерывание. Как раз хватает несколько ячеек eeprom записать

иногда можно писать побитно. т.е. 0xFF -> 0xFE -> 0xFC -> 0xF8 -> 0xF0 -> ..., и 4096 байт превращяются в 32768 бит. раз в минуту -> 32768 минут = почти 23 дня. * 10000...

Попробуйте. При записи в ячейку возможно обнулять биты. (в единички - только стиранием).

на самом деле, первые 2-4 байта можно использовать как счетчик перезаписей (+KC), или еще один сектор использовать для записи битов количеств перезаписей основного сектора. Или чередовать секторы - на что хватит фантазии.

НЛО прилетело и опубликовало эту надпись здесь
Еще можно FRAM на i2c повесить — 10^13 циклов перезаписи.

Можно и обычную внешнюю I2C EEPROM. Там минимум 1 млн. перезаписей страницы. Взять самую мелкую, хоть на 1 кбит и с помощью 16 страниц можно обеспечить работу счётчика в течение 20 лет.

Согласно Миландру данный контроллер аналог STM32F103X, который имеет backup domain. Так и чухаем его регистры и по прерыванию питания сливаем в энергонезависимую. Так будет кошернее. К стати, бекап домен имеет свое питание, соответственно проблема стремится к нулю.

Надо будет опробовать ваше решение. Только батареечное питание ставить не вариант, но можно ионистор прикрутить.

иногда ставят электролит (не очень большой, хотя бы 470uF на 6.3V). Компаратором или АЦП ловят просадку по питанию и за несколько секунд — сотен милисекунд и даже десятков милисекунд можно очень много всего забекапить и корректно завершить все критические секции.
ионисторы сильно разные по утечкам. Разнятся даже в зависимости от партии. У некоторых большой саморазряд. Да и вроде влагу из воздуха сосут, что саморазряд ускоряется со временем. Из-за этого некоторые вендоры начали заливать их компаундом.
Не думаю что стоит всерьез надеятся на них если требуется целостность данных больше чем несколько часов.
Внешняя микросхема eeprom или даже более дешевая serial-flash будет лучше и дешевле.

На самом то деле, что мешает держать счётчик в ОЗУ и при событии снижения питания (детектирование любым удобным способом) или просто с более длительным периодом записывать в ПЗУ?

Переменную можно разместить в неинициализируемой области (настраиваем скрипт для линкера) и перезагрузки не страшны.

Нужна лишь ёмкость по питанию чуть больше чем обычно. Можно сказать почти бесплатное решение.

Да, мы пробовали всякие супервизоры питания. В диапазоне температур -50 +50 и термоциклировании и утечек отечественных электролитов сложно говорить о надёжности супервизоров. В итоге решение периодически записывать в энергонезависимую память, тем более, что она доступна непосредственно в МК оказалось самым надёжным.

Оперативной памяти доверять нельзя. Ионистор не защитит Вас от броска по питанию или статического разряда (ESD) и все ваши накопления за несколько дней будут утеряны. Писать надо регулярно в EEPROM с последовательным «размазыванием», с сохранением контрольной суммы и номера серии, желательно не реже чем раз в сек. Номер серии нужен для того, что бы при перезапуске устройства найти последнее правильное значение. Данное решение выстрадано и проверено годами.

Что будет, когда счетчик переполнится?

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

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

Это произойдет лишь через 12 лет :)

12 лет ничто для электронной техники ИМХО. У меня дома комп 2010 года трудится, как раз 12 лет. Я бы очень опечалился, если он внезапно из-за такой мелочи превратился в тыкву.

Так это же смотря какая электроника. Поди сейчас найди у кого-то смартфон такого возраста :)

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

ЗЫ айфон шесть, с которого я пишу выпускался с 14го года, у товарища есть в пользовании пятый и брал он его новым один из первых, ему уже девять лет и менять он его ни на что не хочет, говорит это последний из телефонов, следующие - одни лопаты. ))

Я вовсе не исключаю, что есть владельцы таких смартфонов, но их придется поискать :)
Что касается описываемого Вами случая со счетчиком, то если даже по прошествии 12 лет работы он 10 раз подряд будет включаться на время, меньшее, чем 1024 минуты (около 17 часов), то это все равно будет слишком несущественно на фоне общего времени наработки. Если это какой-то не супер критический прибор, то я, например, считаю допустимым это.

Это не про смартфоны. Это все больше про войну.

Ага, понятно )))

- так, ребята... "науке" больше не наливать... топлива...

Немножко не понял вопроса. Страница разбита на 4 сектора по 256 4-х байтных слов. И каждый из этих секторов стирается отдельно. Т.е. для перехода на запись в следующий сектор его предварительно очищают. Когда у вас все 4 сектора заполнены происходит стирание первого сектора и переход от четвертого сектора к первому. При этом предыдущие данные сохраняются в четвертом секторе.

У вас наступает момент, когда в память записывается последнее число, которое является максимальным. После него через минуту счетчик переполняется и принимает нулевое значение, которое тоже записывается в память. Затем, допустим, оборудование до истечения (256*3+1) минут - согласен, не 1023, - выключают. Таким образом, у нас в памяти присутствует максимально возможное значение и куча всяких других.

После включения вы ищете по всем страницам наибольшее значение и оно оказывается равным максимально возможному. Через минуту снова записывается нулевое значение и т.д.. И, если после включения оборудование проработало менее (256*3+1) минут и его выключили, то максимально возможное значение осталось незатертым.

Если бы вы при переполнении (обнуления) счетчика произвели бы стирание всех страниц, то такого зазора в (256*3+1) минут, в котором не происходит подсчет моточасов, не было бы.

Может глупый вопрос, но для чего объединение включать в отдельную структуру?

typedef struct 
{
  union 
  {
...
	};
} counter_value_t;

Это такой стиль или в этом есть скрытый смысл?

Вопрос не глупый. Это просто артефакт, лишнее, не подчищенное. Можно вполне убрать вложение в структуру. Сделать сразу typedef union{...}counter_value_t

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации