Небольшая заметка о том, как сохранить параметры при работе с контроллерами STM32.
Часто бывает нужно сохранить небольшие значения в памяти (флаги и т.п.), чтобы можно было использовать в дальнейшем. Например, можно сделать независимый счетчик запусков контроллера или счетчик зависаний.
Памяти FLASH много, но в STM32 она разбита на страницы (pages), и если нужно перезаписать 1 байт на этой странице, нужно стереть ее всю. Так как же сохранить наши флаги или счетчик?
Часто последние страницы выделяют под такую задачу. И периодически перезаписывают ее или еще что-то делают с ней.
Я расскажу как можно сохранить 2 байта в памяти. Для этого я буду использовать область называемую User Option Bytes, тут располагаются флаги о запрете на чтение прошивки, запись в страницы, настройки резета и сторожевого таймера, а также есть 2 байта для пользовательских данных.
Для доступа к ним есть структура OB:
1 2 3 4 5 6 7 8 9 10 11 |
typedef struct { __IO uint16_t RDP; __IO uint16_t USER; __IO uint16_t Data0; __IO uint16_t Data1; __IO uint16_t WRP0; __IO uint16_t WRP1; __IO uint16_t WRP2; __IO uint16_t WRP3; } OB_TypeDef; |
В коде доступ к этим двум байтам так:
1 2 |
x = OB->Data0; y = OB->Data1; |
Но это чтение данных, тут все просто. А вот записать новое значение – это та же процедура, что и для обычной области, за исключением размера этой области. Функция записи нового значения может выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
uint16_t y[6]; // сохраняем настройки y[0] = OB->USER; y[1] = OB->WRP0; y[2] = OB->WRP1; y[3] = OB->WRP2; y[4] = OB->WRP3; y[5] = OB->Data2; //Запись // разблокировка флеша FLASH_Unlock(); // стираем Option Bytes FLASH_EraseOptionBytes(); // запись данных 0xAA в Data0 FLASH_ProgramOptionByteData(0x1FFFF804, 0xAA); FLASH_ProgramOptionByteData(0x1FFFF806, y[5]); FLASH_ProgramOptionByteData(0x1FFFF802, y[0]); FLASH_ProgramOptionByteData(0x1FFFF808, y[1]); FLASH_ProgramOptionByteData(0x1FFFF80A, y[2]); FLASH_ProgramOptionByteData(0x1FFFF80C, y[3]); FLASH_ProgramOptionByteData(0x1FFFF80E, y[4]); // блокируем флеш FLASH_Lock(); |
Смысл в том, что сохраняем во FLASH лишь маленький объем, а не всю страницу.
Проблем, думаю, возникнуть не должно, но если есть вопросы, пишите.
Почему не перезаписываем значение RDP (0x1FFFF800) ?