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, назначение — по их названиям:
| Поле | Бит | Назначение |
|---|---|---|
| ECCC | 30 | исправленная одиночная ошибка |
| ECCD | 31 | обнаруженная двойная ошибка |
| ECCC2, ECCD2 | 28, 29 | вторая пара флагов исправления и обнаружения (подробности — в RM0440) |
| ECCIE | 24 | разрешение прерывания по исправленной ошибке |
| SYSF_ECC | 22 | ошибка в системной памяти |
| BK_ECC | 21 | номер банка |
| ADDR_ECC | 18: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 не публикует.
Источники
- 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
- 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), перезаписывать не стёртое слово не рекомендуется
- 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)
- 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
Нашли ошибку?
Смотрите также
- Код ХэммингаКодирование, синдром, исправление ошибки, SECDED
- Бит чётностиParity: контроль чётности символа UART, even и odd
- Двухбанковая флеш-память (dual bank)Флеш-память из двух банков: чтение во время записи и обмен банков
- Flash и загрузчик STM32Страницы и секторы, BOOT0, системный загрузчик, AN3155, IAP, option bytes, RDP
- HardFaultИсключение Cortex-M при необработанной ошибке
- NMI (немаскируемое прерывание)Исключение Cortex-M с приоритетом −2, которое нельзя запретить
- NAND-флеш-памятьСтраницы и блоки NAND, плохие блоки, ECC и чем NAND отличается от NOR