Files
JBao_Temp_Humi_Fan_FW/apps/usr_app/app_arbiter.c
T
wuchuyuan 5cc7e9dbd6 接入温湿度风扇产品固件(仲裁/条件/定时/显示),并补齐规格书与外设驱动
新增 usr_app 产品逻辑:手动>定时>条件仲裁、条件控温湿、定时任务、数码管显示、
按键/LED、风扇档位、NVM 掉电恢复、配对与开关机,上电按规格恢复上次状态。
新增 usr_periph:AHT20、CT1642、板级引脚与硬件封装;见宝协议 cond_config
改为 7 字节编解码,并接入产品 DP。
补充《温湿度风扇_固件需求规格书》,工程加入对应源文件。
.gitignore 忽略 WorkBuddy/Cursor 本地会话
2026-08-31 15:17:27 +08:00

160 lines
4.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/******************************************************************************
* @file app_arbiter.c
* @brief CBR3 模式仲裁器实现(规格书第 12 章:手动 > 定时 > 条件)
* @author cyWu <1917507415@qq.com>
* @date 2026.08.31
* @version V1.0.0
* @history
* - V1.0.0, 2026.08.31, cyWu, 首次发布(P2
*
* @note 本模块是唯一模式占用源,运行在 usr_timer_loop(任务上下文)。
* 规则落地(规格书 12 章):
* - 手动动作 → manual_intervene()owner=NONE
* 条件引擎感知后作废本轮(RAM,须回安全再满时长才重新触发);
* 定时引擎感知后本窗剩余时间不自动抢回(等下一窗开始沿)。
* - 定时窗开始 → timer_take()(定时 > 条件,条件即使满时长也不开);
* - 条件触发 → cond_take()(仅 owner!=TIMER 允许;快照只存第一次);
* - 两路条件后触发覆盖 → 仍走 cond_take(),快照不变(不回栈)。
******************************************************************************/
#include "app_arbiter.h"
#include "app_mode.h"
#include "app_fan.h"
#define LOG_TAG_CONST APP
#define LOG_TAG "[ARB]"
#define LOG_INFO_ENABLE
#include "debug.h"
/** 仲裁器上下文 */
typedef struct {
ArbOwner_t owner; /**< 当前占用者 */
uint8_t snap_valid; /**< 条件快照是否有效 */
uint8_t snap_mode; /**< 快照模式(第一次条件抢权前) */
uint8_t snap_gear; /**< 快照档位 */
} AppArbiterCtx_t;
static AppArbiterCtx_t s_arb;
/**
* @brief 初始化仲裁器
* @return 无
*/
void app_arbiter_init(void)
{
s_arb.owner = ARB_OWNER_NONE;
s_arb.snap_valid = 0;
s_arb.snap_mode = 0;
s_arb.snap_gear = 0;
log_info("arbiter init\n");
}
/**
* @brief 当前模式占用者
* @return ArbOwner_t
*/
uint8_t app_arbiter_get_owner(void)
{
return (uint8_t)s_arb.owner;
}
/**
* @brief 手动动作统一入口:释放一切自动化占用
* @note 条件/定时引擎下个 tick 查 owner 感知后各自作废;不恢复快照
* (手动已接管,快照对应的用户状态已过时)
* @return 无
*/
void app_arbiter_manual_intervene(void)
{
if (s_arb.owner != ARB_OWNER_NONE) {
log_info("manual intervene, owner %d -> none\n", s_arb.owner);
}
s_arb.owner = ARB_OWNER_NONE;
}
/**
* @brief 条件引擎尝试占用
* @return 1=成功;0=定时占用中(规格书 12:定时 vs 条件 → 定时胜)
*/
uint8_t app_arbiter_cond_take(void)
{
if (s_arb.owner == ARB_OWNER_TIMER) {
return 0; /* 定时窗内条件不触发 */
}
if (!s_arb.snap_valid) {
/* 第一次条件抢权前快照用户状态;后覆盖/多次触发不改快照(10.3-6) */
s_arb.snap_mode = app_mode_get_active();
s_arb.snap_gear = app_fan_get_gear();
s_arb.snap_valid = 1;
log_info("cond take, snapshot mode=%d gear=%d\n", s_arb.snap_mode, s_arb.snap_gear);
}
s_arb.owner = ARB_OWNER_COND;
return 1;
}
/**
* @brief 条件是否仍在占用
* @return 1=owner==COND
*/
uint8_t app_arbiter_cond_active(void)
{
return (s_arb.owner == ARB_OWNER_COND) ? 1 : 0;
}
/**
* @brief 条件自然失效:恢复快照后调用(清 owner 与快照)
* @return 无
*/
void app_arbiter_cond_release(void)
{
if (s_arb.owner == ARB_OWNER_COND) {
s_arb.owner = ARB_OWNER_NONE;
}
s_arb.snap_valid = 0;
}
/**
* @brief 取条件快照
* @param mode 输出模式
* @param gear 输出档位
* @return 无
*/
void app_arbiter_cond_get_snapshot(uint8_t *mode, uint8_t *gear)
{
*mode = s_arb.snap_mode;
*gear = s_arb.snap_gear;
}
/**
* @brief 条件被手动打断:只清快照(不恢复、不清 owner)
* @return 无
*/
void app_arbiter_cond_snapshot_clear(void)
{
s_arb.snap_valid = 0;
}
/**
* @brief 定时窗开始占用(优先级高于条件)
* @return 1=成功
*/
uint8_t app_arbiter_timer_take(void)
{
if (s_arb.owner != ARB_OWNER_TIMER) {
log_info("timer take\n");
}
s_arb.owner = ARB_OWNER_TIMER;
return 1;
}
/**
* @brief 定时窗结束释放(调用方负责收口:风扇 0、mode 0)
* @return 无
*/
void app_arbiter_timer_release(void)
{
if (s_arb.owner == ARB_OWNER_TIMER) {
s_arb.owner = ARB_OWNER_NONE;
}
}