feat(采集标定): 卡1 TPAFE 量程口径定死 + 卡3 cfg_file 补 CFG_VAL_INT

卡 1(文档口径;卡 0/12 实测类按用户指示跳过,只落口径与占位):
- ADC通道映射说明.md 文首摘要行的 ±10 V 更正为 ±5 V 双极性:板上 RANGE
  接 GND,±5 V 满量程 = 10 V 跨度,LSB ≈ 152.59 µV/码(@引脚)
- §7 TPAFE 量程行重写并括注 ±10 V 是芯片可选档(RANGE=HIGH,跨度 20 V、
  LSB 305.18 µV)、本板未用;§1 缺陷实质 2 补「满量程 = 10 V 跨度」
- 新增 §7.1 端到端量纲链路分段口径:②引脚侧 LSB 系数定死(TPAFE 152.59 /
  STM32 805.66 µV/码,纯转换器事实、与前端网络无关,卡 2 的 ROM 默认按此
  冻结);③1k+1k 网络「2:1 分压 vs 源阻抗匹配」两读法待卡 0 注入斜率判别;
  ④端子→AINn 变比为仓库缺口待卡 0b;305.18/1611.3 定性为读法 A 的条件值、
  判别前禁入代码;§9 变更记录编号不动(继保规划有指向本文件 §9 的跨文档
  引用),新增行追加于其后
- 全仓其余 ±10 V 仅剩芯片手册转写与 tpafe5160 RANGE 枚举可选档注释
  (芯片能力描述,非本板口径);数据可信.md §2.1 冲突挂账归 lead 销项

卡 3(代码;cfg_file.c 带 BOM,编辑后核 EF BB BF 完好):
- 新增值类型 CFG_VAL_INT(枚举尾部追加、既有值不变;len 1/2/4 小端补码):
  s_decode_int() = strtol + ERANGE + 宽度上下界双校验(两端 long 均 32 位,
  超范围文本饱和成 LONG_MAX 仅比界抓不住,ERANGE 必查);s_encode() 带负号
  %ld 输出;cfg_file_register() 拒 INT 非法 len
- 单测新增 TC-CONFIG-006/007/008:-1 / INT32_MIN / INT32_MAX / 越界拒绝
  (含饱和带 2147483648)/ 编码带负号 / [sys] 段 load-save-load 往返一致 /
  注册拒绝 INT len=3 —— cfg_file 套件 200/200 PASS
- 回归:net_cfg 45/45、ftp_cfg 16/16 PASS,既有 network/ftp 段行为不变
- 越界改动说明:TC-CONFIG-006~008 定义行登记进属主文档
  docs/测试说明/配置文件单元测试说明.md(id-check 增量拦截要求在属主登记处
  补定义,该文件不在本卡写范围但为门禁唯一修复路径,仅追加 3 行用例 + 1 行
  变更记录,lead 评审时留意)

gate:@build 0 错误 0 警告(Code=214104 RO=18860 RW=1204 ZI=131852);
RAM 增量 0 B(RW/ZI 与 ram_baseline 2026-10-24 行完全一致,IRAM1 57.7%、
CCM 87.9% 不变),Flash +324 B;uvprojx 零挂载变化、未入库。
staged 门禁全绿,唯 mem-numbers / mem-budget 因 Flash 增量需台账回填
(--write 目标 docs/内存管理/** 属单写者文件,本道不得触碰):
gate: only mem-budget/mem-numbers pending lead ledger backfill
(--all-files 全量自查确认失败面仅此两条;BOM/CR/U+FFFD/字面量 ASCII 已
手工自查)
This commit is contained in:
2026-10-25 03:13:32 +08:00
parent 15aa08552c
commit 411594bf67
5 changed files with 240 additions and 10 deletions
+120 -5
View File
@@ -7,7 +7,7 @@
* **内存虚拟文件系统**桩实现(cfg_store_* 系列强符号)。
*
* 为什么要主机侧单测(而不是只用板端套件):
* 1. 配置引擎的核心是"文本 <-> 结构"的纯变换(INI 段/键解析、四种值类型
* 1. 配置引擎的核心是"文本 <-> 结构"的纯变换(INI 段/键解析、五种值类型
* 编解码、外科手术式保存、超长守卫),与硬件无关;板端套件无法穷举
* 畸形输入,更无法在毫秒内构造"超长文件 / 写失败 / 堆分配失败"。
* 2. 主机侧可**精确注入**故障:文件缺失、读取失败、写失败、分配失败——
@@ -21,6 +21,12 @@
* TC-CONFIG-003 IP4 正常与非法(段数不足、>255、前导非数字、多余后缀)
* TC-CONFIG-004 MAC 三种分隔符 + 大小写 + 非法
* TC-CONFIG-005 STR 正常 / 超长拒绝 / 边界(恰好放下)
* TC-CONFIG-006 INT 合法解码:0 / -1 / INT32_MIN / INT32_MAX / 各宽度边界 /
* 前导 + / 前导 0(数据可信卡 3:负零点偏移可落盘)
* TC-CONFIG-007 INT 非法拒绝:空 / 非数字 / 带后缀 / 越界(含 strtol 饱和带,
* 即超 INT32 但钳位后恰落界内的文本)/ 坏 len
* TC-CONFIG-008 INT 编码带负号输出 + 注册校验(INT len=3 拒绝)+
* [sys] 段 load/save/load 全链往返一致(出厂模板带负号默认)
* —— INI 解析(s_split_line / s_match_section / s_key_value / s_parse)——
* TC-CONFIG-010 注释(; 与 #)与空行忽略
* TC-CONFIG-011 CRLF / LF 混排
@@ -229,16 +235,23 @@ static const cfg_key_def_t s_net_keys[] = {
{ "name", CFG_VAL_STR, offsetof(sec_net_t, name), 12u },
};
/* 段 B:[sys],无回调,用于验证多段与超长字段拒绝 */
/* 段 B:[sys],无回调,用于验证多段、超长字段拒绝与 INT 有符号往返(卡 3)。
* 字段按自然对齐排布:u32@0 / i8@4 / i16@6 / i32@8,offset 用 offsetof 取真值 */
typedef struct {
uint32_t baud; /* offset 0 len 4 UINT */
uint32_t baud; /* offset 0 len 4 UINT */
int8_t ofs8; /* offset 4 len 1 INT */
int16_t ofs16; /* offset 6 len 2 INT(负默认:模板须带负号写出) */
int32_t ofs32; /* offset 8 len 4 INT(默认 INT32_MIN:极值往返) */
} sec_sys_t;
static sec_sys_t s_sys_data;
static const sec_sys_t s_sys_def = { 115200u };
static const sec_sys_t s_sys_def = { 115200u, -5, -300, (-2147483647 - 1) };
static const cfg_key_def_t s_sys_keys[] = {
{ "baud", CFG_VAL_UINT, offsetof(sec_sys_t, baud), 4u },
{ "baud", CFG_VAL_UINT, offsetof(sec_sys_t, baud), 4u },
{ "ofs8", CFG_VAL_INT, offsetof(sec_sys_t, ofs8), 1u },
{ "ofs16", CFG_VAL_INT, offsetof(sec_sys_t, ofs16), 2u },
{ "ofs32", CFG_VAL_INT, offsetof(sec_sys_t, ofs32), 4u },
};
/* ===================== 辅助 ===================== */
@@ -417,6 +430,103 @@ static void tc_str(void) {
CHECK(s_decode_str(d, 8u, "") == 0 && d[0] == '\0', "empty string ok");
}
/* TC-CONFIG-006/007:INT 解码(数据可信卡 3——有符号零点偏移) */
static void tc_int_decode(void) {
uint8_t d[4];
printf("[TC-CONFIG-006] INT decode valid\n");
CHECK(s_decode_int(d, 4u, "0") == 0 && d[0] == 0u && d[3] == 0u, "int32 zero");
CHECK(s_decode_int(d, 4u, "-1") == 0 && d[0] == 0xFFu && d[1] == 0xFFu &&
d[2] == 0xFFu && d[3] == 0xFFu, "-1 = four FF bytes (two's complement)");
CHECK(s_decode_int(d, 4u, "-2147483648") == 0 && d[0] == 0x00u &&
d[1] == 0x00u && d[2] == 0x00u && d[3] == 0x80u, "INT32_MIN accepted");
CHECK(s_decode_int(d, 4u, "2147483647") == 0 && d[0] == 0xFFu &&
d[1] == 0xFFu && d[2] == 0xFFu && d[3] == 0x7Fu, "INT32_MAX accepted");
CHECK(s_decode_int(d, 1u, "-128") == 0 && d[0] == 0x80u, "int8 -128");
CHECK(s_decode_int(d, 1u, "127") == 0 && d[0] == 0x7Fu, "int8 +127");
CHECK(s_decode_int(d, 2u, "-32768") == 0 && d[0] == 0x00u && d[1] == 0x80u,
"int16 -32768");
CHECK(s_decode_int(d, 2u, "32767") == 0 && d[0] == 0xFFu && d[1] == 0x7Fu,
"int16 +32767");
CHECK(s_decode_int(d, 4u, "+42") == 0 && d[0] == 42u, "leading + accepted");
CHECK(s_decode_int(d, 4u, "-0") == 0 && d[0] == 0u && d[3] == 0u, "-0 decodes 0");
CHECK(s_decode_int(d, 4u, "00012") == 0 && d[0] == 12u && d[3] == 0u,
"leading zeros accepted");
printf("[TC-CONFIG-007] INT decode invalid rejected\n");
CHECK(s_decode_int(d, 4u, "") == -1, "empty rejected");
CHECK(s_decode_int(d, 4u, "abc") == -1, "non-numeric rejected");
CHECK(s_decode_int(d, 4u, "12x") == -1, "trailing garbage rejected");
CHECK(s_decode_int(d, 4u, "-") == -1, "bare sign rejected");
CHECK(s_decode_int(d, 4u, "1.5") == -1, "decimal point rejected");
CHECK(s_decode_int(d, 4u, "0x10") == -1, "hex text rejected");
CHECK(s_decode_int(d, 1u, "-129") == -1, "int8 -129 rejected");
CHECK(s_decode_int(d, 1u, "128") == -1, "int8 128 rejected");
CHECK(s_decode_int(d, 2u, "-32769") == -1, "int16 -32769 rejected");
CHECK(s_decode_int(d, 2u, "32768") == -1, "int16 32768 rejected");
CHECK(s_decode_int(d, 4u, "2147483648") == -1, "INT32_MAX + 1 rejected (ERANGE)");
CHECK(s_decode_int(d, 4u, "-2147483649") == -1, "INT32_MIN - 1 rejected (ERANGE)");
CHECK(s_decode_int(d, 4u, "99999999999") == -1, "huge magnitude rejected (ERANGE)");
CHECK(s_decode_int(d, 4u, "-99999999999") == -1, "huge negative rejected (ERANGE)");
CHECK(s_decode_int(d, 3u, "1") == -1, "invalid len 3 rejected");
}
/* TC-CONFIG-008:INT 编码带负号 + [sys] 段 load/save/load 全链往返 */
static void tc_int_encode(void) {
char buf[24];
uint8_t field[4];
static const cfg_key_def_t k32 = { "ofs32", CFG_VAL_INT, 0u, 4u };
static const cfg_key_def_t k8 = { "ofs8", CFG_VAL_INT, 0u, 1u };
printf("[TC-CONFIG-008] INT encode (sign in text)\n");
field[0] = 0xFFu; field[1] = 0xFFu; field[2] = 0xFFu; field[3] = 0xFFu;
CHECK(s_encode(&k32, field, buf, sizeof(buf)) > 0 && strcmp(buf, "-1") == 0,
"FFFFFFFF encodes -1");
field[0] = 0x00u; field[1] = 0x00u; field[2] = 0x00u; field[3] = 0x80u;
CHECK(s_encode(&k32, field, buf, sizeof(buf)) > 0 &&
strcmp(buf, "-2147483648") == 0, "INT32_MIN bytes encode with sign");
field[0] = 0xFFu; field[1] = 0xFFu; field[2] = 0xFFu; field[3] = 0x7Fu;
CHECK(s_encode(&k32, field, buf, sizeof(buf)) > 0 &&
strcmp(buf, "2147483647") == 0, "INT32_MAX bytes encode");
field[0] = 0x80u;
CHECK(s_encode(&k8, field, buf, sizeof(buf)) > 0 && strcmp(buf, "-128") == 0,
"int8 0x80 encodes -128");
field[0] = 0x7Fu;
CHECK(s_encode(&k8, field, buf, sizeof(buf)) > 0 && strcmp(buf, "127") == 0,
"int8 0x7F encodes 127");
printf("[TC-CONFIG-008] INT section roundtrip (load -> save -> load)\n");
vfs_reset();
register_std();
CHECK(cfg_file_load() == 0, "load creates template");
CHECK(strstr(vfs_get(), "ofs32=-2147483648") != NULL,
"template INT32_MIN default written with sign");
CHECK(strstr(vfs_get(), "ofs8=-5") != NULL, "template int8 default -5");
s_sys_data.ofs32 = -123456;
s_sys_data.ofs16 = -2;
s_sys_data.ofs8 = -128;
CHECK(cfg_file_save() == 0, "save with negatives");
CHECK(strstr(vfs_get(), "ofs32=-123456") != NULL, "negative saved with sign");
CHECK(strstr(vfs_get(), "ofs8=-128") != NULL, "int8 -128 saved");
s_sys_data.ofs32 = 1;
s_sys_data.ofs16 = 1;
s_sys_data.ofs8 = 1;
CHECK(cfg_file_load() == 0, "reload ok");
CHECK(s_sys_data.ofs32 == -123456 && s_sys_data.ofs16 == -2 &&
s_sys_data.ofs8 == -128, "INT values roundtrip identical");
/* 越界文本 = 该键拒绝、留工厂默认并留痕;同段其余键不受牵连 */
vfs_reset();
register_std();
vfs_put("[sys]\r\nbaud=9600\r\nofs32=2147483648\r\nofs8=-129\r\nofs16=-300\r\n");
CHECK(cfg_file_load() == 0, "load with out-of-range INT keys");
CHECK(s_sys_data.ofs32 == s_sys_def.ofs32, "out-of-range ofs32 keeps default");
CHECK(s_sys_data.ofs8 == s_sys_def.ofs8, "out-of-range ofs8 keeps default");
CHECK(s_sys_data.ofs16 == -300, "valid ofs16 in same section parsed");
CHECK(s_sys_data.baud == 9600u, "UINT key beside INT parsed");
}
/* TC-CONFIG-010~015:INI 解析 */
static void tc_parse(void) {
printf("[TC-CONFIG-010..015] INI parsing via load\n");
@@ -522,6 +632,7 @@ static void tc_register(void) {
{
cfg_section_reg_t r;
static const cfg_key_def_t bad_uint[] = { { "k", CFG_VAL_UINT, 0u, 3u } };
static const cfg_key_def_t bad_int[] = { { "k", CFG_VAL_INT, 0u, 3u } };
static const cfg_key_def_t bad_mac[] = { { "k", CFG_VAL_MAC, 0u, 4u } };
static const cfg_key_def_t bad_str[] = { { "k", CFG_VAL_STR, 0u, 80u } };
static const cfg_key_def_t zero_len[] = { { "k", CFG_VAL_UINT, 0u, 0u } };
@@ -536,6 +647,8 @@ static void tc_register(void) {
r.p_keys = bad_uint;
CHECK(cfg_file_register(&r) == -1, "UINT len=3 rejected");
r.p_keys = bad_int;
CHECK(cfg_file_register(&r) == -1, "INT len=3 rejected");
r.p_keys = bad_mac;
CHECK(cfg_file_register(&r) == -1, "MAC len=4 rejected");
r.p_keys = bad_str;
@@ -859,6 +972,8 @@ int main(void) {
printf("=== Config File Tests ===\n");
tc_uint();
tc_int_decode();
tc_int_encode();
tc_ip4();
tc_mac();
tc_str();