/****************************************************************************** * @file app_defer.h * @brief ISR→任务上下文的延后执行标志位(统一收口 2026-08-31 复位事故教训) * @author cyWu <1917507415@qq.com> * @date 2026.08.31 * @version V1.0.0,首次发布 * * @note ⚠ 硬约束:flash 擦写(syscfg_write)、BLE 广播切换、关机收口等"重活" * 禁止在 usr_timer_add 的中断上下文回调(本产品 20ms usr_timer_tick / * 按键长按回调)里直接执行,只能在 usr_timer_loop(BLE 线程,任务 * 上下文,栈充足)里执行。之前每个模块各自发明一个 pending 标志 * (off_pending/pair_pending/ota_pending/nvm 的 s_need_save), * 容易被后来的功能遗漏这条红线——本模块把"打标志"这一步收成统一 * 接口:ISR 只准调 app_defer_request(),真正执行永远在 * app_function_loop() 里用 app_defer_take() 消费。 ******************************************************************************/ #ifndef __APP_DEFER_H__ #define __APP_DEFER_H__ #include /** 延后动作位,新增一种"需要写flash/切广播/关机"的动作就加一项 */ typedef enum { APP_DEFER_NVM_SAVE = 0, /**< VM 防抖到点,需要落盘 */ APP_DEFER_PAIR, /**< 长按 5s 松手,需要清绑定进配对 */ APP_DEFER_OTA, /**< 长按 12s 到点,需要进 OTA */ APP_DEFER_MAX } AppDeferBit_t; /** * @brief 中断上下文调用:只置位,不做任何实际动作 * @param bit 要延后的动作 * @return 无 */ void app_defer_request(AppDeferBit_t bit); /** * @brief 任务上下文调用:查询并清除标志(取出即消费,最多处理一次) * @param bit 要消费的动作 * @return 1=之前挂起过(现在可以执行真正动作),0=没挂起 */ uint8_t app_defer_take(AppDeferBit_t bit); /** * @brief 任务上下文调用:只查询是否挂起,不清除(多个动作互斥判断用) * @param bit 要查询的动作 * @return 1=挂起中,0=未挂起 */ uint8_t app_defer_is_pending(AppDeferBit_t bit); /** * @brief 任务上下文调用:撤销挂起(如 OTA 触发时要撤销配对) * @param bit 要撤销的动作 * @return 无 */ void app_defer_cancel(AppDeferBit_t bit); #endif /* __APP_DEFER_H__ */