Практическое применение двухзонной флеш-памяти MSPM0L1117: Стратегия разделения на 128 КБ и руководство по избежанию типичных ошибок при OTA-обновлении

STY TECHNOLOGY LIMITED 41

Ваше обновление по протоколу OTA снова привело к «кирпичу»? 128 КБ флеш‑памяти вроде бы достаточно, но при разбиении на разделы возникают сплошные подводные камни — загрузчик занимает пространство приложений, при отключении питания теряется прошивка, отсутствует механизм отката. Двухзонная архитектура флеш‑памяти MSPM0L1117 изначально создана для надежного OTA‑обновления, однако официальное руководство никогда не объясняет: как оптимально разбить память объемом 128 КБ? В данной статье, основываясь на реальных проектах серийного производства, мы разбираем底层 логику переключения банков A/B и предлагаем практическое решение по разделению и отказоустойчивую схему обновления.

Разбор двухзонной архитектуры флеш‑памяти MSPM0L1117

Карта флеш‑памяти MSPM0L1117 Банк A (нижние 64 КБ) 0x0000_0000 - 0x0000_FFFF Код / данные приложения Область конфигурации (общая) Зарезервировано / загрузчик Банк B (верхние 64 КБ) 0x0001_0000 - 0x0001_FFFF Код приложения / Данные Область конфигурации (общая) Загрузчик (фиксированный) Смена банков

Флеш-память MSPM0L1117 объёмом 128 КБ реализована по физической двухбанковой архитектуре: банки A и B являются зеркальными копиями друг друга и поддерживают аппаратное переназначение адресов. Основное преимущество такой архитектуры заключается в том, что во время обновления не требуется прерывать работу текущего исполняемого ПО, что позволяет действительно выполнять обновление «на ходу».

Физическое отображение и механизмы защиты банков A/B объёмом 128 КБ

Физическое адресное пространство с двумя банками охватывает диапазон от 0x0000_0000 до 0x0001_FFFF; банк A固定 занимает нижние 64 КБ (0x0000_0000–0x0000_FFFF), а банк B — верхние 64 КБ (0x0001_0000–0x0001_FFFF). Бит BANK_SWAP в ключевом регистре FLASH_CONF управляет переключением видимого пространства памяти; после переключения адрес 0, который видит процессор, фактически указывает на другой физический банк.

Механизмы защиты разделены на три уровня: защита записи/стирания на уровне секторов (32 сектора × 4 КБ), блокировка только для чтения на уровне банка и глобальное отключение отладочного порта. При массовом производстве рекомендуется активировать блокировку BSL (уровень безопасности загрузчика), чтобы предотвратить несанкционированное чтение пакетов обновления.

Возможности RWW и безопасное окно прерываний

Функция чтения во время записи позволяет процессору выполнять код из банка A и одновременно записывать новую прошивку в банк B. Однако существуют ключевые ограничения: в пределах одного банка нельзя одновременно читать и записывать, а операция стирания блокирует все обращения к этому банку примерно на 20 мс. Обработчики прерываний должны размещаться в текущем работающем банке; в противном случае возникнет ошибка шины.

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

Стратегия разделения на 128 КБ: оптимальное решение для трех типов сценариев

Разделение — первый и решающий этап успешности OTA-обновлений. Хотя 128 КБ кажутся достаточным объемом, после вычета пространства для загрузчика, конфигурационного раздела и журнала доступное приложению пространство часто сокращается менее чем до 50%.

Симметричная двухзонная схема (60 КБ + 60 КБ): стандартные сценарии OTA

Загрузчик размером 8 КБ фиксируется в верхней части флеш‑памяти (0x0001_F000–0x0001_FFFF), оставшиеся 120 КБ делятся поровну. Каждый раздел по 60 КБ предназначен для размещения кода приложения и данных, а общий раздел конфигурации размером 8 КБ хранит номер версии, флаги обновления и счётчик отката. Этот вариант подходит для сценариев с объёмом приложения до 45 КБ и необходимостью частых полных обновлений.

РегионДиапазон адресовРазмерОписание
Банк A0x0000_0000–0x0000_EFFF60 КБРабочая область или целевая область обновления
Банк B0x0001_0000-0x0001_EFFF60 КБРабочая область или целевая область обновления
Область конфигурации0x0000_F000-0x0000_F7FF2 КБОбщая для двух банков, защита от потери питания
Загрузчик0x0001_F000-0x0001_FFFF4 КБНевозможно обновить, аппаратная блокировка

Асимметричная схема разделения (48 КБ + 80 КБ): крупное приложение + упрощённый загрузчик

Когда объём приложения превышает 55 КБ, симметричная схема оказывается недостаточной. Банк A сжимается до 48 КБ и используется как резервная зона «золотого прошивки», а банк B расширяется до 80 КБ для размещения основного приложения. Загрузчик упрощается до 4 КБ, оставляя только функции связи, проверки и переключения; обновление приложения осуществляется посредством дифференциальных пакетов.

Этот подход жертвует гибкостью отката — возможности старой версии в банке A ограничены, но взамен пространство основного приложения увеличивается на 33%. Подходит для потребительских продуктов с быстрыми итерациями функций и большими единовременными изменениями.

Проектирование канала обновления OTA и реализация конечного автомата

Надёжный OTA — это не просто «скачать и перезагрузиться»; требуется конечный автомат и восстановление после ошибок, охватывающие весь процесс.

Трехэтапный конечный автомат: загрузка — проверка — переключение

Определение состояний: IDLE→DOWNLOADING→VERIFYING→READY→SWAPPING→COMMITTED; при тайм‑ауте или ошибке на любом этапе происходит переход в режим RECOVERY. Ключевой дизайн: перед каждым переходом состояния записывается флаг в область конфигурации, а после перезагрузки при отключении питания этот флаг считывается для восстановления контекста.

На этапе проверки применяется двойная защита: CRC‑32 плюс цифровая подпись: на уровне транспорта CRC обнаруживает битовые ошибки, а RSA‑1024 или HMAC‑SHA256 проверяют легитимность источника прошивки. Встроенный генератор истинно случайных чисел TRNG микроконтроллера MSPM0L1117 обеспечивает источник энтропии для производных ключей.

Защита от потерь данных при отключении питания и механизм восстановления после прерывания записи

Естественное преимущество двухбанковой архитектуры: во время обновления запись производится в неактивный банк, поэтому при любом отключении питания после перезагрузки система продолжит загрузку из исходного банка. Единственное окно риска — первые 100 мкс после записи бита BANK_SWAP; в это время необходимо использовать внешнюю FRAM или EEPROM для сохранения флага «переключение инициировано».

Для восстановления после прерывания используется стратегия «двойной флаг + серийный номер»: в области конфигурации поддерживаются current_seq и target_seq; равенство этих значений означает стабильное состояние, а неравенство — процесс переключения. После завершения переключения при первом запуске нового банка требуется явная коммит‑операция; в противном случае при следующем перезапуске произойдет автоматическое откатывание.

Структура двойного номера версии и атомарный флаг переключения

Номер версии реализован как 64‑битное значение: старшие 32 бита — основная версия (семантическая), младшие 32 бита — временная метка сборки. В области конфигурации одновременно хранятся active_version и pending_version; при переключении обновляется только pending_version, а после успешного запуска новой прошивки выполняется атомарный коммит — pending копируется в active; весь процесс не может быть прерван.

Логика проверки некорректной прошивки и автоматического отката

После загрузки нового банка микропрограмма переходит в «пробный период»: в течение окна превышения времени ожидания сторожевого таймера необходимо завершить самотестирование и отправить сигнал heartbeat по коммуникации. Если сигнал не отправлен вовремя или самотестирование завершилось неудачно, загрузчик сбрасывает флаг переключения, и при следующем холодном запуске система принудительно вернется к исходному банку. Эта мера предотвращает переход в состояние «кирпича», локализуя сбой в рамках одного цикла загрузки.

Избежание проблем на практике: пять наиболее частых ошибок при диагностике

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

Превышение времени стирания и конфликт со сторожевым таймером

Типичное время стирания сектора размером 4 КБ составляет 15–25 мс; если период сторожевого таймера установлен на 20 мс, во время стирания может произойти сброс системы из‑за неактивного обновления таймера. Решение: временно увеличьте интервал сторожевого таймера до 100 мс перед началом стирания или используйте интервальный режим «стирай небольшой участок — обновляй таймер». Более оптимальный подход — разбить задачу стирания на этапы и выполнять её через хук свободного времени RTOS.

Балансировка ресурса флеш‑памяти и учёт износа

Номинальный ресурс Flash микроконтроллера MSPM0L1117 составляет 100 тыс. циклов стирания и записи, однако частое обновление конфигурационной области становится узким местом. По результатам измерений: при каждом обновлении запись в конфигурационную область выполняется около 20 раз, и тысяча обновлений уже потребляет 20% срока службы. Решение: применить алгоритм балансировки износа для конфигурационной области с двойным резервированием и поочередной записью; либо подключить внешнюю EEPROM по интерфейсу I²C для хранения данных высокочастотных обновлений.

Контрольный список проверки и запуска в массовое производство

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

Граничное тестирование: заполнение памяти до полной емкости и моделирование аварийного отключения питания

Тестовый пункт первый: заполнить банк до 100% емкости (каждый байт не должен быть равен 0xFF), проверить, что операции стирания, записи и проверки проходят успешно. Тестовый пункт второй: с помощью программируемого источника питания смоделировать случайные отключения питания на четырех этапах — включение, работа, стирание и переключение, по 1000 циклов каждого типа, и подсчитать процент успешного запуска. Цель: коэффициент восстановления после аварийного отключения ≥ 99,9%.

Процесс прошивки на производственной линии и развертывания начальной версии

При первой прошивке на производственной линии необходимо одновременно записать загрузчик, начальную прошивку банка A и флаг «Банк A активен». Банк B должен оставаться в стертом состоянии (полные нули 0xFF); при обнаружении загрузчиком активности одного банка он автоматически синхронизирует образ, обеспечивая изначально двузонную резервную емкость.

Ключевые выводы

  • Двузонная флеш‑память MSPM0L1117Емкость 128 КБ требует тщательного планирования: симметричное решение (60+60 КБ) подходит для стандартных приложений, ассиметричное решение (48+80 КБ) предназначено для сценариев дифференциальных обновлений больших приложений
  • Автоматический контроллер состояний должен охватывать весь путь от DOWNLOADING до COMMITTED; на каждом этапе перехода фиксируется соответствующий флаг, что позволяет восстановить контекст после сбоя питания
  • Управление версиями реализовано по схеме двух зон и двух серийных номеров; после успешного тестового запуска новой прошивки выполняется атомарная коммитация, исключающая риск превращения устройства в «кирпич»
  • Конфликт между сторожевым таймером и временными диаграммами стирания является скрытым убийцей в массовом производстве; необходимо предусмотреть запас прочности не менее 3× или использовать стратегию периодического обновления сторожевого таймера.
  • Неравномерный износ зоны конфигурации нельзя игнорировать: при тысячах циклов обновления достигается предел ресурса флеш‑памяти, поэтому рекомендуется подключить внешнюю EEPROM для распределения нагрузки.

Часто задаваемые вопросы

Поддерживает ли 128 КБ двухзонная флеш‑память MSPM0L1117 одновременную работу версий A и B?

Нет. Работа двух банков взаимно исключительна: в каждый момент времени только один банк отображается по адресу 0. Термин «двухзонная» относится к избыточному хранению данных, а не к параллельному выполнению. Переключение версий должно осуществляться с помощью аппаратного бита BANK_SWAP, что сопровождается перезагрузкой системы и восстановлением контекста.

Как обрабатывать прерывание связи во время обновления OTA?

Прерывание на этапе загрузки: после срабатывания таймера тайм‑аута флаг сбрасывается, а полученные данные сохраняются для продолжения передачи или полной повторной загрузки. Прерывание на этапе проверки: если данные получены полностью, локальная проверка продолжается; в противном случае возвращается состояние загрузки. Прерывание на этапе переключения: наиболее опасный случай; требуется использование атомарного флага в конфигурационной области. После перезагрузки загрузчик определяет, завершено ли переключение; если нет, сохраняется исходный банк.

MSPM0L1117SRHBRМожет ли загрузчик обновляться сам по себе?

Аппаратная блокировка официальной области BSL не позволяет выполнять обновление на месте, но пользовательский загрузчик можно разместить в стираемой области. Рекомендуется закрепить 4 КБ ядра загрузчика в области BSL, а сложную обработку протокола перенести в пользовательскую область; расширение функциональности можно реализовать с помощью таблицы переходов, избегая обращения к защищенным областям.

Как убедиться, что новая прошивка не приведет к «кирпичу» до начала переключения?

Использование свойства RWW: после записи нового прошивки в банк B можно вычислить CRC команд по адресу входной точки и сравнить его с ожидаемым значением. Более надежный подход — встроить в банк B «минимальный самотестовый образ» — чисто вычислительный код, не зависящий от периферийных устройств; загрузчик переключается на его выполнение для проверки, а затем выполняет официальное переключение.

Является ли дифференциальная обновление лучше полного при объеме 128 КБ?

Размер дифференциального пакета обычно снижается до 15–30% от полного, но в флеш‑памяти необходимо сохранять старую версию в качестве базовой. В сценарии 128 КБ, при использовании симметричного разделения, базовая версия и дифференциальный вывод должны размещаться в одном банке, поэтому реальная экономия ограничена. В асимметричном варианте банк A фиксируется как базовый, а банк B принимает дифференциальный вывод; в этом случае выигрыш заметен, рекомендуется использовать вместе с алгоритмами bsdiff или MTF.