1fe163ba7b
- prot_set:新增 PS_GLOBAL_EN(枚举尾追加);值区双缓冲 + 单字交换, prot_set_set_sealed 原子写+封存;selfcheck 改 seqlock 式复核 (提交撞见 = 本轮跳过)→ 收口 B5 登记的 µs 级误锁窗口 - 持久化:新增 App/cfg/prot_set_store.c/h,/prot_set.bin blob (magic+版本+计数+值区+sum32 正/反码对,144 B)走 cfg_store_write_atomic; uvprojx 注册 + 模拟器豁免点名(check_registration 同步) - 写路径:C_SE/YK12 执行段置脏 → iec104Task 投递 SYS_EVT_PROT_SET_SAVE (事件位 bit7)→ defaultTask(配置引擎属主)落盘,写失败脏回置 = 天然 重试;装载 = STORAGE_READY 屏障前整表原子 parse(损坏保出厂默认 + 自检留痕 prot set corrupt;文件缺失 = 首启静默) - YK12 转真:两段式(选择段校验 DPC / 执行段 set_sealed),protectTask 下一拍读退出态 → 复位元件 + 停判据(global plate OUT/IN 边沿日志); 本地定值项 comm_addr=0 显式不可寻址(防 IOA=0 误命中首个本地项) - 单测:prot_set 63 断言(+33:软压板/原子写/脏握手/blob 往返/损坏拒绝/ 伪造自洽越界对抗样本)、iec104 94 断言(+7:YK12 两段转真/置脏/本地项 C_RD EVI) - 文档:IEC104 设计说明 §3.3/§3.4/§7、保护规划 §3.5 L5-1/§7 P4/变更记录、 App/algo 与 App/cfg README、W1 任务卡 B7→🟦(台架腿 🔴 待窗口,随 B6 同窗) - 验证:@build 0 错 0 警(Code=205500,ZI +280 = 双缓冲+blob 缓冲); ci_local 全绿(L0 27 钩子 + L0.5 13 套件 826 断言);ram_baseline 台账 受管区与内存快照已同步;19 个改动文件无 BOM / LF / 零乱码
123 lines
5.2 KiB
C
123 lines
5.2 KiB
C
/*
|
||
* 模块名称:保护任务(L3 板端接线,B5)——实现
|
||
* 模块功能:见 protect_task.h。每拍三件事:
|
||
* ① L5-4 采样故障闭锁:adc_health_flags() 电平位命中 → 元件状态
|
||
* 复位(防陈旧判据)+ 本拍不 eval;
|
||
* ② prot_set_selfcheck()(L5-1 定值完整性巡检,31 项 sum32,开销
|
||
* 可忽略;失配 → prot_set 内部闭锁,eval 自动复位全元件);
|
||
* ③ prot_elm_run()(phasor rms → 判据步进)+ 动作位图边沿日志;
|
||
* ④ 全局软压板 PS_GLOBAL_EN(104 YK12 两段式投退,B7):退出 =
|
||
* 复位元件 + 停判据(与采样闭锁同构,独立边沿日志)。
|
||
* 定值/元件初始化在 app_main_init(内核前,B5);本任务只消费。
|
||
* 线程约定:prot_elm_run / prot_set_selfcheck 仅本任务上下文(prot_elm.h);
|
||
* 跨上下文复归(104 YK11)经 prot_elm_request_reset 落请求。
|
||
* 创建日期:2026-10-12(B5)
|
||
*/
|
||
#include "protect_task.h"
|
||
|
||
#include "cmsis_os2.h"
|
||
|
||
#define DBG_TAG "[PROT]"
|
||
#define DBG_LINE_BUF_MAX 128U
|
||
#include "dbg_log.h"
|
||
|
||
#include "adc_health.h"
|
||
#include "prot_elm.h"
|
||
#include "prot_set.h"
|
||
#include "task_watchdog.h"
|
||
|
||
/* L5-4 采样故障电平闭锁位:stall(可自愈)+ backward(锁存)都须停判据。
|
||
* 锁存类(FRSTDATA/HW_ERR 等)不在此列——它们是一次性事件痕迹,不构成
|
||
* "当前测量不可信";持续 stall/backward 才是。 */
|
||
#define PROT_HF_LOCK_MASK (ADC_HF_TPAFE_STALL | ADC_HF_STM32_STALL | ADC_HF_SEQ_BACKWARD)
|
||
|
||
static uint32_t s_prev_active; /* 上拍动作位图(边沿日志用) */
|
||
static uint8_t s_prev_hf_lock; /* 上拍采样闭锁态(边沿日志用) */
|
||
static uint8_t s_prev_plate_out; /* 上拍全局软压板退出态(边沿日志用,B7) */
|
||
|
||
/*
|
||
* 函数功能:动作位图变化沿日志(逐变化元件打名字与状态)
|
||
* 入口参数:active - 本拍 prot_elm_active_mask()
|
||
* 函数说明:V0.1 无出口硬件(规划 R7),动作 = 遥信 + 日志;SOE 落盘随 L4。
|
||
*/
|
||
static void s_log_active_edge(uint32_t active) {
|
||
uint32_t chg = active ^ s_prev_active;
|
||
uint32_t i;
|
||
|
||
for (i = 0u; (i < (uint32_t)PE_COUNT) && (chg != 0u); i++) {
|
||
const uint32_t bit = 1u << i;
|
||
|
||
if ((chg & bit) != 0u) {
|
||
prot_elm_state_t st;
|
||
|
||
chg &= ~bit;
|
||
prot_elm_state((prot_elm_id_t)i, &st);
|
||
DBG_INFO("elm %s asserted=%u picked=%u",
|
||
prot_elm_name((prot_elm_id_t)i),
|
||
(unsigned)st.asserted, (unsigned)st.picked);
|
||
}
|
||
}
|
||
s_prev_active = active;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:protectTask 线程入口
|
||
* 入口参数:argument - 未用
|
||
* 返 回 值:无(不返回)
|
||
* 函数说明:无就绪屏障(判据只依赖 phasor 使用区,未就绪时 prot_elm_run
|
||
* 整拍自跳;采样闭锁另有 adc_health 电平位兜底)→ 上电即跑。
|
||
* 每拍喂看门狗(TASK_WD_PROTECT,产品 required_mask 0x1F7)。
|
||
*/
|
||
void protect_task(void *argument) {
|
||
(void)argument;
|
||
|
||
DBG_INFO("protect task start: cycle=%ums elm=%u",
|
||
(unsigned)PROTECT_TASK_CYCLE_MS, (unsigned)PE_COUNT);
|
||
|
||
for (;;) {
|
||
uint32_t now = osKernelGetTickCount();
|
||
uint32_t hf = adc_health_flags();
|
||
|
||
if ((hf & PROT_HF_LOCK_MASK) != 0u) {
|
||
/* L5-4:测量链不可信 → 复位元件(本任务上下文,直接 init 合法)
|
||
* 并跳过判据;stall 自愈后下一拍自动恢复 */
|
||
if (s_prev_hf_lock == 0u) {
|
||
DBG_ERROR("sampling FAULT -> protection blocked (hf=0x%08lX)",
|
||
(unsigned long)(hf & PROT_HF_LOCK_MASK));
|
||
}
|
||
s_prev_hf_lock = 1u;
|
||
prot_elm_init();
|
||
} else {
|
||
if (s_prev_hf_lock != 0u) {
|
||
DBG_INFO("sampling recovered -> protection resumed");
|
||
s_prev_hf_lock = 0u;
|
||
}
|
||
/* L5-1 巡检:定值区与封存校验和不符 → prot_set 闭锁(下一拍起
|
||
* eval 自动复位全元件)。B7 收口:104 定值写改走
|
||
* prot_set_set_sealed(影子区写+封存后单字交换),selfcheck 另有
|
||
* seqlock 式复核(提交撞见 = 本轮跳过),误锁窗口已消除。 */
|
||
(void)prot_set_selfcheck();
|
||
/* 全局软压板(PS_GLOBAL_EN,104 YK12 两段式投退,B7):退出 =
|
||
* 保护停止判据并复位元件状态(重新投入从干净快照起步) */
|
||
if (prot_set_get_ctl(PS_GLOBAL_EN) == 0u) {
|
||
if (s_prev_plate_out == 0u) {
|
||
DBG_INFO("global plate OUT -> protection disabled");
|
||
s_prev_plate_out = 1u;
|
||
}
|
||
prot_elm_init();
|
||
} else {
|
||
if (s_prev_plate_out != 0u) {
|
||
DBG_INFO("global plate IN -> protection enabled");
|
||
s_prev_plate_out = 0u;
|
||
}
|
||
prot_elm_run(now);
|
||
}
|
||
}
|
||
|
||
s_log_active_edge(prot_elm_active_mask());
|
||
|
||
task_wd_beat(TASK_WD_PROTECT);
|
||
osDelay(PROTECT_TASK_CYCLE_MS);
|
||
}
|
||
}
|