/****************************************************************************** * @file app_runrec.h * @brief CBR3 31 天运行记录(DP21 run_record,RO,124B) * @author cyWu <1917507415@qq.com> * @date 2026.09.02 * @version V1.0.0,随规格书 V3.0.0 新建 * * @note 规格书第 13.1 节。31 格 uint32 **大端**,单位秒: * slot[0]=今天 slot[1]=昨天 … slot[30]=前 30 天。 * 「在运行」= 风扇实际在转(fan_gear != 0 的真实输出)。手动、 * 通风开段、强力、定时、联动都算;**通风停 5 分钟那段不算**。 * 日期轴:未对时只往 slot[0] 累加、不旋转;对成功后按本地日历左移 * N 天;掉电上电先把 VM 的 31 格灌回 RAM。 * 落盘:每累计运行满 BOARD_RUN_RECORD_SAVE_SEC(600s) 写一次 VM; * 跨天旋转**立刻写**。拔电无软关机钩子,接受丢不满 10 分钟的秒数。 * DP21:任务上下文每 500ms 灌进 gDevData(读请求 / 10min 全量用); * 差分变化上报不带本 DP,避免每秒推 124B。 * * ⚠ 上下文分工(规格书第 0/13 章,2026-08-31 事故定论): * - app_runrec_tick() = 20ms **中断上下文**:只折 pending 秒, * 禁止改 s_rec[]、禁止 syscfg_write。 * - app_runrec_rotate_if_needed() = 500ms **任务上下文**:收下 * pending、跨天旋转、灌 DP21、必要时立刻写 VM。 ******************************************************************************/ #ifndef __APP_RUNREC_H__ #define __APP_RUNREC_H__ #include #include "board_pin.h" /** DP21 载荷长度:31 × 4 = 124 字节 */ #define APP_RUNREC_PACK_LEN (BOARD_RUN_RECORD_DAYS * 4u) /** * @brief 初始化运行记录(RAM 清零,DP21 灌全 0) * @return 无 */ void app_runrec_init(void); /** * @brief 20ms 中断上下文节拍:风扇在转就把毫秒折成 pending 秒 * @param dt 距上次调用的毫秒数 * @note ⚠ 不改 31 格数组、不写 flash。未对时也照常折秒,由任务加到 slot[0]。 * @return 无 */ void app_runrec_tick(uint16_t dt); /** * @brief 500ms 任务上下文:收下 pending、每拍灌 DP21、跨天旋转、满 10 分钟写 VM * @note 由 usr_timer_loop 调用。对时成功后首次读到日历只登记日期不旋转 * (slot[0] 已是当天累计值,继续累加)。 * @return 无 */ void app_runrec_rotate_if_needed(void); /** * @brief 取某天的运行秒数 * @param day 0=今天,1=昨天,… 30=前 30 天;越界返回 0 * @return 秒数 */ uint32_t app_runrec_get(uint8_t day); /** * @brief 打包成 DP21 的 124B 载荷(31 × uint32 大端) * @param out 输出缓冲,长度 APP_RUNREC_PACK_LEN * @note BOARD_RUNREC_ENABLE=0 时输出全 0(13.1) * @return 无 */ void app_runrec_pack(uint8_t *out); /** * @brief 从 VM 的 124B 载荷灌回 RAM(开机 app_nvm_load 调用) * @param in 输入缓冲,长度 APP_RUNREC_PACK_LEN * @return 无 */ void app_runrec_unpack(const uint8_t *in); /** * @brief slot[0] 对应的本地日期(yyyymmdd 十进制压缩),0=未对时 * @return 日期 */ uint32_t app_runrec_get_slot0_date(void); /** * @brief 设置 slot[0] 对应日期(开机 app_nvm_load 调用) * @param ymd yyyymmdd 十进制压缩;0=未对时 * @return 无 */ void app_runrec_set_slot0_date(uint32_t ymd); /** * @brief 清零 31 格与日期(出厂重置用,规格书第 14 章) * @return 无 */ void app_runrec_reset(void); #endif /* __APP_RUNREC_H__ */