Pull to refresh

Comments 83

Не хотелось составлять длинный нудный список использованных работ, в конце концов гугл есть у всех.

А вот этого не могу одобрить. Список литературы — это может быть еще и список рекомендуемый автором к ознакомлению по данной теме.

В своё оправдание могу сказать, что в тексте есть несколько ссылок.

«Список, рекомендуемый автором к ознакомлению по данной теме» — затронуто слишком много тем (флеш-память, deflate, crc, вскользь другие коды обнаружения и коррекции ошибок, linux devicetree). По каждой теме есть десятки заслуживающих внимания публикаций. Боюсь, что даже если бы я и нашёл силы составить достойный список, один его вид убивал бы весь энтузиазм.

Насчет списка литературы поддержу.


А так — спасибо за статью

Из жизни — при активной работе, и даже иногда без нее — в SPI NOR памяти довольно часто возникают битовые ошибки. Atmel, Winbond, ST — не важно. Поэтому CRC — обязательно к применению. В тех устройствах которые мы исследуем/ чиним производители железок много лет (сколько используются SPI NOR) используют CRC для контроля считанных данных — и кода, и секций с данными. PS: уточню — я про 25 серию
Да, встречал такую информацию.

«На столе» битовых ошибок пока не попадалось, но это не показатель, конечно.
Я уже писал, что было очень горячее желание добавить ECC, но я понял, что для принятия решения нужна статистика.

Если для вас потеря записи будет несущественна — то ECC вам не нужен. В таком случае с помощью CRC вы лишь сможете определить факт появления «битой» записи. Если нужно обеспечить еще и коррекцию — я бы сделал простой 1-битовый алгоритм коррекции ошибок, в паре с CRC32. В сети полно реализаций алгоритма, например загуглите доку Samsung по Hamming ECC for NAND Flash — его вполне можно применить и на SPI. Причем вы можете защищать с помощью ECC не пакет данных (запись в вашей терминологии), а страницу, к примеру размером 64-256 байт.
мне потеря более-менее критична так как данные пишутся одним сжатым потоком, я потеряю не одну запись, а её и все последующие на странице.

В сети полно реализаций алгоритма, например загуглите доку 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 для страницы.
Да, визуально он. У меня лежат pdf с описанием, там приблизительно то же. Ну а насчет страниц — да, это действительно проблема. Может быть имеет смысл просто дублировать записи — писать их два раза или в две флешки. Это будет проще чем городить огород с ецц
Я рассматривал и этот вариант тоже. Повторю: накоплю статистику, а там видно будет.
UFO just landed and posted this here
А почему не смотрели в сторону EEPROM?
Вроде бы у вас копеечные размеры, а EEPROM позволяет миллион перезаписей (на самом деле больше, но миллион гарантируется).
Я в начале статьи написал, что хочется иметь объём не меньше нескольких мегабайт, так что EEPROM отпадает.
Что же до числа записей, по грубым прикидкам и с NOR у нас есть запас в пару порядков.

P.S. «в простонародье» когда говорят EEPROM часто имеют в виду именно NOR Flash.
В простонародье сильно ошибаются. Разница в надёжности на порядок. Но, если вам хватает, почему бы и нет. Хотя, если пару порядков, то и нормальная SLC должна была бы справиться.
Они только в этом году к 4 мегабитам (512 килобайт) приблизились, и это будет конская цена. Пруф — STMicro Introduces the World’s First 4Mbit SPI EEPROM — новость 22 ноября 2019 года. M95M04. Обещают 4 миллиона циклов записи и 40 лет сохранности.
Во-первых мегабитная микруха стоит 140р. в розницу. Во-вторых, кто вам мешает их хоть 8 штук повесить, например по i2c? Я бы даже сказал, что кольцевую запись было бы проще организовать.
А вообще, у меня в аквариуме SD-карта на 128Мб (SLC) уже много лет трудится, журналы пишет, жива-здорова, но тут тоже как повезёт…
1 мегабит — это всего 128 килобайт, автору их прийдется распаять 64 штуки чтобы достичь сравнимой емкости. Насчет вашей SD карты — а сейчас просто купить такие новые недорого? В те времена когда ваша SD карта была выпущена (это начало нулевых) — кроме SLC другой памяти и не существовало…
У меня вообще складывается впечатление (из собственного опыта), что порча данных на флешках чаще бывает из-за нештатного пропадания питания, нежели от недостатков архитектуры NAND. У меня в фотоаппаратах данные чаще теряются, чем в видеорегистраторе авто, при том, что там нагрузка выше. Потому что регистратор одной ногой подключен к гарантированному батарейному питанию и всегда выключается корректно.
Я бы сформулировал так: чаще глючит/умирает контроллер, чем сама память.
С SSD, кстати, то же самое.
Контроллер не умирает в них вообще никогда. Занимаемся Data recovery — поэтому знаем о чем говорим. Повреждаются служебные данные — таблицы трансляции, страницы с микрокодом в нандах, много чего. В основном проблемы связаны со стеканием заряда и, как следствие, с невозможностью прочитать (и скорректировать с помощью ECC) нужные для старта накопителя объекты.
Интересовался как именно работает ftl в реальных устройствах, так ничего не нашёл. Плохо искал? Или никто не делится информацией — ни разработчики, ни те, кто реверсят?
Такую информацию можно добыть реверсом и изучением расположения данных в нандах.
нет, при постоянном обновлении данных вы не сталкиваетесь со стеканием заряда в ячейках, а с редко используемой флешкой — в полный рост проявляется data retention — для TLC памяти он гарантируется всего в 3 месяца для изношенной памяти. Кстати, для Enterpice SSD производитель указывает разный ресурс памяти в циклах, в зависимости от того, сколько данные должны храниться. Например, если нужно 3 месяца — то это 500 циклов, типичных для TLC. Если нужно неделю — то это уже будет (по памяти, могу ошибиться) 10000.
при постоянном обновлении данных вы не сталкиваетесь со стеканием заряда в ячейках, а с редко используемой флешкой — в полный рост проявляется data retention

И что делать, чтобы максимально продлить срок службы MicroSD с системой?

Получается, часто пишем (изначальный подход) — плохо. Не пишем (readonly) — опять плохо, заряд а ячейках не обновляется.
Если карта памяти новая — у вас есть гарантированно полгода-год. Дальше уже может сдохнуть даже в режиме RO.
К стати, по поводу влияния пропажи питания. После первого же инцидента, связанного с пропаданием питания на моем сервере умного дома (малинка 3.0, ОС выжила, а вот последние настройки слетели) озаботился и купил на Али БП со встроенным аккумулятором 18650. Uptime года три уже, обычная micro sd карта на 16Гб, журналы тоже непрерывно пишутся, показания датчиков температуры, влажности, давления и др. каждую секунду…
О, хотел же перечислить часто встречаемые глюки с флешками, вот один из них: на карту пишется вроде бы нормально, после перезагрузки видим данные давностью несколько часов/дней/недель.

Про кеширование: на CortexA9 (zynq 7000) столкнулся с тем что функция линейного чтения из флеш кэширует данные в кэше проца. Это канешно зависит от настроек translation_table, но по умолчанию она настроена на кеширование. При обычном чтении ( не линейном ) кеширования нет.

Речь про SPI NOR или что-то другое?
используются модули ядра m25p80 и spi_nor?

Я обнаружил это когда работал в bare metal. То есть это фактически возможно и надо иметь это ввиду.

ИМХО вы явно что-то недоговариваете.


не может быть такого, что вы выплюнули в spi 03 XX YY ZZ, а процессор что-то закэшировал.

Есть такой режим линейного чтения. Реализован в контроллере qspi специально для работы с флеш памятью. Как я понимаю, в этом режиме определенное адресное пространство процессора отображается на флеш память и может кешироваться в L2 кеше как и все остальное адресное пространство.

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


в моём случае есть программная обвязка (стек mtd/spi-nor/spi в ядре linux), я её проверил на предмет отсутствия кэширования, о чём и написал в статье (то есть если я читаю из /dev/mtdX, то обязательно идёт обращение к микросхеме).


как обнаружили, кстати?

Замерял скорость чтения. В линейном режиме при повторном чтении показал какую то невероятную скорость, потом понял.

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

Как разработчик ПЛК тоже сталкиваюсь с жалобами клиентов на устойчивость работы с 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 минуты

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


или имеется в виду "после каждой записи ждать минуту"?

1 файл тоже не самый хороший вариант, нормальное число файлов от 10 до 100, мы стараемся чтобы файл хотя бы раз в сутки менялся. И удалялся после устаревания
512 байт слишком мало, реально флешка имеет страницу от 2 до 4 кбайт.
Раз файл не переоткрывался — то он не закрывался. А значит ФС не могла (тут зависит от реализации) делать flush правильным образом.
Пауза желательна после каждой.
Ну и питание, питание на первом месте, если не использовать журналируемые ФС.

Но NOR — это хорошее решение, т.к. тут качество микросхемы под контролем разработчика. Что там запаяют во флешке — вопрос.
512 байт слишком мало, реально флешка имеет страницу от 2 до 4 кбайт.

Можете обосновать подробнее? У большинства NAND 512 байт — как раз минимально допустимый размер записи для срабатывания ECC.
у современных нандов размер страницы 16к, но это вас не должно волновать совсем. Флешке в общем-то совершенно все равно сколько и куда вы пишете. И ей как устройству совершенно все равно сколько там файлов в ФС. Ей вообще все равно как организованы данные. Для транзакций, не кратных размеру страницы нанда все контроллеры флешек используют механизм «апдейтов» — такое послойное наложение новых секторов поверх изначального содержимого страниц.
Размер страницы это скорее деталь реализации и способа адресации. Только spare area привязана к странице, писать по целой странице не так уж и обязательно, только для скрамблинга может быть выгодно писать целую страницу. А вот уважеть минимальный размер записываемого приходится, иначе не сработает ECC. Поэтому ftl обычно делит нанд на логические сектора минимального допустимого размера. Альтернатива — это только что-то наподобие UBI и запись в размер стираемого блока, а он довольно велик.

Вы сейчас про замену замену NOR Flash?


А в чём смысл?
Вот посмотрите, например, pdf от Macronix. "Data retention" падает в зависимости от числа Erase и температуры, после 10к Erase при температуре 80℃ данные будут сохранны в течение года.
Для предполагаемого применения этого более, чем достаточно.

Никто не упомянул такой важнейший фактор, как рабочая температура flash памяти. Изолированный затвор полевых транзисторов ячеек теряет заряд намного быстрее при высоких температурах. Перегревающаяся ячейка быстро обнулится. Средний срок хранения данных каждый производитель пишет очень по-разному. Но я считаю, что нужно брать самый минимальный срок из всех, исходя из того, как часто на практике память выходит из строя или частично обнуляется сама по себе. А это 10 лет при 25 градусах. Отсюда можно сделать вывод, что при нагреве срок ощутимо уменьшится. Ну и как вывод, при длительном хранении необновляемых данных, их нужно регулярно перезаписывать, стирая ячейки (заряжая затворы транзисторов) скажем, каждые 5 лет. Теперь вопрос ограниченности циклов записи на ячейку, которые у flash памяти стираются страницами. Нужно ориентироваться на опять же минимальное число, заявляемое производителями. Это 1 тысяча циклов. Значит, чтобы флешка жила долго, нужен как можно больший объём ячеек, дабы часто их не перезаписывать. И последнее. В последних версиях ядра Linux реализована поддержка файловой системы exFAT. Она оптимизирована под более равномерный износ флеш-памяти. Думаю оптимальный ценовой вариант это 32ГБ MicroSD + exFAT + около 25 градусов рабочей температуры. Успехов! P. S.: Забыл упомянуть об ускорении обнуления ячеек, при чтении соседних. Электроны близко бегают, видимо подогревают. )))
В последних версиях ядра Linux реализована поддержка файловой системы exFAT. Она оптимизирована под более равномерный износ флеш-памяти.

А можно детали?
Тут, например, я сходу не увидел ничего, что должно серьёзно повлиять на число перезаписей.


На самом деле, практически в любой файловой системе последовательная запись в preallocated файл практически не вызывает write amplification, но, как я писал уже, это не спасает.


Значит, чтобы флешка жила долго, нужен как можно больший объём ячеек, дабы часто их не перезаписывать.

я уже писал, не помогает.


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


в любом случае раз есть возможность не играть в азартные игры с USB/SD/MicroSD/etc — я буду этой возможностью пользоваться.

Тогда в роли надёжной и быстродействующей памяти для индексов и контрольных сумм к flash хранилищу использовать что-то вроде дешёвой FRAM типа FM25L04B-GTR.

Вы уже третий, кто рекомендует F-RAM. Но никто так и не аргументировал чем F-RAM лучше NOR в этом случае.
Больше число перезаписей? Ну так и с NOR у нас запас на пару порядков.
Нет проблемы с data retention? Так я писал чуть выше, что даже в неблагоприятных условиях NOR справится.
Ниже BER? Я не видел оценки ни для NOR, ни для F-RAM.


Тогда в роли надёжной и быстродействующей памяти для индексов и контрольных сумм к flash хранилищу

Данные писать на MicroSD, а CRC (и, возможно, некоторые метаданные) на F-RAM?
То есть вы предлагаете собрать воедино недостатки обоих подходов "хранить данные на MicroSD" и "держать MicroSD в RO, хранить данные где-то ещё": с одной стороны, мы усложняем аппаратную часть, вводя дополнительное хранилище; с другой, при выходе карточки памяти из строя мы всё равно теряем данные.

Кстати индексы можно записывать самым щадящим методом прямо во flash, используя натуральный счёт из битов. Стираем блок ячеек, получаем единицы. Записываем нули по одному. Количество нулей и будет числом индекса. Получается большой расход объёма, но при этом редчайшее стирание ячеек. Из 32 мегабит отдай мегабит на индекс, и можно вести отсчёт до 1 048 576. Затем весь мегабит стирается, и всё по новой.
Автор, годная статья, радует подход с разных углов, избыточное кодирование и прочее. Если данные относятся к коммерческим транзакциям, то хранить их ни на USB-флэшке, ни на [micro]SD, конечно, нельзя. Даже на двух в режиме RAID:) Поведение внутреннего контроллера при отключении питания хотя и зависит от стоимости изделия, но всё равно без гарантий. Поэтому альтернативный и контролируемый способ записи информации, конечно, напрашивается…

Но это долгое и недешёвое удовольствие. У Вас proof of concept или реально работающий проект? Сколько устройств в эксплуатации, как давно, какая статистика по отказам?

Иногда можно упростить реализацию добавлением контроля качества питания с запасом энергии на гарантированное закрытие транзакции. Не берусь утверждать, что это Ваш случай, но всё же.
Но это долгое и недешёвое удовольствие. У Вас proof of concept или реально работающий проект?

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


Сколько устройств в эксплуатации, как давно, какая статистика по отказам?

чуть больше сотни, поддержка SPI flash с нового года, пока особой статистики нет.

Можно было использовать NILFS2 или F2FS. Готовые файловы системы циклического типа. И писать на них что хочешь.

Есть в ядре Линукса.

и та, и другая работают поверх блочного устройства, а не поверх mtd.
сомневаюсь, что с микросхемой в 4мб стоит что-то хранить в файловой системе.
и циклическую запись так и так пришлось бы реализовывать самому.

А зачем было заморачиваться с крохотной микросхемой, если есть поддержка MicroSD?

так в статье же написано: чтобы перевести microsd в readonly

И проблемы бы с флэшками не было бы, если бы использовали такую ФС.

не верю. в сети достаточно много отзывов о погибших флешках, эксплуатировавшихся в режиме r/o (справедливости ради, у меня за три месяца ан примерно сотне устройств пока ни одной, но так и срок невелик)

Флэшки гибнут потому что у них нет полноценного контроллера для выравнивания износа.
ФС, типа NILFS2, сами на программном уровне решают этот вопрос.
Организуя циклическую перезапись по типу кольцевого буфера.

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

когда-то давно я делал просто линейную запись в файл на флешке (в циклической записи не было нужды из-за смешных объёмов). один-единственный preallocated файл. и они всё равно дохли пачками.


хотя говорить «дохли» неправильно.
самое частое: записываешь в файл, записываешь. после каждой записи делаешь fsync. всё отлично. но только после ребута в файле оказывается информация на какой-то момент несколько дней назад. и всё опять «работает», после ребута опять откат.
вторая, наверное, по частоте проблема: считаешь md5 флешки, перевтыкаешь, считаешь ещё раз — не сходится.
ну и банальное "флешка перестала определяться" случается тоже.


из всего этого на износ NAND похоже разве что второе. только оно и на новых флешках встречается, вы уверены, что замена файловой системы поможет? )

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

2. Даже если вы пишете очень корректно, так что не затрагиваются FAT таблицы, то всё равно переписываются аттрибуты (mtime), которые лежат на определённых секторах и сектор вылетает вместе с остальной флэшкой.

3. Поэтому и нужны ФС, которые умеют любую запись самостоятельно записывать в новое пространство.
  1. ещё раз повторю: я не переписывал данные в файле, только дозапись.
    так что хоть единственный файл, хоть 1024 разных файла — роли не играет.
  2. да, я в курсе. только вот список типичных проблем, который приводил чуть выше, наводит на мысли, что дело не в этом.

вообще у меня устойчивое ощущение, что в флешках чаще выходит из строя/глючит контроллер чем NAND

ещё раз повторю: я не переписывал данные в файле, только дозапись.
так что хоть единственный файл, хоть 1024 разных файла — роли не играет.


В таком случае вы постоянно переписывали FAT c каждой следующей дозаписью. Рецепт лечения тот же — использовать ФС приспособленную для флэш: NILFS2 или F2FS или подобную.
В таком случае вы постоянно переписывали FAT c каждой следующей дозаписью.

один-единственный preallocated файл

2. Даже если вы пишете очень корректно, так что не затрагиваются FAT таблицы, то всё равно переписываются аттрибуты (mtime), которые лежат на определённых секторах и сектор вылетает вместе с остальной флэшкой.


ещё раз повторю: я не переписывал данные в файле, только дозапись.
так что хоть единственный файл, хоть 1024 разных файла — роли не играет.


Если файл preallocated, то вы именно переписывали, а не делали дозапись.

А если файл был sparse — то ещё и FAT переписывалась при каждой дозаписи.

файл не был sparse. и да, я переписывал, но каждый сектор только по 2 раза (первый раз — заполнение нулями при создании файла, второй — запись данных).


не считая модификации mtime, такая запись ничем не отличается от последовательной записи в блочное устройство руками (и не сильно отличается от тех же flash-friendly fs, только overhead меньше)

Некровопрос: на флешке ftl при перезаписи не переносит данные в другой физический сектор?
На большинстве микросд и многих флэшках нет полноценного контроллера, который осуществляет выравнивание износа. А ftl там примерно 1 к 1.
Тогда почему это называется ftl?!
flash translation layer. Это не означает что он должен уметь делать выравнивание износа. Он ответственен только за трансляцию логических адресов в физическое адресное пространство микросхем.

речь про usb/sd? единого ответа, как я понимаю, нет, каждый производитель решает сам

А чем NILFS2/F2FS лучше/надежнее UBIFS?
NILFS2 позволяет откатиться практически на любой момент времени назад в прошлое.
И я не слышал, чтобы при внезапном отключении питания nilfs2 теряла работоспособность, в отличии от UBIFS (есть статья на Хабре о таких проблемах).
Не могли бы уточнить ссылку? А то поиск в хабре по ubifs не нашел.
Я правильно понял, что разница в том, что ubifs может «проморгать» битые данные, а nilfs2 — нет. Но откатываться на предыдущую версию без последних изменений все-равно придется?
Я думаю, разница в другом. NILFS2 если видит проблемы, то сама по себе откатывается к предыдущему снепшоту секундной давности.
Не уверен, что ей всегда можно быть благодарным за это)

Продолжая обозначенную в самом начале тему readonly SBC. Что вы думаете о материале он ещё актуален?

если воспринимать его как сборник относящейся к теме информации — да, конечно.
как инструкцию — сложно сказать, именно такую задачу (сделать из стандартного debian ro систему, которую при желании временно можно перевести в rw) я не решал.


если вопрос был про то, стоит ли переводить в ro, то стоит.

Sign up to leave a comment.

Articles