lift_indicator_suite/bsp/boot_state
2026-07-13 16:47:47 +03:00
..
include/bsp # bootloader: Phase 4 - preparing 2026-07-13 16:47:47 +03:00
src # bootloader: Phase 4 - preparing 2026-07-13 16:47:47 +03:00
CMakeLists.txt # bootloader: Phase 4 - preparing 2026-07-13 16:47:47 +03:00
README.md # bootloader: Phase 4 - preparing 2026-07-13 16:47:47 +03:00

bsp_boot_state — счётчик попыток загрузки (SRC_GPR)

Счётчик попыток загрузки поверх SRC General Purpose Register — переживает тёплый/watchdog-сброс, обнуляется только на POR. Даёт коду восстановления прожить несколько сбросов подряд без персистентного хранилища во flash.


Аппаратура

Параметр Значение
Периферия SRC (System Reset Controller)
Регистр счётчика SRC_GPR[2] (GPR3, 0-based индекс fsl_src API)
Переживает тёплый сброс, watchdog-сброс
Обнуляется только POR (детект — SRC->SRSR, бит IPP_RESET_B)
Занято ROM (не трогать) GPR1/2 (warm-boot entry/arg), GPR6/7/8/9 (ROM, explicit note в RM), GPR10 (альт. SBMR1)
Не занято ROM, но занято конвенцией GPR5 — RM рекомендует под различение SYSRESETREQ/CPU lockup, не наша задача

Контракт: разделение с bsp_wdog

SRC->SRSR и WDOG1->WRSR — разные регистры с разной семантикой очистки. WRSR самоочищается на каждый сброс (не требует явной очистки — см. bsp_wdog_caused_last_reset()). SRSR — write-1-to-clear и копит биты между тёплыми сбросами, если их не чистить софтом: bsp_boot_state_init() чистит SRSR при каждом вызове, поэтому вопрос «был ли сброс по watchdog» остаётся за bsp_wdog, а не за этим модулем — этот модуль отвечает только за «был ли сброс POR».


API

void     bsp_boot_state_init(void);       /* взвести — читает/чистит SRC->SRSR, детектит POR */
bool     bsp_boot_state_was_por(void);    /* true, если последний сброс — POR */
uint32_t bsp_boot_attempt_count(void);    /* текущее значение счётчика, 0 сразу после POR */
void     bsp_boot_attempt_inc(void);      /* +1 — звать перед попыткой прыжка в образ */
void     bsp_boot_attempt_reset(void);    /* обнулить — новый образ/фолбэк-стирание */
void     bsp_boot_health_mark(void);      /* = bsp_boot_attempt_reset(), для вызова из приложения */

bsp_boot_state_init() не идемпотентна — повторный вызов в той же сессии увидит уже очищенный SRSR как «не POR». Звать ровно один раз, как можно раньше в main().


Быстрый старт

#include "bsp/boot_state.h"

/* main.c — после board_hw_init()/bsp_wdog_init(): */
bsp_boot_state_init();

if (bsp_boot_attempt_count() >= THRESHOLD)
{
    /* серия сбросов подряд без здорового образа — решение о фолбэке/recovery
     * принимает вызывающий код, не этот модуль */
}

bsp_boot_attempt_inc();   /* перед каждой попыткой прыжка */
/* ... */
bsp_boot_health_mark();   /* приложение подтвердило собственное здоровье */

CMake

target_link_libraries(firmware_bootloader PRIVATE bsp_boot_state)

Зависимости модуля:

Зависимость Тип Описание
sdk_src PRIVATE fsl_src.hSRC_Get/SetGeneralPurposeRegister, SRC_Get/ClearResetStatusFlags