STM32 + Параллельная NAND Flash + файловая система Yaffs. Часть первая


Как часто приходится жалеть о принятых решениях. Безрассудно прожитые школьные годы, неверно выбранный ВУЗ, разгульная студенческая жизнь, переезд не в тот город, выбор параллельной NAND Flash в качестве вместилища архивных данных.
Вот казалось бы, интерфейс EMC есть, команды у флешки для записи/чтения простые, как угол дома и самое главное — дешево! Кто-то может возразить, сказав, что обычные SD-карты сегодня тоже дешевые и разъемы к ним недорогие, плюс по софту тоже все готово — тут тебе и файловая система FATFs, и примеры. Но иногда в такой разговор может вмешаться слишком «умный» программист, который скажет:
— Нет! Мы делаем промышленный прибор, который будет подвержен тряскам во время транспортировки, кривым рукам наладчиков на объекте, вибрациям в процессе работы. Никаких разъемов для критически важных узлов.
На что вы возможно ответите:
— Тогда может быть использовать память с интерфейсом SPI, там вроде как тоже давно все изведанно.
— Нет, нет! Дорого, да и чем плоха NAND'а? — очень самоуверенно возражает оппонент.
— Ну я не уверен насчет…
— Бла, бла, бла! Поверьте я знаю что предлагаю, нам нужна параллельная NAND flash.
— Ну Вы не сомневаетесь, что по софту не будет проблем?
— Кто сомневается?! Я сомневаюсь?!!!
— Ладно, ладно, дерзайте, — махнете Вы рукой.
Микросхема будет заложена в решение, и пути назад уже не будет…


Спустя пару месяцев на стол «умному» программисту ложится распаянная плата, со словами: «Ну ты это, того… Кхм! Оживи ее. И это, потом, если не затруднит, объясни наладчику, как зашить и настроить остальные 100500 плат». Думаю не лишним будет сказать, что плате стоит мощный STM32F429, с приделанной снаружи SDRAM на 30 мегабайт, так что проблем с памятью и производительностью не предвидится. А в качестве же самой флешки выбрана NAND128-A.

И тут до самой самоуверенности наконец-то доходит внимательно изучить даташит. Как оказалось, несмотря на обманчивую простоту интерфейса у параллельных NAND Flash есть нюанс. Суть в том, что с завода на всех флешках такого типа может быть определенное количество битых блоков. Так конкретно у флешки NAND128A может быть до 1024 битых блоков! Эти блоки располагаются совершенно случайным образом, но производитель любезно их пометил в области spare (что это такое и как они помечены — чуть позже). Но это слабое утешение, ибо в процессе работы будут появляться новые битые блоки. И это совершенно нормально.

Чтобы окончательно обрисовать ситуацию пару слов о решаемой задаче, для которой, собственно, и закладывалась память. Ее основное назначение хранить архивы измерений, причем архивы разные — суточные, недельные, месячные. Формат архивов произвольный, это определяет конечный пользователь (устройство свободно программируемое). Т.е. хранимую информацию нужно, как-то логически разделять и предоставлять пользователю в удобном виде. Тут как нельзя кстати пришлась бы файловая система, которая позволила оперировать архивными данными, как отдельными файлами. Вдобавок ни о каких потерях данных не может быть и речи, прибор серьезная разработка, по крайней мере так думают его разработчики.

И вот главный герой дочитал даташит, после чего взглянул на лежащую перед ним плату, потом взглянул на большую гору ее копий. Он явственно ощутил проступающие капли холодного пота на спине и чувство чего-то сжимающего, где то там внизу, ниже пояса. О чем он думал в тот момент? О веревках с мылом? О поездках в дальние страны? О, нет! Он думал о блоках и страницах, из которых состоит память.

Все 128 мегабит (да-да именно мегабит, а не мегабайт) флешки, разделены на блоки по 16 килоБайт. Каждый блок разделен на страницы по 512 байт + 16 дополнительных байт, так называемая spare область. Страница в свою очередь может быть разделена на 2 части по 256 байт (не во всех флешках). Если блок битый уже с завода, то в 6-ом байте spare области первой страницы блока будет записано значение отличное от 0xFF. Именно этим признаком и предлагает пользоваться производитель, чтобы отличать «битого от небитого», рисуя витиеватые алгоритмы у себя в документации на микросхему. Но как быть с блоками, которые потенциально испортятся в процессе работы?

Открыв тему на каком-то форуме, наш герой обнаруживает, что не одинок. Действительно умные ребята уже не раз озадачивались этой проблемой и уже давно используют алгоритмы для генерации кода Хеминга. Работает это достаточно просто, предположим у Вас есть некоторый объем данных, который нужно сохранить в NAND Flash. Эти данные делятся на куски по 512 байт и для каждого такого куска вычисляется специальное число называемое ECC (Error Correction Code) длинной 24 бита. После чего каждый такой кусок пишется в свою страницу, а рядом в области spare располагается его ECC. Если после записи окажется, что ECC, посчитанное для того что оказалось в памяти не совпадает с тем, что было посчитано для данных, то блок считается битым. Более того, если окажется что блок «умрет» в процессе работы, то ECC позволит восстановить 1 бит данных, а если окажется испорчено 2 бита, то сможет предупредить о недостоверности. Таким образом разработчик получает инструмент достоверного отслеживания битых блоков.

На словах все складно, но рассуждая чуть дальше, наш «унмый» невольно приходит к выводу, что уж больно много работы выходит. Мало того что нужно вычислять ECC, нужно ведь еще как-то индексировать данные. Казалось бы все решаемо, но сколько это займет времени и что получится в итоге? А в итоге получается какая-никакая, а файловая система. «Стоп! Зачем изобретать велосипед? Уже наверняка есть готовая файловая система!» — думает он. Но увы, Fat16/32 в чистом виде на NAND не ложатся, поговаривают, что NXFFS из NuttX должна довольно легко выдираться, у Keil есть библиотека RL-FlashFS, но она платная и не открытая… Неужели нет вариантов?

Вариант нашелся — это файловая система Yaffs. Она идет в составе некоторых дистрибутивов Linux, и активно там используется. Ее портирование заняло некоторого времени, но гораздо более вменяемого, чем написание всего «с нуля». Как и ожидалось она позволила оперировать файлами и полностью инкапсулировала в себе все тонкости работы с битыми блоками. Ее размещение требует большого объема оперативной памяти (порядка 150 килобайт), так что в схемах где нет внешней SRAM/SDRAM ее применение маловероятно. Но у нас SDRAM есть, а значит тот кто принял решение будет жить…

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

Продолжение: Часть вторая

Содержание


Часть первая
Часть вторая
Часть третья

Комментарии (68)

RSS свернуть / развернуть
Интересно!
0
А вы будете покупать лицензию или отдавать исходники всей прошивки своего устройства под GPLv2+, кстати?
+2
Исходники с самим портом я точно выложу. А сама прошивка кому нужна? Если я правильно понимаю GPLv2+ исходники нужно открывать по требованию сообщества. Если уж прям попросят, выложу.
0
Не сообщества а того, кому вы дали бинарник :)
По сути, вы не имеет права распространять бинарник без исходников. И запрещать распространять дальше тоже не имеете права.
Т.е. теоретически, вот я не покупаю у вас плату — вы мне не даёте бинарник прошивки — я не имею права требовать у вас и исходники. Но как только кто-то кто купил плату потребовал исходники — он уже имеет право и мне отдать, хотя платы у меня нет. Как-то так. Т.е. на первом уровне распространения вы можете давать не кому попало а своим клиентам, но вот уже дальше не можете остановить клиентов от раздачи всему миру.

Просто надо быть к этому готовым. Участвовал не в одном проекте где в сторону GPL-кода даже смотреть было запрещено, что бы не попасть таким образом.
+1
А как это работает в случае, если финальная программа состоит из бинарных модулей? Вот тот же yaffs у нас в составе отдельного бинаря, который отдельно зашивается. Программа в процессоре состоит из множества бинарей заливаемых в разной комбинации в зависимости от условий. Эти бинари нужно открывать все?
0
А здесь мы вступаем на зыбкую почву юриспруденции и интерпретации текстов лицензий. Сейчас общепринято считать, что если у вас есть хотя бы байт GPL-кода, то он заражает всё, даже если у вас динамическая линковка. От заражения в случае динамической линковки спасает LGPL, но код yaffs — под полной GPL.

Очень спорный вопрос — что случается если это необязательный плагин. Т.е. если есть не-GPL (например, вообще closed-source) программа и к ней МОЖЕТ БЫТЬ сделан open-source плагин с GPL-кодом, но программа работает и без плагина. Есть две точки зрения: первая — что если плагин поставляется совсем отдельно (пользователю надо самому вручуню отдельно качать по отдельной ссылке), то нарушения нет (потому что программа — не derived work от GPL-кода, работает без него, и нет совместого distribution, пользователь получает два совсем разных и как бы не связанных пакета). Вторая точка зрения, что даже тогда это нарушение лицензии, но совершает его не автор закрытой программы а сам пользователь, когда принимает решение загрузить этот плагин.

Но вот если GPL-код обязателен для работы программы (прошивки, девайса), то тут всё однозначно — не важно, отдельно оно залиается или скачивается или в составе одного файла, но это derived work всё в целом и, значит, попадает под GPL.

Ну и стандартная отмазка: IANAL (I am not a lawyer, а не то, что можно подумать в первый момент).
0
Если автор распространяет под гпл шаблон для написания плагина к закрытой программе, то ни какого нарушения нет, ничего открывать не обязан (данный код является его интеллектуальной собственностью и использует двоёное лицензирование). А вот тот, кто будет с этот код использовать — обязан гплку соблюдать, или снова таки связаться с автором для приобретения отдельной лицензии.
Отсылка к лгпл+

Пытался я в этом как-то разобраться. Нашёл несколько кейсов. Моё мнение такого: ни какого GPL, только BSD, MIT, WTFPL и подобные, или платные лицензии. Не к чему копирастию поощерять.
0
Не к чему копирастию поощерять.
Вообще-то это копилефтия. GPL такая, какая она есть, именно для борьбы с копирастией.
0
Собственно ссылки на те кейсы я не сохранял, мне хватило простого чтения (в том числе комментариев Столмена), дабы для себя сделать вывод, что гпл, таки, копирасты.
0
Антикопирасты. Что местами не сильно лучше)
0
Если шаблон от автора программы, то да, всё так как вы пишете. А вот что делать если автор X распространяет закрытую программу к которой можно писать плагины и плагин с использованием GPL-кода автора Y?

Я-то сам тоже BSD'шник :)
0
Плагин должен идти под гпл, система остаётся закрытой.
Если плагин представляет собой длл + коннектор на основе шаблона, то варианта 2. Если шаблон был под LGPL, то дллка может идти закрытой. Если шаблон был под GPL1/GPL2 то дллку обязаны открыть. Начиная с GPL3 (не помню точно, википедию смотрите), в неё включили LGPL ввиду наличия встраиваемых систем, мол привод к общему знаминателю. По факту это значит что да, дллку вы можете оставить закрытой, но только в каких-то там особых случаях, которые определяются исключительно толщиной вашего кошелька и опытностью ваших адвокатов, а ежели это обычный ПК, то вы обязаны дллку открыть. Всё что GPL3 и выше — чистая копирастия. GPL2 и ниже «не рекомендуются», потому что «новые лицензии более свободны».
0
«новые лицензии более свободны»
«Лучше принуждают к свободе», я бы сказал)
0
Воследних два выражения в кавычках, это цитаты, так что ни каких «я бы сказал» ;)
0
Я знаю, что это цитаты. И что?
0
  • avatar
  • Vga
  • 01 сентября 2017, 08:59
Вопрос дилетанта. А если в программе используется модуль (исходник) GPL и какой-то покупной модуль (исходник), лицензия которого запрещает передавать его третьим лицам (NDA)?
0
Значит от какого-то из них придется отказаться.
+1
Выбирайте — или-или. Именно по этому если разрабатываете коммерческое ПО лучше даже не подглядывать как что-то сделано в GPL-реализации. А то напишете очень похожий код — и привет, delivered work.
+1
А насколько реально доказать что в исходниках использовались модули под открытой лицензией распространения если исходники никому не передаются? Или это для случаев, когда исходники открываются, но автор запрещает их использовать в своих (или коммерческих) целях?
0
Зависит от того на сколько вы на виду. Если вы сделали 100 устройств и всё — то никто и внимания не обратит. Если вы продаёте супер-успешный DVD-плеер (аппаратный, я имею ввиду), то велики шансы, что кто-то из любопытства разломает прошивку и найдёт там, прямо по бинарному коду, доказательства, что у вас пол-прошивки — это GPL'ный mplayer (реальная история). А дальше если вы в США, то велика вероятность реального иска с помощью адвокатов EFF или другой подобной организации, помогающей авторам с копилефтом разбираться с нарушениями их прав. А если вы в России или Китае? Ну, пошумят на Реддите да тем дело и кончится.

В общем-то и D-Link и Samsung выкладывали исходники прошивок своих рутеров да телевизоров именно под таким давлением (там, конечно, линукс внутри был). А вот Sony и Nintendo использует активно куски FreeBSD и в ус не удют — напишут мелким шрифтом на последней странице руководства пользователя упоминание этого и всё. Имеют право :)
0
Или вот есть такой отечественный процессор — «Эльбрус». Тот, что настоящий, а не на базе OpenSPARC. Под него есть Linux. Но только засада — у него засекречена даже система команд (по крайней мере, была полтора года назад, может что-то изменилось, но зная всю эту комитетно-секретную публику, я сомневаюсь). Где исходники порта Linux? Нету. Более того, там есть даже OpenJDK. Портировали новосибирцы, очень толковые ребята, делали офигенный доклад на международной (!) конференции Joker об этом. Я с ними потом говорил в кулуарах. Где, говорю, исходники-то? GPL же. А они: «мы подписали НДА, исходники у заказчика — военных — все вопросы к ним».
А поставляется этот Эльбрус как «программно-аппаратный комплекс». По идее, любой, кто заказал этот комплекс в конфигурации с Java может потребовать и исходники. А потом их выложить в интернет. Но, видимо, на практике, заказывают этот комплекс те, кто никогда ничего в интернет не выложат. А если выложат то пойдут под суд за разглашение гостайны или ещё что-нибудь подобное.

К тому же, я видел мнение (повторюсь: я не юрист), что GPL вообще юридически ничтожна (термин такой) в России. И дело не в том, что она по-английски (есть официальный «нотариально заверенный» перевод), а в том что что-то там противоречит нашему гражданскому кодексу, что автоматически её аннулирует. но подробностей я не знаю и даже не поручусь, что это действительно так.
+1
Вот новосибирцы и ответили на ваш вопрос. Да, они могут вам отдать исходники, т.к. гпл, но они за это сядут, по тому и не станут. Так же и любой другой покупатель (которым то ещё надо стать). И, таки, да, сядут именно новосибирцы, потому что они, как подрядчики, нарушили гпл — они знали, что результат будет закрытым.
0
скажу вам, этот комплекс поставляется без исходников. такие дела.
0
Вы бы меня очень удивили, если бы сказали противоположное. Но спасибо за подтверждение, всегда приятно узнать, что не ошибаешься в людях (тех, кто поставляет).
0
Кажется, вот этот ответ не в ту ветку попал.
0
Порой их там (прямо в бинарнике) находят. Авторы какой-то игры для PS2 так залетели — GPL библиотеку опознали прямо в бинарнике игры и потащили в суд.
0
Это если бинарник отдавать :) А если код в процессоре, как у автора?
0
Можно и оттуда выковырять, все зависит от желания.
0
P.S. Но в целом, конечно, обычно работает правило Неуловимого Джо.
0
С точки зрения вопроса «как жить с NAND'ом?» достаточно любопытно поизучать формат данных на картах памяти для PS2. Там не без странностей (японцы, сэр), но ФС явно заточена под флеш.
0
  • avatar
  • Vga
  • 29 августа 2017, 05:23
Молодец! У меня задач таких нет, но вряд ли я бы нашёл/применил эту файловую систему. Если будет описание процесса портирования — вообще красота!
0
Keil есть библиотека, но она платная и не открытая… FATFs
читаем из документации CubeMX

Therefore FatFs license is one of the BSD-style licenses, but there is a big difference.
Because FatFs is for embedded projects, the conditions for redistributions in binary form,
such as embedded code, hex file and binary library, are not specified to increase its
usability. The documentation of the distributions need not include about FatFs and its
license document, and it may also. Of course FatFs is compatible with the projects under
GNU GPL. When redistribute it with any modification, the license can also be changed to
GNU GPL or BSD-style license
+1
Мой косяк — библиотека Keil называется RL-FlashFS. В статье я уже поправил. Она идет в составе их библиотеки RLARM, и там есть порт для работы именно с NAND Flash.
0
если можно, сравнените Yaffs & FATFs
0
Ну основное различие в том, что FATFs не натянешь на параллельную NAND Flash.
0
Натянешь. Нижний уровень надо написать с обработкой возможных ошибок (у нас благо есть куда записать «лишние данные»). Размер страницы увеличиваем с 512 до страницы нанда (сокращаем количество перезаписей).
В конце концов, флэшки (юсб-стики) чёрти сколько времени с фатом жили и ничего.
0
а совсем ничего, что в стике между нандом и усб есть контроллер, который, кроме реализации умс, как раз и занимается описанными проблемами нанда, а особо умные умеют даже в веар левелинг?..
0
Угу, контроллер в юсб-стике не стм32, и запрограммировать стм не получится так. и вообще с нанд умеют работать только специализированные контроллеры.
0
В конце концов, флэшки (юсб-стики) чёрти сколько времени с фатом жили и ничего.
Да и SD-шки, с которыми FatFs обычно юзается, работают точно так же. По сути, надо делать свой Wear-Leveling в подсовываемом FatFs драйвере.
0
Об этом и речь — FatFs предоставляет интерфейс для работы с файлами, но учетом бэдов не занимается. То есть разработчику нужно самому отслеживать битые блоки на уровне драйвера. А как это сделать? Я не совсем понимаю, может быть вы подскажете. Вот например файловая система хочет записать что-то в страницу номер 666, но это страница в блоке помеченном, как битый. В результате драйвер отдает вместо 666 страницы, страницу 777 из другого блока, и теперь при каждом чтении будет «помнить», что когда попросят 666, нужно дать 777. Так что ли?
0
Насчет FatFs не знаю, но виндовая реализация FAT, насколько я помню, сама учитывает бэд-блоки и ведет их карту. По крайней мере нортон откуда-то подтягивал карту бэдов еще до проверки дискеты.
В результате драйвер отдает вместо 666 страницы, страницу 777 из другого блока, и теперь при каждом чтении будет «помнить», что когда попросят 666, нужно дать 777.
Флешки как-то так внутри и делают. И тебе придется, но не столько из-за бэдов, сколько из-за необходимости реализовать wear leveling.
В целом, конечно, удобнее заюзать изначально спроектированную под флэш файловую систему.
0
Ну вот собственно к этому я и пытался подвести. Альтернатив в плане готовых либ нет.
0
Есть еще как минимум JFFS, JFFS2, LogFS, UBIFS.
0
Кстати, да. Но правда с ними та же история что и с Yaffs.
0
Один из костылей — чекдиск при обнаружении битых секторов помечает их в специальный список (такой же файл, просто состоящий из битых секторов).
Другой костыль — контроллер жёсткого диска имеет описанную карту переадресаций. она сохранена на том же диске в сервисных секторах, с набором других пустых секторов для подмены. Собственно когда жесткие диски переразмечают, чтобы получить больше мамяти — открывают этот резерв (или чтобы убитый напрочь диск большего объёма выдать за нормальный, пусть и меньшего).
Второй подход оказывается более практичным. В нанд резервируем место под сервисные задачи (прошивка контроллера, таблица перенаправлений, запасные сектора для подмены), а системе говорим что у нас не 128Мбит, а 15МБ. Система думает, что работает с линейным пространством, а на самом деле контроллер выполняет всю черновую работу.
0
Вопрос только, зачем все это делать, если нет необходимости в обратной совместимости. Где подобные костыли — там однажды вылезут и leaky abstractions.
В смысле изначального посыла — теоретически натянуть FatFs можно, конечно, можно даже без всех этих манипуляций. Но практически — «there is no tsukihime anime».
0
А как быть, если блок с сервисными данными помрет?
0
Флешки не опознающиеся видел?)
+2
Прошивка перезаписывается крайне редко, износ ей не грозит. Утекание заряда может быть проблемой, так что бутлодырь, контрольные суммы и дублирование. Остальное Vga уже написал.
0
Хрен бы там, слет прошивки с NAND'а — явление распространенное. Этому способствует как write-disturbance, так и такое прелестное явление, как порча NAND-памяти при многократном чтении. Плюс ограниченное время хранения данных (современные SSD могут потерять данные за 3-6 месяцев без питания).
С кондовой памятью из топика такие сюрпризы врядли грозят, но обычно на NAND'е прошивку хранят девайсы, где эта память юзается для контента (всякие медиаплееры и иже с ними), и, соответственно, стоят чипы высокой емкости.
0
Интересно, сам задавался этим вопросом. Автор, пиши еще)
0
Неужели какая-нибудь 25Q128 на 16 мегабайт намного дороже чем NAND на тот же объем?
0
А там не примерно то же самое внутри, только с другим интерфейсом и без места под данные WL? Сектора при записи и там дохнуть будут.
0
Я не встречал случаев, чтобы при эксплуатации флеш-памяти 25Qхх дохли отдельные сектора. Обычно дохнет вся флешка.
0
А она при этом на запись использовалась?
0
Это NOR флеш, там своя атмосфера.
0
Вроде дохнуть при перезаписи свойственно любому флешу, не? Насколько я помню, NAND и NOR отличаются только соединением ячеек в массив, первый компактнее, второй лучше дружит с рандомным чтением.
0
у NOR гарантированный ресурс больше гораздо. Зато nand гораздо дешевле в расчёте на одну ячейку.
0
Логично, но, по идее, при достаточно долгой эксплуатации и активной записи и в NOR'е будут вылетать ячейки?
0
Будут, но через довольно продолжительный срок.
0
никаких разъёмов говорите? А для кого по вашему делали emmc? чип на пару гигабайт стоит около 5 баксов за 1000.

Ну да это так — лирика. NAND не так страшен как кажется, spare область — означает всего лишь некоторое количество байт за страницей. ECC можно и не использовать, если особо смелый. ONFI спеку скурить можно за неделю и за неделю же написать минимальный драйвер для работы с nand.

В принципе можно обойтись и без ФС, если писать данные как в кольцевой буфер, тогда и wear-leveling делать особо не надо.

Главное чтобы микруха была slc. mlc, или того хуже tlc имеют отличные приколы с write-disturbance на соседние блоки на соседних plane. Вот там начинается задница.
0
eMMC тоже рабочий вариант, согласен. А они есть не в BGA?
0
помнится вроде в tssop-48 видел
0
А нет, память меня подводит.
0
Тогда это может быть проблемой, сами понимаете ))
0
Те что я видел, вполне паяются феном и твёрдой рукой. А если в серии — пофигу, паяют роботы. Но в общем и целом согласен, головняка добавляет.
0
А будет ли это интересно посмотрю по интересу к этой статье.
Конкретно этот пост не интересен (и на тематический не тянет), а вот продолжение — другой вопрос.
0
… после чего взглянул на лежащую перед ним плату, потом взглянул на большую гору ее копий. Он явственно ощутил проступающие капли холодного пота на спине и чувство чего-то сжимающего, где то там внизу, ниже пояса. О чем он думал в тот момент? О веревках с мылом? О поездках в дальние страны? О, нет!

:)
Шекспир и племянники отдыхают!
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.