Comments 83
Не хотелось составлять длинный нудный список использованных работ, в конце концов гугл есть у всех.
А вот этого не могу одобрить. Список литературы — это может быть еще и список рекомендуемый автором к ознакомлению по данной теме.
«Список, рекомендуемый автором к ознакомлению по данной теме» — затронуто слишком много тем (флеш-память, deflate, crc, вскользь другие коды обнаружения и коррекции ошибок, linux devicetree). По каждой теме есть десятки заслуживающих внимания публикаций. Боюсь, что даже если бы я и нашёл силы составить достойный список, один его вид убивал бы весь энтузиазм.
Насчет списка литературы поддержу.
А так — спасибо за статью
«На столе» битовых ошибок пока не попадалось, но это не показатель, конечно.
Я уже писал, что было очень горячее желание добавить ECC, но я понял, что для принятия решения нужна статистика.
В сети полно реализаций алгоритма, например загуглите доку Samsung по Hamming ECC for NAND Flash
Вы про этот алгоритм:
github.com/torvalds/linux/blob/master/Documentation/driver-api/mtd/nand_ecc.rst
?
Он почему-то везде называется кодом Хэмминга, хотя он требует 22 добавочных бит на блок из 2048бит, а «настоящий» код Хэмминга — 12 добавочных бит (а в 24 добавочных бита ЕМНИП помещается код, исправляющий 2 битовые ошибки).
Как я понимаю, преимущество у этого кода — простота реализации и скорость.
Причем вы можете защищать с помощью ECC не пакет данных (запись в вашей терминологии), а страницу, к примеру размером 64-256 байт.
это не сработает, если нужны операции записи размером меньше страницы, NOR не позволит переписать уже записанный ECC для страницы.
Вроде бы у вас копеечные размеры, а EEPROM позволяет миллион перезаписей (на самом деле больше, но миллион гарантируется).
Что же до числа записей, по грубым прикидкам и с NOR у нас есть запас в пару порядков.
P.S. «в простонародье» когда говорят EEPROM часто имеют в виду именно NOR Flash.
А вообще, у меня в аквариуме SD-карта на 128Мб (SLC) уже много лет трудится, журналы пишет, жива-здорова, но тут тоже как повезёт…
С SSD, кстати, то же самое.
при постоянном обновлении данных вы не сталкиваетесь со стеканием заряда в ячейках, а с редко используемой флешкой — в полный рост проявляется data retention
И что делать, чтобы максимально продлить срок службы MicroSD с системой?
Получается, часто пишем (изначальный подход) — плохо. Не пишем (readonly) — опять плохо, заряд а ячейках не обновляется.
Про кеширование: на CortexA9 (zynq 7000) столкнулся с тем что функция линейного чтения из флеш кэширует данные в кэше проца. Это канешно зависит от настроек translation_table, но по умолчанию она настроена на кеширование. При обычном чтении ( не линейном ) кеширования нет.
Да, о ней.
Я обнаружил это когда работал в bare metal. То есть это фактически возможно и надо иметь это ввиду.
ИМХО вы явно что-то недоговариваете.
не может быть такого, что вы выплюнули в spi 03 XX YY ZZ, а процессор что-то закэшировал.
Есть такой режим линейного чтения. Реализован в контроллере qspi специально для работы с флеш памятью. Как я понимаю, в этом режиме определенное адресное пространство процессора отображается на флеш память и может кешироваться в L2 кеше как и все остальное адресное пространство.
ну так с этого и надо было начинать, это уже не прямая работа с микросхемой через SPI, а через обвязку (в вашем случае аппаратную).
в моём случае есть программная обвязка (стек mtd/spi-nor/spi в ядре linux), я её проверил на предмет отсутствия кэширования, о чём и написал в статье (то есть если я читаю из /dev/mtdX, то обязательно идёт обращение к микросхеме).
как обнаружили, кстати?
А почему не FRAM? Например https://www.cypress.com/products/f-ram-nonvolatile-ferroelectric-ram
Но с другой пример лечения пореза пальца пересадкой мозга в клонированное тело.
Как разработчик ПЛК тоже сталкиваюсь с жалобами клиентов на устойчивость работы с USB накопителями.
И анализ проектов пользователей показал что оно и должно ломаться со временем.
Что делает типичный «автоматизатор»:
1. Создаёт множество файлов логов, особенно в корне (корень у той же FAT очень особенная область)
1а. Создаёт множество файлов с одинаковым началом и различием в районе 10-50 го символа имени. Как результат механизм формирования коротких имён в FAT в зависимости от реализации стека либо сходит с ума, либо работает как черепаха в бетоне.
2. Пишет в файлы по чуть-чуть. (запись на 50 байт — а трётся страница флеши в глубине флешки)
3. Пишет непрерывно (нет времени для встроенного контроллера флеши на сбор мусора и релокацию)
4. Не используются алгоритмы контроля качества питания (сигнал по первичке щита на пропадание питания, отдельный БП увеличенной мощности на питание ПЛК) — в результате пропадание питание встречает программу логирования со «спущенными штанами»
5. Дешевые флешки — это самый простой пункт.
Соответственно, простые рекомендации по вышеизложенным пунктам позволяют логировать на флешки без проблем с их выходом из строя.
1. Файлов должно быть мало.
2. Файлы должны именоваться уникально начиная с первых символов, имя надо делать в формате 8.3
3. Пишем сразу не менее чем блок FAT (до 64 кБайт!)
4. Пишем атомарно, открыл, записал, закрыл, сделал FLUSH.
5. Пишем с паузами. По опыту желательно не менее 1 минуты
6. Система питания должна удерживать питание на флешке не менее 5-6 секунд после получения сигнала о пропадании питания. Естественно в это время надо закрыть все файлы и не писать.
И внезапно проблемы с флешками исчезают.
хорошо, расскажу, как было в предыдущем проекте с USB-флешками, которые периодически подыхали.
Файлов должно быть мало.
запись была в один-единственный файл.
притом даже без циклической перезаписи, просто один файл.
объёма флешки было достаточно на несколько лет работы.
и да, по сути на этой флешке больше ничего не было (помимо этого файла там лежало ещё несколько, обновляемых не чаще нескольких раз в месяц), сама прошивка была в parallel NOR железки.
Пишем сразу не менее чем блок FAT (до 64 кБайт!)
ну не нужно мне было столько писать. писал по 512 байт.
Пишем атомарно, открыл, записал, закрыл, сделал FLUSH.
именно так оно и было (разве что файл не переоткрывался, зачем?)
Пишем с паузами. По опыту желательно не менее 1 минуты
там было в районе тысячи записей в сутки, минутных пауз там было больше, чем достаточно.
или имеется в виду "после каждой записи ждать минуту"?
512 байт слишком мало, реально флешка имеет страницу от 2 до 4 кбайт.
Раз файл не переоткрывался — то он не закрывался. А значит ФС не могла (тут зависит от реализации) делать flush правильным образом.
Пауза желательна после каждой.
Ну и питание, питание на первом месте, если не использовать журналируемые ФС.
Но NOR — это хорошее решение, т.к. тут качество микросхемы под контролем разработчика. Что там запаяют во флешке — вопрос.
512 байт слишком мало, реально флешка имеет страницу от 2 до 4 кбайт.
Можете обосновать подробнее? У большинства NAND 512 байт — как раз минимально допустимый размер записи для срабатывания ECC.
Вы сейчас про замену замену NOR Flash?
А в чём смысл?
Вот посмотрите, например, pdf от Macronix. "Data retention" падает в зависимости от числа Erase и температуры, после 10к Erase при температуре 80℃ данные будут сохранны в течение года.
Для предполагаемого применения этого более, чем достаточно.
В последних версиях ядра Linux реализована поддержка файловой системы exFAT. Она оптимизирована под более равномерный износ флеш-памяти.
А можно детали?
Тут, например, я сходу не увидел ничего, что должно серьёзно повлиять на число перезаписей.
На самом деле, практически в любой файловой системе последовательная запись в preallocated файл практически не вызывает write amplification, но, как я писал уже, это не спасает.
Значит, чтобы флешка жила долго, нужен как можно больший объём ячеек, дабы часто их не перезаписывать.
я уже писал, не помогает.
возможно, версия о вине неожиданного отключения (питание отключается в момент, когда флешка обновляет какие-то свои внутренние структуры) имеет право на жизнь. хотя у меня есть стойкое ощущение, что выключение/перезагрузка просто обнажает проблему, которая образовалась до этого (в пользу этого говорит хотя бы тот факт, что часто после перезагрузки обнаруживается пропажа не только последних данных, а данных за последние несколько дней или даже недель).
в любом случае раз есть возможность не играть в азартные игры с USB/SD/MicroSD/etc — я буду этой возможностью пользоваться.
Вы уже третий, кто рекомендует F-RAM. Но никто так и не аргументировал чем F-RAM лучше NOR в этом случае.
Больше число перезаписей? Ну так и с NOR у нас запас на пару порядков.
Нет проблемы с data retention? Так я писал чуть выше, что даже в неблагоприятных условиях NOR справится.
Ниже BER? Я не видел оценки ни для NOR, ни для F-RAM.
Тогда в роли надёжной и быстродействующей памяти для индексов и контрольных сумм к flash хранилищу
Данные писать на MicroSD, а CRC (и, возможно, некоторые метаданные) на F-RAM?
То есть вы предлагаете собрать воедино недостатки обоих подходов "хранить данные на MicroSD" и "держать MicroSD в RO, хранить данные где-то ещё": с одной стороны, мы усложняем аппаратную часть, вводя дополнительное хранилище; с другой, при выходе карточки памяти из строя мы всё равно теряем данные.
Но это долгое и недешёвое удовольствие. У Вас proof of concept или реально работающий проект? Сколько устройств в эксплуатации, как давно, какая статистика по отказам?
Иногда можно упростить реализацию добавлением контроля качества питания с запасом энергии на гарантированное закрытие транзакции. Не берусь утверждать, что это Ваш случай, но всё же.
Но это долгое и недешёвое удовольствие. У Вас proof of concept или реально работающий проект?
недешёвое в разработке? или в железе? в железе как раз недорого, рублей 100 на микросхему, место на плате, ну с пайкой может чуть дороже.
разработка я бы тоже не сказал, что очень дорогая, дольше всего, наверное, выбирал как буриданов осёл между разными вариантами с статью писал )
Сколько устройств в эксплуатации, как давно, какая статистика по отказам?
чуть больше сотни, поддержка SPI flash с нового года, пока особой статистики нет.
Есть в ядре Линукса.
и та, и другая работают поверх блочного устройства, а не поверх mtd.
сомневаюсь, что с микросхемой в 4мб стоит что-то хранить в файловой системе.
и циклическую запись так и так пришлось бы реализовывать самому.
так в статье же написано: чтобы перевести microsd в readonly
не верю. в сети достаточно много отзывов о погибших флешках, эксплуатировавшихся в режиме r/o (справедливости ради, у меня за три месяца ан примерно сотне устройств пока ни одной, но так и срок невелик)
ФС, типа NILFS2, сами на программном уровне решают этот вопрос.
Организуя циклическую перезапись по типу кольцевого буфера.
Ну и флэшку, самой собой, нужно брать покачественнее.
Флэшки гибнут потому что у них нет полноценного контроллера для выравнивания износа.
когда-то давно я делал просто линейную запись в файл на флешке (в циклической записи не было нужды из-за смешных объёмов). один-единственный preallocated файл. и они всё равно дохли пачками.
хотя говорить «дохли» неправильно.
самое частое: записываешь в файл, записываешь. после каждой записи делаешь fsync. всё отлично. но только после ребута в файле оказывается информация на какой-то момент несколько дней назад. и всё опять «работает», после ребута опять откат.
вторая, наверное, по частоте проблема: считаешь md5 флешки, перевтыкаешь, считаешь ещё раз — не сходится.
ну и банальное "флешка перестала определяться" случается тоже.
из всего этого на износ NAND похоже разве что второе. только оно и на новых флешках встречается, вы уверены, что замена файловой системы поможет? )
2. Даже если вы пишете очень корректно, так что не затрагиваются FAT таблицы, то всё равно переписываются аттрибуты (mtime), которые лежат на определённых секторах и сектор вылетает вместе с остальной флэшкой.
3. Поэтому и нужны ФС, которые умеют любую запись самостоятельно записывать в новое пространство.
- ещё раз повторю: я не переписывал данные в файле, только дозапись.
так что хоть единственный файл, хоть 1024 разных файла — роли не играет. - да, я в курсе. только вот список типичных проблем, который приводил чуть выше, наводит на мысли, что дело не в этом.
вообще у меня устойчивое ощущение, что в флешках чаще выходит из строя/глючит контроллер чем NAND
ещё раз повторю: я не переписывал данные в файле, только дозапись.
так что хоть единственный файл, хоть 1024 разных файла — роли не играет.
В таком случае вы постоянно переписывали FAT c каждой следующей дозаписью. Рецепт лечения тот же — использовать ФС приспособленную для флэш: NILFS2 или F2FS или подобную.
В таком случае вы постоянно переписывали FAT c каждой следующей дозаписью.
один-единственный preallocated файл
2. Даже если вы пишете очень корректно, так что не затрагиваются FAT таблицы, то всё равно переписываются аттрибуты (mtime), которые лежат на определённых секторах и сектор вылетает вместе с остальной флэшкой.
ещё раз повторю: я не переписывал данные в файле, только дозапись.
так что хоть единственный файл, хоть 1024 разных файла — роли не играет.
Если файл preallocated, то вы именно переписывали, а не делали дозапись.
А если файл был sparse — то ещё и FAT переписывалась при каждой дозаписи.
файл не был sparse. и да, я переписывал, но каждый сектор только по 2 раза (первый раз — заполнение нулями при создании файла, второй — запись данных).
не считая модификации mtime, такая запись ничем не отличается от последовательной записи в блочное устройство руками (и не сильно отличается от тех же flash-friendly fs, только overhead меньше)
И я не слышал, чтобы при внезапном отключении питания nilfs2 теряла работоспособность, в отличии от UBIFS (есть статья на Хабре о таких проблемах).
habr.com/ru/post/273425
.
Продолжая обозначенную в самом начале тему readonly SBC. Что вы думаете о материале он ещё актуален?
Моя реализация кольцевого буфера в NOR flash