W1 功能主线完成:内存台账三件套(W1-0) + IEC104 上行(B4) + protectTask 板端接线(B5)

W1-0 台账三件套:scripts/ram_baseline.py(四模式)+ ram_baseline.tsv 趋势 +
docs/内存管理/RAM预算台账.md + pre-commit mem-budget 钩子(RW_IRAM1/RW_CCM >92%
即 FAIL + Top-10 附表);审查报告 §5.5 三条闭环。

B4 IEC 60870-5-104 上行(被控站,TCP 2404):App/protocol/iec104/ 三模块
(asdu 编解码 / pts 点表+数据源 vtable / link APCI+FSM,纯逻辑零 I/O)+
App/task/iec104_serv.c(iec104Task,NET_READY 屏障 100ms 分片喂位)。
82 断言 L0.5 全绿 + iec104-unit-test 钩子(第 31 钩子);
设计说明 docs/子系统设计/IEC104上行设计说明.md 全量回填。

B5 protectTask(L3 板端接线):App/task/protect_task.c——20ms 判据节拍
prot_elm_run + L5-4 采样故障闭锁(adc_health 电平位→元件复位)+ L5-1 定值
校验和巡检;新增 prot_elm_request_reset() 收口跨上下文复归(104 YK11 落请求、
eval 头部消费);定值/元件初始化移入 app_main_init(内核前)。TC-PE-010
(prot_elm 28 用例)。

门禁与内存:TASK_WD_PROTECT=8 入 required_mask(产品 0x77→0x1F7、HW 层
0x1F5,看门狗单测 39 断言同步);FreeRTOS 堆 48→56KB(.ioc L1 参数 +
FreeRTOSConfig.h 同步,RAM预算台账 §6 登记配额 48→56KB)。
ZI 144,008→152,204(+8,196 B = 堆 +8KB,B5 扩容);Code=204,348。
stack_report:protectTask 512 words 静态链 872 B/余 57%、iec104Task
640 words 1456 B/余 43% 均 PASS;RW_IRAM1 73.1% / RW_CCM 87.9%(<92%)。

验证:@build 0 错 0 警;ci_local 全绿(31 钩子 + 13 主机侧单测);
doc-links 135 文档 PASS。登记簿 B4/B5 销项、W1 波次完成;保护规划/看门狗
说明/AGENTS(9 任务)/RAM 三文档全部同步。

遗留(验收窗口,非代码空洞):台架第三方 104 主站往返(送检窗口)、
标准源注入动作判据、@test PROT 锚点 + protect 栈水位 + 新堆 min_ever 复测。
This commit is contained in:
2026-10-12 12:36:23 +08:00
parent e4134a4723
commit 90db528032
49 changed files with 4300 additions and 223 deletions
+37
View File
@@ -39,6 +39,8 @@
#include "sys_events.h"
#include "default_task.h"
#include "adc_task.h" /* B1(2026-10-10):ADC 采集消费者(手写任务,见 Variables 区) */
#include "iec104_serv.h" /* B4(2026-10-12):IEC 104 上行服务(手写任务,见 Variables 区) */
#include "protect_task.h" /* B5(2026-10-12):保护判据节拍任务(手写任务,同上) */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -119,6 +121,13 @@ static int hook_ptr_ok(const void *p)
* syslog_post 回显尾)。静态最坏链 1080 B,512 words 时余 968 B < 1024 B
* ISR 底线 → 抬至 640 words(2.5 KB,堆余量 min_ever 7152→≈6640 B,可承受)。
* 栈值以 `scripts/stack_report.py` 实测最坏链为准,改动前后各跑一次。
* iec104Task 640 words:B4(2026-10-12)104 上行服务(2404 监听 + link 状态
* 机)。link/pts 缓冲全静态;stack_report 实测静态最坏链 1456 B(拆链
* 重建监听 → net_bind → SPI 故障 → 日志尾,日志主导)。512 words 时余
* 592 B < 1024 B ISR 底线 → 抬至 640(2.5 KB)。
* protectTask 512 words:B5(2026-10-12)保护判据节拍(prot_elm_run 消费者
* + L5-4 采样闭锁)。stack_report 实测静态最坏链 872 B(float 判据 +
* phasor 快照 + 日志尾),余 1176 B / 57% ≥ ISR 底线 → 512 保持。
*/
/* 存储测试变量(g_storage_stats / s_perf_buf)已迁至 test/board/storage_test_task.c */
osThreadId_t timeSyncTaskHandle;
@@ -140,6 +149,28 @@ const osThreadAttr_t adcTask_attributes = {
.stack_size = 640 * 4,
.priority = (osPriority_t) osPriorityAboveNormal,
};
/* B4(2026-10-12):IEC 60870-5-104 被控站服务(2404 监听 + 链路状态机消费)。
* 手写于此而非 .ioc(同 timeSyncTask/adcTask:不在 Tasks01 里 → 重生成会丢,
* 靠审计 WARN 提示)。640 words:stack_report 实测静态最坏链 1456 B(拆链→
* 重建监听→net_bind→SPI 故障→日志尾,日志主导);512 words 时余 592 B
* < 1024 B ISR 底线 → 抬至 640(2.5 KB,CCM 堆 min_ever 再降 512 B,可承受)。 */
osThreadId_t iec104TaskHandle;
const osThreadAttr_t iec104Task_attributes = {
.name = "iec104Task",
.stack_size = 640 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* B5(2026-10-12):保护判据节拍(prot_elm_run 消费者 + L5-4 采样闭锁)。
* 手写于此而非 .ioc(同上)。512 words:stack_report 实测静态最坏链 872 B
* (float 判据 + phasor 快照 + 日志尾),余 1176 B / 57% ≥ ISR 底线 → 保持。
* 优先级 Normal:V0.1 无出口硬件(规划 R7),判据是 20ms 软实时,不需要
* adcTask 的 AboveNormal;规划 §4 的"1ms/高"随 P2 瞬时值元件再评。 */
osThreadId_t protectTaskHandle;
const osThreadAttr_t protectTask_attributes = {
.name = "protectTask",
.stack_size = 512 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
@@ -320,6 +351,12 @@ void MX_FREERTOS_Init(void) {
* (内核启动前)完成;本任务只做运行期采样。 */
adcTaskHandle = osThreadNew(adc_task_func, NULL, &adcTask_attributes);
/* B4(2026-10-12):IEC 60870-5-104 上行服务任务。任务体内先等 NET_READY
* 屏障(100ms 分片 + 每片喂心跳,timeSyncTask 先例),再建 2404 监听并
* 100ms 循环服务;纳入 IWDG required_mask(TASK_WD_IEC104,任何构建都创建)。 */
iec104TaskHandle = osThreadNew(iec104_serv_task, NULL, &iec104Task_attributes);
protectTaskHandle = osThreadNew(protect_task, NULL, &protectTask_attributes);
/* P2-13(2026-10-04):产品构建(未选任何 TEST_SUITE_*)不需要 testTask。
* 上方生成区按 .ioc FREERTOS.Tasks01 无条件创建它,其 2048 words(8KB) 栈 + TCB
* 取自 CCM 堆;而产品构建下 start_test_task() 仅打印一行后 osDelay(1000) 永久空转,