阶段 D 收口:P3 卫生六项 + S-2 boot_log 存档流程 + 登记簿销项
阶段 D(验证与卫生)离线可完成项收口;台架依赖项 D2/D5/D6 保留登记。 - D4 P3 卫生六项: - P3-1 cfg_file.c s_encode:STR 型 len==0 回绕(p_key->len - 1u)直接拒绝 - P3-2 cfg_file_store_mcu.c:原子写临时名由 p_path 同目录推导(s_build_tmp_path) - P3-4 rs485.c:模块描述订正为实际实现(HAL_Delay(1),非 DWT µs) - P3-6 ch395f_get_socket_status:补 p_status NULL 检查 - P3-8 build.md:退出码契约订正为 0/1/2 三档 - P3-11 adc_task/rs485_task:注明"预留桩(未启用)" - D3 S-2:新增 docs/测试说明/boot_log_data/(快照存档目录 + 流程), 并在 测试开发标准流程.md §7.3 登记沉淀约定 - 登记簿销项:删 P3-1/2/4/6/8/11、S-2;阶段 D 表移除 D3/D4; §1 计数更新(P3 6→0、登记簿 10→9);§3 章节重排 (登记簿→§3.2、专项→§3.3);清理 App/cfg/README.md 等对已销编号的引用 - 同步刷新内存快照:Flash 266,632 B / ROM 合计 267,372 B 验证:@build 0 错 0 警;cfg_file 主机单测 149/149; pre-commit --all-files 17/17 通过。
This commit is contained in:
+1
-2
@@ -9,7 +9,7 @@
|
||||
|---|---|
|
||||
| `cfg_file.c/h` | **配置引擎核心**:解析 / 查询 / 保存 / 2s 周期 `cfg_file_poll` |
|
||||
| `cfg_file_store.h` | **存储后端抽象接口**(MCU=FreeRTOS 堆 / 模拟器=宿主堆,共享核心零分配符号) |
|
||||
| `cfg_file_store_mcu.c` | **MCU 端后端实现**:`/config.ini`(`/config.TMP` + `f_rename` 原子写) |
|
||||
| `cfg_file_store_mcu.c` | **MCU 端后端实现**:`/config.ini`(临时名由目标路径同目录推导 + `f_rename` 原子写) |
|
||||
|
||||
## 设计要点
|
||||
|
||||
@@ -25,4 +25,3 @@
|
||||
|
||||
- `docs/子系统设计/配置文件设计说明.md` — 完整设计(分层/解析/持久化/迁移)
|
||||
- `docs/子系统设计/网络配置说明.md` — 网络段
|
||||
- `docs/待处理内容.md` P3-2 — 临时文件名硬编码问题
|
||||
|
||||
+8
-1
@@ -266,7 +266,14 @@ static int s_encode(const cfg_key_def_t *p_key, const uint8_t *p_src, char *p_ds
|
||||
(unsigned)p_src[3], (unsigned)p_src[4], (unsigned)p_src[5]);
|
||||
break;
|
||||
case CFG_VAL_STR: {
|
||||
size_t slen = strlen((const char *)p_src);
|
||||
size_t slen;
|
||||
|
||||
/* P3-1:len==0 时 `p_key->len - 1u` 回绕为 SIZE_MAX → memcpy 巨长越界。
|
||||
* STR 字段至少 1 字节(含结尾 NUL),len==0 非法,直接拒绝 */
|
||||
if (p_key->len == 0u) {
|
||||
return -1;
|
||||
}
|
||||
slen = strlen((const char *)p_src);
|
||||
if (slen >= p_key->len) {
|
||||
slen = p_key->len - 1u;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 模块名称:cfg_file_store (MCU 后端)
|
||||
* 模块功能:cfg_file 存储后端——NAND 上 FatFS 文件 /config.ini(卷根,8.3 合规);
|
||||
* 原子写 = 临时文件 /config.TMP + f_rename;mtime 变更令牌 =
|
||||
* 原子写 = 临时文件 config.TMP(与目标同目录)+ f_rename;mtime 变更令牌 =
|
||||
* (fdate << 16) | fmtime;旧版遗留文件 /cfg/netcfg.bin 供迁移读取
|
||||
* 适用平台:STM32F407ZGTx
|
||||
* 作者:王建锋
|
||||
@@ -18,6 +18,9 @@
|
||||
* dhara journal 竞争实证);busy 返回 -1 由调用方
|
||||
* 按既有失败语义处理(poll 保留 RAM/保存待重试),
|
||||
* 本任务 = 看门狗喂狗点,绝不阻塞等锁
|
||||
* v1.4 2026-10-05 王建锋 原子写临时文件由 p_path 推导(P3-2):与目标同目录的
|
||||
* 固定 8.3 名 config.TMP,不再硬编码卷根;目标恒为
|
||||
* "/config.ini" 时推导结果与旧值逐字节一致
|
||||
*/
|
||||
|
||||
/* 头文件包含区 */
|
||||
@@ -74,8 +77,40 @@ int cfg_store_read(const char *p_path, uint8_t *p_buf, size_t cap, size_t *p_nre
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 临时文件名(8.3 合规)与路径缓冲上限 */
|
||||
#define CFG_STORE_TMP_NAME "config.TMP"
|
||||
#define CFG_STORE_TMP_PATH_MAX 24u
|
||||
|
||||
/*
|
||||
* 函数功能:原子写文件(先写 /config.TMP,成功后 unlink 既有目标 + f_rename 替换)
|
||||
* 函数功能:由目标路径推导同目录的临时文件路径(P3-2)
|
||||
* 入口参数:p_path - 目标文件路径 const char *
|
||||
* p_out - 输出缓冲 char *
|
||||
* cap - 缓冲容量 size_t
|
||||
* 返回值:0 - 成功;-1 - 参数非法/缓冲不足 int
|
||||
* 函数说明:取 p_path 的目录前缀(含末尾 '/';无 '/' 则用当前目录),拼固定 8.3 名
|
||||
* config.TMP。目标 "/config.ini" → "/config.TMP"(与旧硬编码值一致)
|
||||
*/
|
||||
static int s_build_tmp_path(const char *p_path, char *p_out, size_t cap) {
|
||||
const char *p_slash;
|
||||
size_t dirlen;
|
||||
|
||||
if (p_path == NULL || p_out == NULL) {
|
||||
return -1;
|
||||
}
|
||||
p_slash = strrchr(p_path, '/');
|
||||
dirlen = (p_slash != NULL) ? ((size_t)(p_slash - p_path) + 1u) : 0u;
|
||||
if (dirlen + sizeof(CFG_STORE_TMP_NAME) > cap) {
|
||||
return -1;
|
||||
}
|
||||
if (dirlen != 0u) {
|
||||
(void)memcpy(p_out, p_path, dirlen);
|
||||
}
|
||||
(void)memcpy(p_out + dirlen, CFG_STORE_TMP_NAME, sizeof(CFG_STORE_TMP_NAME));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:原子写文件(先写与目标同目录的 config.TMP,成功后 unlink 既有目标 + f_rename 替换)
|
||||
* 入口参数:p_path - 目标文件路径 const char *
|
||||
* p_buf - 待写数据(不可为 NULL) const uint8_t *
|
||||
* len - 数据长度 size_t
|
||||
@@ -86,14 +121,19 @@ int cfg_store_write_atomic(const char *p_path, const uint8_t *p_buf, size_t len)
|
||||
FIL f;
|
||||
FRESULT fr;
|
||||
UINT bw = 0u;
|
||||
char tmp_path[CFG_STORE_TMP_PATH_MAX];
|
||||
|
||||
if (p_buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
/* P3-2:临时文件由 p_path 推导(同目录 + 固定 8.3 名),不再硬编码卷根 */
|
||||
if (s_build_tmp_path(p_path, tmp_path, sizeof(tmp_path)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (vol_lock_wait(0u) == 0u) {
|
||||
return -1; /* 卷被占用:本轮跳过(保存请求由 2s 轮询重试) */
|
||||
}
|
||||
fr = f_open(&f, s_path_tmp, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
fr = f_open(&f, tmp_path, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (fr != FR_OK) {
|
||||
vol_lock_release();
|
||||
return -1;
|
||||
@@ -101,7 +141,7 @@ int cfg_store_write_atomic(const char *p_path, const uint8_t *p_buf, size_t len)
|
||||
fr = f_write(&f, (const void *)p_buf, (UINT)len, &bw);
|
||||
(void)f_close(&f);
|
||||
if (fr != FR_OK || bw != (UINT)len) {
|
||||
(void)f_unlink(s_path_tmp);
|
||||
(void)f_unlink(tmp_path);
|
||||
vol_lock_release();
|
||||
return -1;
|
||||
}
|
||||
@@ -113,9 +153,9 @@ int cfg_store_write_atomic(const char *p_path, const uint8_t *p_buf, size_t len)
|
||||
* 开机 load 按"首启"重建工厂模板——与函数失败语义一致,丢失边界 =
|
||||
* 本次进行中的保存内容(目标原值本就是待覆盖的旧代数据) */
|
||||
(void)f_unlink(p_path); /* 目标不存在返回 FR_NO_FILE,无害 */
|
||||
fr = f_rename(s_path_tmp, p_path);
|
||||
fr = f_rename(tmp_path, p_path);
|
||||
if (fr != FR_OK) {
|
||||
(void)f_unlink(s_path_tmp);
|
||||
(void)f_unlink(tmp_path);
|
||||
vol_lock_release();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
/*
|
||||
* 模块名称:ADC Sampling Task
|
||||
* 模块功能:TPAFE5160 8 通道同步采样,数据缓存与通知
|
||||
* 状态说明:**预留桩(未启用)**——采集链路尚未实现,产品定义未定
|
||||
* (见 docs/待处理内容.md 阶段 B0/B1)。当前 init/func 为空实现,
|
||||
* 不触发 CONVST、不消费数据。
|
||||
* 适用平台:STM32F407ZGTx + TPAFE5160
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-07-19
|
||||
* 修改记录:
|
||||
* v1.0 2026-07-19 王建锋 创建初始版本
|
||||
* v1.1 2026-10-05 王建锋 P3-11:注明"预留桩(未启用)",避免误认为已实现
|
||||
*/
|
||||
|
||||
#include "adc_task.h"
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
/*
|
||||
* 模块名称:RS485 Communication Task
|
||||
* 模块功能:RS-485 轮询收发、协议帧解析与响应
|
||||
* 状态说明:**预留桩(未启用)**——采集/协议链路尚未实现,产品定义未定
|
||||
* (见 docs/待处理内容.md 阶段 B0/B2)。当前 init/func 为空实现,
|
||||
* 不收发、不解析。
|
||||
* 适用平台:STM32F407ZGTx
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-07-19
|
||||
* 修改记录:
|
||||
* v1.0 2026-07-19 王建锋 创建初始版本
|
||||
* v1.1 2026-10-05 王建锋 P3-11:注明"预留桩(未启用)",避免误认为已实现
|
||||
*/
|
||||
|
||||
#include "rs485_task.h"
|
||||
|
||||
Reference in New Issue
Block a user