/****************************************************************************** * @file app_arbiter.c * @brief CBR3 模式仲裁器实现(规格书第 12 章:手动 > 定时 > 联动) * @author cyWu <1917507415@qq.com> * @date 2026.09.02 * @version V2.0.0(规格书 V3.0.0):owner COND → LINKAGE,删除档位快照 * * @note 本模块是唯一占用源,运行在 usr_timer_loop(任务上下文)。 * 规则落地(规格书 12 章): * - 手动动作 → manual_intervene():owner=NONE + 转调 * app_linkage_void()(联动作废本轮,RAM,不写 VM); * 定时引擎感知后本窗剩余时间不自动抢回(等下一窗开始沿)。 * - 定时窗开始 → timer_take()(定时 > 联动,窗内联动不插嘴); * - 联动触发 → linkage_take()(owner==TIMER 时返回 0); * 占用成功**不存档位快照**(联动开=写1、关=写0,不恢复)。 * - 联动自然失效 → linkage_release()。 * 作废标志不存 VM;再武装由 app_linkage 走到 10.3「关」条件后完成。 ******************************************************************************/ #include "app_arbiter.h" #include "app_linkage.h" #define LOG_TAG_CONST APP #define LOG_TAG "[ARB]" #define LOG_INFO_ENABLE #include "debug.h" /** 仲裁器上下文:V2.0.0 起只有 owner(快照整段删除) */ static uint8_t s_owner; /** * @brief 初始化仲裁器 * @return 无 */ void app_arbiter_init(void) { s_owner = ARB_OWNER_NONE; log_info("arbiter init\n"); } /** * @brief 当前风扇占用者 * @return ArbOwner_t */ uint8_t app_arbiter_get_owner(void) { return s_owner; } /** * @brief 手动动作统一入口:释放一切自动化占用 + 作废本轮联动 * @note 联动的作废标志放在 app_linkage(本是联动自己的状态),这里只是 * **唯一转调点**:手动介入的三个入口(短按 / APP 写 mode / APP 写档) * 都只调本函数,业务规则就不会被后来的功能漏掉。 * @return 无 */ void app_arbiter_manual_intervene(void) { if (s_owner != ARB_OWNER_NONE) { log_info("manual intervene, owner %d -> none\n", s_owner); } s_owner = ARB_OWNER_NONE; app_linkage_void(); /* 12 章规则 1:手动 vs 联动 → 手动,本轮联动作废 */ } /** * @brief 联动引擎尝试占用 * @return 1=成功;0=定时占用中(规格书 12:定时 vs 联动 → 定时胜) */ uint8_t app_arbiter_linkage_take(void) { if (s_owner == ARB_OWNER_TIMER) { return 0; /* 定时窗内联动不开、不改档(11.3 / 12 章) */ } if (s_owner != ARB_OWNER_LINKAGE) { log_info("linkage take\n"); } s_owner = ARB_OWNER_LINKAGE; return 1; } /** * @brief 联动是否仍在占用 * @return 1=owner==LINKAGE */ uint8_t app_arbiter_linkage_active(void) { return (s_owner == ARB_OWNER_LINKAGE) ? 1 : 0; } /** * @brief 联动自然失效:让出占用(档位由调用方写) * @return 无 */ void app_arbiter_linkage_release(void) { if (s_owner == ARB_OWNER_LINKAGE) { s_owner = ARB_OWNER_NONE; } } /** * @brief 定时窗开始占用(优先级高于联动) * @return 1=成功 */ uint8_t app_arbiter_timer_take(void) { if (s_owner != ARB_OWNER_TIMER) { log_info("timer take\n"); } s_owner = ARB_OWNER_TIMER; return 1; } /** * @brief 定时窗结束释放(调用方负责收口:风扇 0、mode 0 + 联动重判) * @return 无 */ void app_arbiter_timer_release(void) { if (s_owner == ARB_OWNER_TIMER) { s_owner = ARB_OWNER_NONE; } }