Перейти к содержанию

ECC флеш-памяти

Ячейка флеш-памяти со временем может потерять заряд, и один бит прошивки или данных перевернётся. В STM32G4, L4 и H7 каждое слово флеш-памяти хранится вместе с кодом коррекции ошибок: одиночную ошибку контроллер исправляет сам и сообщает о ней, двойную — обнаруживает.

Обновлено Редакция GAW

ECC флеш-памяти (error correction code) — избыточные контрольные биты, которые контроллер флеш-памяти записывает вместе с каждым словом данных и проверяет при чтении. У STM32G4 и STM32L4 на каждые 64 бита данных приходится 8 бит ECC (RM0440, разд. 3.3.1), у STM32H743 — 10 бит на 256-битное слово (RM0433, с. 148). Схема исправляет одну ошибку в слове и обнаруживает две — это SECDED, single error correction, double error detection.

Почему так устроено

Код вида SECDED — расширенный код Хэмминга: k проверочных бит позволяют найти позицию одной ошибки среди 2^k − 1 позиций, а ещё один бит общей чётности отличает одиночную ошибку от двойной. Наш расчёт: для 64 бит данных достаточно 7 + 1 = 8 бит, для 256 бит — 9 + 1 = 10 бит, что совпадает с числами ST. Точный код ST в руководствах не приводит.

Следствие для программиста — запись только целыми словами. У STM32G4 флеш-память программируется по 72 бита, 64 бита данных и 8 бит ECC, и записать можно только двойное слово; попытка записать байт или полуслово даёт ошибку SIZERR, невыровненный адрес — PGAERR (RM0440). У STM32H7 слово 256 бит, а запись меньшей порции идёт через принудительную запись всего слова (RM0433, разд. 4.3.4). Повторно писать в уже записанное слово нельзя: код ECC не совпадёт.

Флаги ошибок

Результат проверки STM32G4 сообщает в регистре FLASH_ECCR. Поля и биты — по заголовку stm32g474xx.h, назначение — по их названиям:

ПолеБитНазначение
ECCC30исправленная одиночная ошибка
ECCD31обнаруженная двойная ошибка
ECCC2, ECCD228, 29вторая пара флагов исправления и обнаружения (подробности — в RM0440)
ECCIE24разрешение прерывания по исправленной ошибке
SYSF_ECC22ошибка в системной памяти
BK_ECC21номер банка
ADDR_ECC18:0адрес слова с ошибкой

Как STM32G4 сообщает об ошибках, ST описывает в обучающей презентации по флеш-памяти серии (слайды 4, 10 и 26). Одиночную ошибку контроллер исправляет сам и ставит флаг ECCC; прерывание при этом формируется, если оно разрешено (по заголовку — битом ECCIE). Двойная ошибка ставит флаг ECCD и вызывает NMI: запретить это прерывание нельзя, и обработчик NMI должен проверить FLASH_ECCR, а не только флаг системы контроля тактирования. У других серий механизм может отличаться — проверяйте свой RM. Исправленная ошибка — сигнал, что ячейка слабеет: данные прочитаны верно, но их стоит переписать в другое место. Двойная ошибка означает, что слово испорчено. Наш вывод: если NMI_Handler оставить пустым бесконечным циклом, двойная ошибка ECC будет выглядеть как зависание, а отказ внутри самого обработчика NMI уводит ядро в lockup, как и при HardFault. Как устроены банки флеш-памяти, в которых работает ECC, — в статье «Двухбанковая флеш-память», запись и защита флеш-памяти — в статье «Flash-память и загрузчик STM32».

Частые вопросы

Почему у STM32G4 и L4 нельзя дописать байт во флеш-память?

Потому что код ECC считается сразу на 64 бита. RM0440 прямо говорит, что программировать можно только двойное слово: 64 бита данных и 8 бит ECC за раз, а попытка записать байт или полуслово ставит ошибку SIZERR. Для журналов и эмуляции EEPROM данные собирают в 8-байтовые записи.

Что делать, если установлен флаг ECCD?

ECCD означает двойную ошибку, которую исправить нельзя: прочитанное слово неверно. У STM32G4 такая ошибка вызывает немаскируемое прерывание, поэтому разбирать её приходится в NMI_Handler (презентация ST по флеш-памяти STM32G4, слайды 10 и 26). Адрес слова программа берёт из поля ADDR_ECC регистра FLASH_ECCR, банк — из BK_ECC. Наша рекомендация: считать данные по этому адресу испорченными, восстановить их из копии или запросить обновление, а при повторении проверять питание и число циклов стирания.

Это то же самое, что код Хэмминга?

По принципу да: схема «исправить одну ошибку, обнаружить две» (SECDED) — это расширенный код Хэмминга. Наш расчёт для проверки: на 64 бита данных нужно 7 проверочных бит Хэмминга плюс бит общей чётности — ровно 8, как у STM32G4; на 256 бит — 9 + 1 = 10, как у STM32H7. Сам код ST не публикует.

Источники

  1. STMicroelectronics. RM0440 Reference manual STM32G4 Series (Rev 9) — разд. 3.3.1: в двухбанковом режиме чтение 72 бита — 64 бита данных и 8 бит ECC; в однобанковом — 144 бита, 128 бит данных и 2 × 8 бит ECC; программирование: флеш-память пишется по 72 бита (64 + 8 ECC), записать можно только двойное слово, попытка записать байт или полуслово ставит SIZERR, невыровненный адрес — PGAERR
  2. STMicroelectronics. RM0433 Reference manual STM32H742, STM32H743/753 and STM32H750 (Rev 9) — с. 148: ECC — исправление одной ошибки или обнаружение двух на 256-битное слово флеш-памяти с 10 битами ECC; разд. 4.3.4: строки по 256 бит + 10 бит ECC; в память записываются только 256-битные слова, запись меньших порций идёт через принудительную запись слова целиком с ECC (FW1/FW2), перезаписывать не стёртое слово не рекомендуется
  3. STMicroelectronics. CMSIS device header stm32g474xx.h, cmsis-device-g4 (GitHub, Apache-2.0) — регистр FLASH_ECCR по смещению 0x18: ADDR_ECC[18:0] (маска 0x0007FFFF), BK_ECC (бит 21), SYSF_ECC (бит 22), ECCIE (бит 24), ECCC2 (бит 28), ECCD2 (бит 29), ECCC (бит 30), ECCD (бит 31)
  4. STMicroelectronics. STM32G4 — Memory Flash (FLASH), обучающая презентация ST (японская версия на STMCU.jp) — слайд 4: ECC — 8 бит на 64-битное двойное слово; одиночная ошибка обнаруживается и исправляется, сообщение маскируемым прерыванием; двойная ошибка обнаруживается и сообщается через NMI ядру Cortex-M4; слайд 10: при исправлении ставится флаг ECCC в FLASH_ECCR и может формироваться прерывание, при двойной ошибке — флаг ECCD и NMI, адрес ошибки сохраняется в FLASH_ECCR; слайд 26: одиночная ошибка может вызвать прерывание, двойная вызывает NMI

Нашли ошибку?