Search
Write a publication
Pull to refresh

Comments 11

Как алгоритмически организовать NVRAM при условии одноразовой записи страниц Flash?

Когда микроконтроллер не позволяет до-записать уже прописанную страницу flash памяти.

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

Стирать flash можно , но только секторами по 8к byte. А записывать страницами по 128 байт.

Если переменных немного, и место экономить не нужно, то можно сделать минимальный размер переменной в 128 байт, и писать именно с такой грануляцией. Тогда получается, что нам нужно научиться отличать "валидные" переменные от "устаревших", для этого подойдет банальный счетчик "поколений", т.е. функция GetVariable внутри себя проходит по всем записям на флеше, и возвращает значение той, у которой счетчик больше. SetVariable делает то же самое, только пишет в свободное место новую запись с инкрементированным счетчиком. Чтобы не ловить переполнения, счетчик можно сделать 2 или даже 4-байтным.

Как только хранилище заполнилось - стереть все, что сейчас "устарело" по 8 кб за раз, и перенести все оставшееся в начало, сбросив счетчики. Там будет еще проблема небольшая с Fault Tolerant Write, но она решается выделением одного 8кб блока и переносом данных через него.

Вообще хотелось бы ещё как- то утрамбовывать файлы nvram. Есть же записи и в 1 байт , а есть в 512 байт и более. На всю nvram только 256к байт.

Ограничения слишком неприятные получаются, если упаковывать плотнее. По факту у нас запись блоками по 128 байт, и в старые блоки нельзя писать, так что для данных, которые надо обновить, у нас по факту ровно одно место, куда можно писать их - следующий свободный 128-байтовый блок. А дальше там любая переменная размером от 1 до 126 (пусть будет счетчик поколений в 2 байта, для ровного счета) - это одна запись блок. Можно попробовать каждый раз при записи решать задачу о рюкзаке, и пытаться впихнуть сколько-то уже существующих переменных (бампнуть им поколение тоже) в один блок вместе с новой, но может быть медленно и печально (сложность нормального решения такой задачи - почти квадратичная, а у нас МК слабый). В общем, можно разменять производительность на более плотную упаковку, либо нахер выкинуть такой флеш и поставить нормальный SPI/I2C NOR и пошло оно все это в жопу.

А вообще, если еще немного подумать, никакого толку от решения задачи о рюкзаке не будет, если не "накапливать" где-то в ОЗУ несколько вызовов SetVariable перед тем, как на флеш писать. Если писать по одной переменной за раз - никакими оптимизациями там ничего не сделать, потому что мы за один раз в любом случае инвалидируем (т.е. раньше туда можно было писать, теперь - нет) один блок в 128 байт, и потому ничего там меньше все равно сэкономить не выйдет.

Если немного раскрыть идею про "накапливать", можно сделать атрибут для SetVariable вроде "переменная не очень важная, можно кэшировать, если 0, писать разу на флеш, если 1", и в зависимости от него в кэше делать упаковку тех, кому не срочно (т.е. "ждем пока накопится 128 байт изменений, сливаем всех в один блок"), и писать сразу в целый блок тех, кому срочно.

Получится не очень плотно, если срочных будет много, но тут я не вижу вариантов.

И ещё . Запись возможна только блоками по 128 байт по выравненному адресу.

Любопытно - насколько вероятна ситуация утери консистентности всей прошивки в процессе фиксации изменения настроек?

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

ЕМНИП всё завертелось, когда кому-то пришла в голову генитальная идея сэкономить копеечный чип NVRAM и хранить настройки в том же чипе, что и основной чип биос, ведь внезапно он стал избыточно большим - вай нот.

Sign up to leave a comment.

Articles