feat(adc): 新增变比维 r 三维折算,录波段格式升 v2
采样板注入 Ua=5V/Ia=0.5A 读数偏小,根因是固件只输出引脚电压、 缺「端子→引脚」变比。折算改三维: 工程量 = (code + b) × k[µV/码] × 1e-6 × r k 保持 ROM 引脚 LSB,b 为零点,r 为端子变比(int32 Q16)。 变比不能并进 k:UA 端子域 k 达 1.5e5 µV/码、Q16 溢出 int32; r 单独存 Q16 不溢出。两点标定改标 r,k 仍是板级事实。 - 新开单段 [adc_cal_sec](8 键 r_ua..r_in),cfg 段数达 8/8 上限 - 一次变比复用 prot_set 四项,不新开段;r=0 表示本路不折算 - ROM 默认带台架实测变比(电压族 1000、电流族 29.4118), 烧进固件即显二次值;VALID 仍须两点标定,两者互不派生 - eng 判据改「每路要么已配变比、要么削顶不显示」,不再看 VALID - 104 地址 0x8050~0x8057 写 r,run_par_cal_r_set 写值与置脏同函数 - 录波 v2:通道表加 int32 r_q16,头 128→160、整段 5250→5282; code_to_milli 用余数分解换等价单次圆整,20 万组大整数对拍 0 不符 - 文档同步:采集与算法层/通道映射/故障录波/网络配置/配置文件/ 产品需求/内存台账,历史带日期实测数字按冻结口径不改 - 单测 13 套全绿,/keil-build 0 错误 0 警告(256024/31760/ 2080/152368),RAM 实测回填内存内容分配策略 §6.1
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
做什么:
|
||||
用本机 MSVC 编译 test/host/wave_store/wave_store_test.c(它以 #include 纳入
|
||||
**生产源文件** App/algo/wave_store.c),在 PC 上离线跑 CRC-16/MODBUS 规范锚点、
|
||||
整段长度等式(32 + 12*ch + pts*ch*2 + 2 == 5250)、段头编解码往返、拒绝清单、
|
||||
整段长度等式(32 + 16*ch + pts*ch*2 + 2 == 5282)、段头编解码往返、拒绝清单、
|
||||
按通道分列的偏移换算、打包游标三段推进与四条拒绝路径、自产字节自检、段文件名
|
||||
轮转与反解,失败即非 0 退出。零硬件、零烧录、毫秒级。顺带把一段合成段写到 %TEMP%
|
||||
供 PC 侧读段脚本(test/host/wave_read.py)做只读互验(不参与判定)。
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
*
|
||||
* 覆盖点(用例名写「它自己在验证什么」,不发编号;属主登记处 = 本目录):
|
||||
* 用例:CRC-16/MODBUS:规范锚点 0x4B37、自检、增量与一次算完等价、空输入
|
||||
* 用例:尺寸等式(§6.3 / lead 点名):32 + 12*ch + pts*ch*2 + 2 == 5250,
|
||||
* 头 CRC 位置 126、数据区起点 128、9 路 1000 点变体同样成立
|
||||
* 用例:尺寸等式(§6.3 / lead 点名):32 + 16*ch + pts*ch*2 + 2 == 5282,
|
||||
* 头 CRC 位置 158、数据区起点 160、9 路 1000 点变体同样成立
|
||||
* 用例:meta_init 默认值与通道表:sem = 下标、conv/bits 两片转换器映射、
|
||||
* 封存瞬间事实留 0;0xE6 的算术交叉验证(通道顺序证据)
|
||||
* 用例:段头编解码往返:13 个标量 + 8 项表逐字段,含负系数与大 wall
|
||||
@@ -63,19 +63,40 @@ static wave_seg_meta_t s_meta;
|
||||
static wave_seg_meta_t s_back;
|
||||
|
||||
/*
|
||||
* 段头单位标签与逐路有效位图的**平台派生式**(本体在 App/app/ui_data_feed.c 的 feed_eng(),
|
||||
* 段头填写在 App/task/adc_task.c 的 532 至 553 行):电气 8 路全 VALID 才升二次值档位,
|
||||
* 否则停在引脚域。本层不参与这条派生(wave_store 不链 adc_cal),放这里只为钉一件事:
|
||||
* **夹具必须与平台派生式自洽**。一份真机写不出来的字节,验的是两个读者对不可能状态的
|
||||
* 行为,正好掩盖真正的分歧(lead 裁定 2026-10-29,本套上一版就把 eng 留成引脚域而
|
||||
* flags_seq 全置位,那份构造段没资格当互验夹具)。
|
||||
* 段头单位标签的**平台派生式**(本体在 App/task/adc_task.c 的封存交棒块,
|
||||
* 口径说明在 App/app/ui_data_feed.c 的 feed_eng()):每一路电气量「要么已配变比、
|
||||
* 要么削顶(页面本来就显 '-',不参与整帧量纲断言)」,八路全满足才升二次值档位。
|
||||
*
|
||||
* ⚠ v2 之前这条派生式看的是 flags_seq(八路全 VALID);加了变比维之后判据换成
|
||||
* **r_q16 是否已配**:VALID 回答「准不准」、r 回答「什么单位」,V0.1 五路削顶永远
|
||||
* 拿不到 VALID,用 VALID 当量纲判据会让档位永不解除。本夹具必须跟着平台派生式走
|
||||
* (lead 裁定 2026-10-29:一份真机写不出来的字节,验的是两个读者对不可能状态的行为,
|
||||
* 正好掩盖真正的分歧)。削顶位取表内 avail 的 CLIPPED 位(= adc_cal_flags 原值透传)。
|
||||
*/
|
||||
static uint8_t expect_eng(uint8_t a_flags_seq) {
|
||||
return (a_flags_seq == 0xFFu) ? (uint8_t)WAVE_ENG_SEC : (uint8_t)WAVE_ENG_PIN;
|
||||
static uint8_t expect_eng(const wave_seg_meta_t *p_m) {
|
||||
uint8_t i;
|
||||
uint8_t all_ok = 1u;
|
||||
|
||||
for (i = 0u; i < p_m->ch_count; i++) {
|
||||
if (((p_m->ch[i].avail & 0x02u) == 0u) && (p_m->ch[i].r_q16 == 0)) {
|
||||
all_ok = 0u;
|
||||
}
|
||||
}
|
||||
return (all_ok != 0u) ? (uint8_t)WAVE_ENG_SEC : (uint8_t)WAVE_ENG_PIN;
|
||||
}
|
||||
|
||||
static int eng_selfconsistent(const wave_seg_meta_t *p_m) {
|
||||
return (p_m->eng == expect_eng(p_m->flags_seq)) ? 1 : 0;
|
||||
return (p_m->eng == expect_eng(p_m)) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* 字节级:把整头解出来再看派生式是否成立(判据只看已落进字节的事实) */
|
||||
static int head_eng_consistent(const uint8_t *p_head) {
|
||||
wave_seg_meta_t m;
|
||||
|
||||
if (wave_store_head_parse(p_head, (uint32_t)WAVE_ST_HEAD_SZ_CUR, &m) != WAVE_ST_OK) {
|
||||
return 0;
|
||||
}
|
||||
return (m.eng == expect_eng(&m)) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* 一份「像样的」段头:格式侧默认值 + 封存瞬间事实(与 PC 侧口径一致) */
|
||||
@@ -104,6 +125,11 @@ static void fill_meta(wave_seg_meta_t *p_m) {
|
||||
* 解码器不据此判废(lead 裁定 2026-10-29)。削顶位与 clip_mask 的对应关系仍要保持
|
||||
* 自洽(bit1 = 削顶,聚合起来正好 0xE6),那是数据自身的一致性,不是格式不变式。 */
|
||||
p_m->ch[i].avail = (uint8_t)(tpa ? 0x01u : 0x03u);
|
||||
/* v2:变比维。本份「已标定后仍削顶」形态里,非削顶的三路 TPAFE 已配变比
|
||||
* (ROM 电压族 65536000 = 1000.0),削顶的五路片内 ADC 也照 ROM 电流族
|
||||
* (1927532)填上 —— 削顶与否不影响整帧量纲断言,但填了才与 eng = 二次值
|
||||
* 自洽(见 expect_eng)。真值形态(一路都没配变比、eng = 引脚域)由 v01 覆盖。 */
|
||||
p_m->ch[i].r_q16 = tpa ? 65536000 : 1927532;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +232,8 @@ static int meta_same(const wave_seg_meta_t *p_a, const wave_seg_meta_t *p_b) {
|
||||
for (i = 0u; i < p_a->ch_count; i++) {
|
||||
if ((p_a->ch[i].sem != p_b->ch[i].sem) || (p_a->ch[i].conv != p_b->ch[i].conv) ||
|
||||
(p_a->ch[i].bits != p_b->ch[i].bits) || (p_a->ch[i].avail != p_b->ch[i].avail) ||
|
||||
(p_a->ch[i].k_q16 != p_b->ch[i].k_q16) || (p_a->ch[i].b_codes != p_b->ch[i].b_codes)) {
|
||||
(p_a->ch[i].k_q16 != p_b->ch[i].k_q16) || (p_a->ch[i].b_codes != p_b->ch[i].b_codes) ||
|
||||
(p_a->ch[i].r_q16 != p_b->ch[i].r_q16)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -241,23 +268,23 @@ int main(void) {
|
||||
|
||||
/* ---------- 用例:尺寸等式 ---------- */
|
||||
printf("-- 用例:尺寸等式 --\n");
|
||||
CHECK(WAVE_ST_HEAD_CRC_POS(8u) == 126u, "头 CRC 位置 = 30 + 12*8");
|
||||
CHECK(WAVE_ST_HEAD_BYTES(8u) == 128u, "整头 = 128 字节");
|
||||
CHECK(WAVE_ST_HEAD_CRC_POS(8u) == 158u, "头 CRC 位置 = 30 + 16*8");
|
||||
CHECK(WAVE_ST_HEAD_BYTES(8u) == 160u, "整头 = 160 字节");
|
||||
CHECK(WAVE_ST_HEAD_SZ_CUR == WAVE_ST_HEAD_BYTES((uint8_t)WAVE_ST_CH_NUM), "当前值宏与参数化宏同源");
|
||||
CHECK(WAVE_ST_DATA_BYTES(8u, 320u) == 5120u, "数据区 = 5120 字节");
|
||||
CHECK(WAVE_ST_SEG_TOTAL(8u, 320u) == 5250u, "整段 = 5250 字节");
|
||||
CHECK(WAVE_ST_SEG_TOTAL(8u, 320u) == 5282u, "整段 = 5282 字节");
|
||||
CHECK(WAVE_ST_SEG_SZ_CUR == WAVE_ST_SEG_TOTAL((uint8_t)WAVE_ST_CH_NUM, (uint16_t)WAVE_ST_PTS_DEF),
|
||||
"整段当前值宏与参数化宏同源");
|
||||
CHECK((32u + (12u * 8u) + (320u * 8u * 2u) + 2u) == 5250u,
|
||||
"等式 32 + 12*ch + pts*ch*2 + 2 == 5250(接线道拿它比对 f_write 写回数)");
|
||||
CHECK(WAVE_ST_SEG_TOTAL(9u, 1000u) == (32u + 108u + 18000u + 2u), "9 路 1000 点变体同式(每周波点数是数据)");
|
||||
CHECK((32u + (16u * 8u) + (320u * 8u * 2u) + 2u) == 5282u,
|
||||
"等式 32 + 16*ch + pts*ch*2 + 2 == 5282(接线道拿它比对 f_write 写回数)");
|
||||
CHECK(WAVE_ST_SEG_TOTAL(9u, 1000u) == (32u + 144u + 18000u + 2u), "9 路 1000 点变体同式(每周波点数是数据)");
|
||||
fill_meta(&s_meta);
|
||||
CHECK(wave_store_seg_size(&s_meta) == 5250u, "seg_size 按头字段算出 5250");
|
||||
CHECK(wave_store_head_bytes(8u) == 128u, "head_bytes(8)");
|
||||
CHECK(wave_store_seg_size(&s_meta) == 5282u, "seg_size 按头字段算出 5282");
|
||||
CHECK(wave_store_head_bytes(8u) == 160u, "head_bytes(8)");
|
||||
CHECK((wave_store_head_bytes(0u) == 0u) && (wave_store_head_bytes(10u) == 0u), "非法通道数返回 0");
|
||||
CHECK(wave_store_data_off(8u, 320u, 0u, 0u) == 128u, "第 0 列点 0 从整头之后开始");
|
||||
CHECK(wave_store_data_off(8u, 320u, 1u, 0u) == (128u + 640u), "按通道分列:第 1 列 = 128 + 320*2");
|
||||
CHECK(wave_store_data_off(8u, 320u, 7u, 319u) == (5250u - 2u - 2u), "最后一列最后一点贴数据 CRC");
|
||||
CHECK(wave_store_data_off(8u, 320u, 0u, 0u) == 160u, "第 0 列点 0 从整头之后开始");
|
||||
CHECK(wave_store_data_off(8u, 320u, 1u, 0u) == (160u + 640u), "按通道分列:第 1 列 = 160 + 320*2");
|
||||
CHECK(wave_store_data_off(8u, 320u, 7u, 319u) == (5282u - 2u - 2u), "最后一列最后一点贴数据 CRC");
|
||||
CHECK(wave_store_data_off(0u, 320u, 0u, 0u) == 0xFFFFFFFFu, "通道数非法 -> 哨兵");
|
||||
CHECK(wave_store_data_off(8u, 320u, 8u, 0u) == 0xFFFFFFFFu, "列号越界 -> 哨兵");
|
||||
CHECK(wave_store_data_off(8u, 320u, 0u, 320u) == 0xFFFFFFFFu, "点越界 -> 哨兵");
|
||||
@@ -286,13 +313,14 @@ int main(void) {
|
||||
if ((s_back.ch[i].conv != want_conv[i]) || (s_back.ch[i].bits != want_bits[i])) {
|
||||
ok_map = 0;
|
||||
}
|
||||
if ((s_back.ch[i].avail != 0u) || (s_back.ch[i].k_q16 != 0) || (s_back.ch[i].b_codes != 0)) {
|
||||
if ((s_back.ch[i].avail != 0u) || (s_back.ch[i].k_q16 != 0) ||
|
||||
(s_back.ch[i].b_codes != 0) || (s_back.ch[i].r_q16 != 0)) {
|
||||
ok_zero = 0;
|
||||
}
|
||||
}
|
||||
CHECK(ok_sem != 0, "sem = 下标(PC 侧必须校验的一条)");
|
||||
CHECK(ok_map != 0, "conv/bits 映射:UA UN IA = TPAFE 16 位,其余五路 = 片内 ADC 12 位");
|
||||
CHECK(ok_zero != 0, "avail / k_q16 / b_codes 留 0 等 adcTask 现取现填(本层不链 adc_cal)");
|
||||
CHECK(ok_zero != 0, "avail / k_q16 / b_codes / r_q16 留 0 等 adcTask 现取现填(本层不链 adc_cal)");
|
||||
}
|
||||
{
|
||||
uint16_t m = (uint16_t)((1u << 1) | (1u << 2) | (1u << 5) | (1u << 6) | (1u << 7));
|
||||
@@ -326,6 +354,8 @@ int main(void) {
|
||||
for (i = 0u; i < v01.ch_count; i++) {
|
||||
/* 三路 TPAFE 既不VALID也不削顶;五路片内 ADC 削顶但未标定 */
|
||||
v01.ch[i].avail = (uint8_t)(((i == 0u) || (i == 3u) || (i == 4u)) ? 0x00u : 0x02u);
|
||||
/* 真值形态:一路都没配变比(V0.1 无 CT/PT 变比),与 eng = 引脚域自洽 */
|
||||
v01.ch[i].r_q16 = 0;
|
||||
}
|
||||
/* 注意:head_build 成功时返回的是写出的字节数(不是 WAVE_ST_OK)——
|
||||
* 与 wave_ring_read_ch 同一类「返回实际长度」的契约 */
|
||||
@@ -361,25 +391,44 @@ int main(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK(buf[WAVE_ST_OFF_ENG] == expect_eng(buf[WAVE_ST_OFF_FLAGS]),
|
||||
"构造形态落进字节之后 eng 与逐路有效位图仍自洽");
|
||||
CHECK(head_eng_consistent(buf) != 0,
|
||||
"构造形态落进字节之后 eng 与逐路变比仍自洽");
|
||||
fill_meta(&v01);
|
||||
v01.flags_seq = 0x00u;
|
||||
v01.eng = (uint8_t)WAVE_ENG_PIN;
|
||||
for (i = 0u; i < v01.ch_count; i++) {
|
||||
v01.ch[i].avail = (uint8_t)(((i == 0u) || (i == 3u) || (i == 4u)) ? 0x00u : 0x02u);
|
||||
v01.ch[i].r_q16 = 0; /* 一路都没配变比 -> 引脚域 */
|
||||
}
|
||||
if ((wave_store_head_build(&v01, buf, (uint32_t)sizeof(buf)) == (int)WAVE_ST_HEAD_SZ_CUR) &&
|
||||
(buf[WAVE_ST_OFF_ENG] == (uint8_t)WAVE_ENG_PIN) &&
|
||||
(buf[WAVE_ST_OFF_FLAGS] == 0x00u)) {
|
||||
CHECK(buf[WAVE_ST_OFF_ENG] == expect_eng(buf[WAVE_ST_OFF_FLAGS]),
|
||||
"本波真值形态落进字节之后 eng 仍停引脚域(0x00 不是 0xFF,不许谎报二次值)");
|
||||
CHECK(head_eng_consistent(buf) != 0,
|
||||
"本波真值形态落进字节之后 eng 仍停引脚域(变比全 0,不许谎报二次值)");
|
||||
} else {
|
||||
CHECK(0, "本波真值形态编码后 eng 与逐路有效位图字节不符");
|
||||
}
|
||||
CHECK(expect_eng(0xFFu) == (uint8_t)WAVE_ENG_SEC, "派生式:电气 8 路全有效才升二次值档位");
|
||||
CHECK(expect_eng(0x00u) == (uint8_t)WAVE_ENG_PIN, "派生式:一路都没标定则停引脚域");
|
||||
CHECK(expect_eng(0x7Fu) == (uint8_t)WAVE_ENG_PIN, "派生式:部分标定(缺 IN 那一路)整帧仍算引脚域");
|
||||
CHECK(eng_selfconsistent(&v01) != 0, "夹具自洽:真值形态(全零 / 引脚域)");
|
||||
CHECK(eng_selfconsistent(&both) != 0, "夹具自洽:构造形态(全有效 / 二次值)");
|
||||
CHECK(eng_selfconsistent(&v01) != 0, "夹具自洽:真值形态(变比全 0 / 引脚域)");
|
||||
CHECK(eng_selfconsistent(&both) != 0, "夹具自洽:构造形态(变比全配 / 二次值)");
|
||||
CHECK(eng_selfconsistent(&s_meta) != 0, "夹具自洽:本套所有合成段共用的那份段头");
|
||||
/* 派生式的三档探针(用段头对象探,不依赖字节):元本体是「每路要么已配变比、
|
||||
* 要么削顶不显示」——削顶那几路配不配变比都不影响结论 */
|
||||
{
|
||||
wave_seg_meta_t p;
|
||||
|
||||
fill_meta(&p);
|
||||
CHECK(expect_eng(&p) == (uint8_t)WAVE_ENG_SEC,
|
||||
"派生式:非削顶的八路都配了变比 -> 二次值档位");
|
||||
fill_meta(&p);
|
||||
p.ch[7].avail = 0x00u; /* IN 非削顶 */
|
||||
p.ch[7].r_q16 = 0; /* 且没配变比 */
|
||||
CHECK(expect_eng(&p) == (uint8_t)WAVE_ENG_PIN,
|
||||
"派生式:一路非削顶且无变比 -> 整帧仍算引脚域");
|
||||
fill_meta(&p);
|
||||
p.ch[7].r_q16 = 0; /* 只清变比,仍削顶 */
|
||||
CHECK(expect_eng(&p) == (uint8_t)WAVE_ENG_SEC,
|
||||
"派生式:削顶那路配不配变比都不影响(页面本来就显 '-',不参与整帧量纲断言)");
|
||||
}
|
||||
/* 反证本层**不参与**单位标签派生:故意造一份违反派生式的段头(全有效却仍标引脚域),
|
||||
* 编码与解码都该照样通过——判废只留给完整性判据,派生式不一致是 PC 侧软告警的活。
|
||||
* 这份只当探针用,绝不写进任何互验产物(真机写不出这串字节) */
|
||||
@@ -409,24 +458,38 @@ int main(void) {
|
||||
fill_meta(&s_meta);
|
||||
s_meta.ch[0].k_q16 = 10000000;
|
||||
s_meta.ch[0].b_codes = -8192;
|
||||
s_meta.ch[0].r_q16 = 0;
|
||||
s_meta.ch[7].k_q16 = 52800000;
|
||||
s_meta.ch[7].b_codes = 8191;
|
||||
/* v2:变比原值往返(含 ROM 默认的电压族 65536000 = 1000.0 V/V 与电流族
|
||||
* 1927532 = 29.4118 A/V);0 也要能往返(= 本路不折算,不是缺省) */
|
||||
s_meta.ch[0].r_q16 = 65536000;
|
||||
s_meta.ch[1].r_q16 = 1927532;
|
||||
s_meta.ch[2].r_q16 = 0;
|
||||
s_meta.wall = 0xFFFFFFFFu;
|
||||
s_meta.frame_seq = 0u;
|
||||
{
|
||||
uint32_t hn = build_head();
|
||||
CHECK(hn == 128u, "head_build 产出整头 128 字节");
|
||||
CHECK(hn == 160u, "head_build 产出整头 160 字节");
|
||||
CHECK((s_img[0] == (uint8_t)WAVE_ST_MAGIC0) && (s_img[1] == (uint8_t)WAVE_ST_MAGIC1) &&
|
||||
(s_img[2] == (uint8_t)WAVE_ST_VER), "魔数 = 57 52 01(第三字节就是版本号)");
|
||||
(s_img[2] == (uint8_t)WAVE_ST_VER), "魔数 = 57 52 02(第三字节就是版本号)");
|
||||
CHECK(WAVE_ST_VER == 2u, "格式版本 = 2(通道表 16 字节/路)");
|
||||
CHECK(s_img[WAVE_ST_OFF_VER] == s_img[WAVE_ST_OFF_MAGIC + 2u], "ver 字段与魔数第三字节同值");
|
||||
CHECK((s_img[30u + (12u * 8u)] != 0u) || (s_img[31u + (12u * 8u)] != 0u), "头 CRC 落在 126/127");
|
||||
CHECK((s_img[30u + (16u * 8u)] != 0u) || (s_img[31u + (16u * 8u)] != 0u), "头 CRC 落在 158/159");
|
||||
{
|
||||
uint16_t crc = wave_store_crc(s_img, 126u);
|
||||
CHECK((s_img[126] == (uint8_t)(crc & 0xFFu)) && (s_img[127] == (uint8_t)(crc >> 8)),
|
||||
uint16_t crc = wave_store_crc(s_img, 158u);
|
||||
CHECK((s_img[158] == (uint8_t)(crc & 0xFFu)) && (s_img[159] == (uint8_t)(crc >> 8)),
|
||||
"头 CRC 低字节在前(§6.3)");
|
||||
}
|
||||
CHECK(wave_store_head_parse(s_img, hn, &s_back) == WAVE_ST_OK, "head_parse OK");
|
||||
CHECK(meta_same(&s_meta, &s_back) != 0, "13 个标量 + 8 项表逐字段往返一致(含负系数)");
|
||||
CHECK(meta_same(&s_meta, &s_back) != 0, "13 个标量 + 8 项表逐字段往返一致(含负系数与 r_q16)");
|
||||
/* v2 新增断言:段头往返后 r_q16 原值不变(int32 原值,不经 float) */
|
||||
CHECK((s_back.ch[0].r_q16 == 65536000) && (s_back.ch[1].r_q16 == 1927532) &&
|
||||
(s_back.ch[2].r_q16 == 0), "段头往返后 r_q16 原值不变(1000.0 / 29.4118 / 不折算)");
|
||||
/* r_q16 落在 12 字节偏移、小端 int32 */
|
||||
CHECK((s_img[30u + WAVE_ST_CH_OFF_RQ16 + 0u] == 0x00u) &&
|
||||
(s_img[30u + WAVE_ST_CH_OFF_RQ16 + 3u] == 0x03u),
|
||||
"r_q16 在表项偏移 12、小端(65536000 = 0x03E80000)");
|
||||
}
|
||||
|
||||
/* ---------- 用例:拒绝清单 ---------- */
|
||||
@@ -476,7 +539,7 @@ int main(void) {
|
||||
m.trig_src = 5u;
|
||||
CHECK(wave_store_head_build(&m, s_img, IMG_CAP) == WAVE_ST_E_FORMAT, "触发源 5 拒");
|
||||
fill_meta(&m);
|
||||
CHECK(wave_store_head_build(&m, s_img, 127u) == WAVE_ST_E_PARAM, "缓冲装不下整头拒");
|
||||
CHECK(wave_store_head_build(&m, s_img, 159u) == WAVE_ST_E_PARAM, "缓冲装不下整头拒");
|
||||
CHECK(wave_store_head_build(NULL, s_img, IMG_CAP) == WAVE_ST_E_PARAM, "空段头指针拒");
|
||||
CHECK(wave_store_seg_size(NULL) == 0u, "seg_size 空指针返 0");
|
||||
}
|
||||
@@ -485,18 +548,18 @@ int main(void) {
|
||||
{
|
||||
uint32_t hn = build_head();
|
||||
uint8_t save = s_img[0];
|
||||
CHECK(hn == 128u, "参考头重编 OK");
|
||||
CHECK(hn == 160u, "参考头重编 OK");
|
||||
s_img[0] = (uint8_t)'X';
|
||||
CHECK(wave_store_head_parse(s_img, hn, &s_back) == WAVE_ST_E_FORMAT, "魔数第一字节错 -> 格式错");
|
||||
s_img[0] = save;
|
||||
s_img[WAVE_ST_OFF_VER] = 2u;
|
||||
s_img[WAVE_ST_OFF_VER] = 3u;
|
||||
CHECK(wave_store_head_parse(s_img, hn, &s_back) == WAVE_ST_E_FORMAT,
|
||||
"ver 与魔数第三字节不一致 -> 格式错(不许按新布局猜)");
|
||||
s_img[WAVE_ST_OFF_VER] = (uint8_t)WAVE_ST_VER;
|
||||
s_img[WAVE_ST_OFF_MAGIC + 2u] = 2u;
|
||||
CHECK(wave_store_head_parse(s_img, hn, &s_back) == WAVE_ST_E_FORMAT, "版本号 2 -> 拒");
|
||||
s_img[WAVE_ST_OFF_MAGIC + 2u] = 1u;
|
||||
CHECK(wave_store_head_parse(s_img, hn, &s_back) == WAVE_ST_E_FORMAT, "版本号 1(老 v1 段)-> 拒");
|
||||
s_img[WAVE_ST_OFF_MAGIC + 2u] = (uint8_t)WAVE_ST_VER;
|
||||
CHECK(wave_store_head_parse(s_img, 127u, &s_back) == WAVE_ST_E_PARAM, "缓冲不足整头 -> 参数错");
|
||||
CHECK(wave_store_head_parse(s_img, 159u, &s_back) == WAVE_ST_E_PARAM, "缓冲不足整头 -> 参数错");
|
||||
CHECK(wave_store_head_parse(s_img, 7u, &s_back) == WAVE_ST_E_PARAM, "连通道数字节都读不到 -> 参数错");
|
||||
s_img[40] = (uint8_t)(s_img[40] ^ 0xA5u);
|
||||
CHECK(wave_store_head_parse(s_img, hn, &s_back) == WAVE_ST_E_CRC, "头覆盖区被改一字节 -> CRC 不符");
|
||||
@@ -520,7 +583,8 @@ int main(void) {
|
||||
{
|
||||
wave_ch_desc_t d;
|
||||
int32_t mv = 0;
|
||||
d.sem = 0u; d.conv = 0u; d.bits = 16u; d.avail = 1u; d.k_q16 = 10000000; d.b_codes = 0;
|
||||
d.sem = 0u; d.conv = 0u; d.bits = 16u; d.avail = 1u;
|
||||
d.k_q16 = 10000000; d.b_codes = 0; d.r_q16 = 0;
|
||||
CHECK(wave_store_code_to_milli(&d, 0, &mv) == WAVE_ST_OK, "TPAFE 零点折算 OK");
|
||||
CHECK(mv == 0, "零点 = 0 mV");
|
||||
(void)wave_store_code_to_milli(&d, 9261, &mv);
|
||||
@@ -539,6 +603,36 @@ int main(void) {
|
||||
CHECK(mv == 0, "系数没填时幅值归零(形状仍在,PC 侧会看到平线)");
|
||||
CHECK(wave_store_code_to_milli(NULL, 0, &mv) == WAVE_ST_E_PARAM, "空表项拒");
|
||||
CHECK(wave_store_code_to_milli(&d, 0, NULL) == WAVE_ST_E_PARAM, "空输出拒");
|
||||
|
||||
/* ---- v2:变比维(口径锚点三条,都必须与 PC 解码器同解) ---- */
|
||||
d.k_q16 = 10000000;
|
||||
d.b_codes = 0;
|
||||
(void)wave_store_code_to_milli(&d, 9261, &mv);
|
||||
{
|
||||
int32_t pin = mv; /* r_q16 = 0:引脚域基准 */
|
||||
d.r_q16 = 65536; /* 比值 1.0 */
|
||||
(void)wave_store_code_to_milli(&d, 9261, &mv);
|
||||
CHECK((pin == 1413) && (mv == pin), "r_q16 = 65536(1.0)与 r_q16 = 0 的引脚域逐位一致");
|
||||
d.r_q16 = 0;
|
||||
(void)wave_store_code_to_milli(&d, -9261, &mv);
|
||||
CHECK(mv == -1413, "r_q16 = 0 退化成引脚域(负半周同理)");
|
||||
d.r_q16 = 65536;
|
||||
(void)wave_store_code_to_milli(&d, -9261, &mv);
|
||||
CHECK(mv == -1413, "r_q16 = 1.0 时负半周同样与引脚域一致(不是 -1414)");
|
||||
}
|
||||
d.r_q16 = 65536000; /* 1000.0 V/V:ROM 电压族默认 */
|
||||
(void)wave_store_code_to_milli(&d, 9261, &mv);
|
||||
/* 精确值 = 1413.116 mV × 1000 = 1413116(**不是** 先圆整再乘的 1413000 ——
|
||||
* 这正是「只在最后圆整一次」的可观测证据:中间圆整会少掉 116 个毫单位) */
|
||||
CHECK(mv == 1413116, "r_q16 = 65536000(1000.0)时放大 1000 倍(1413.116 -> 1413116)");
|
||||
(void)wave_store_code_to_milli(&d, -9261, &mv);
|
||||
CHECK(mv == -1413116, "放大 1000 倍在负半周同样成立(符号不错)");
|
||||
d.r_q16 = 1927532; /* 29.4118 A/V:ROM 电流族默认 */
|
||||
d.k_q16 = 10000000;
|
||||
(void)wave_store_code_to_milli(&d, 9261, &mv);
|
||||
/* 1413 mV * 29.4118 = 41562 毫单位(二次域 mA) */
|
||||
CHECK(mv == 41562, "r_q16 = 1927532(29.4118)时 9261 码 -> 41562 毫单位(二次 mA)");
|
||||
d.r_q16 = 0;
|
||||
}
|
||||
|
||||
/* ---------- 用例:打包游标 ---------- */
|
||||
@@ -550,15 +644,15 @@ int main(void) {
|
||||
s_read_calls = 0u;
|
||||
s_read_points = 0u;
|
||||
CHECK(pack_whole(256u, &len, &rc) == 0, "整段跑完(256 字节分片)");
|
||||
CHECK(s_img[WAVE_ST_OFF_ENG] == expect_eng(s_img[WAVE_ST_OFF_FLAGS]),
|
||||
"整段头字节自洽:写出去的 eng 与逐路有效位图满足平台派生式");
|
||||
CHECK(len == 5250u, "实际产出字节数 = 5250");
|
||||
CHECK(head_eng_consistent(s_img) != 0,
|
||||
"整段头字节自洽:写出去的 eng 与逐路变比满足平台派生式");
|
||||
CHECK(len == 5282u, "实际产出字节数 = 5282");
|
||||
CHECK(s_read_points == (320u * 8u), "数据源被取的点数 = 320*8(不多取不少取)");
|
||||
CHECK(s_read_calls == 40u, "每列 5 批 x 8 列 = 40 次回调(批量取数,不是逐点)");
|
||||
CHECK(wave_store_seg_check(s_img, len, &s_back) == WAVE_ST_OK, "自产字节过整段自检");
|
||||
CHECK(meta_same(&s_meta, &s_back) != 0, "自检回填的段头与原段头一致");
|
||||
{
|
||||
uint16_t dcrc = wave_store_crc(&s_img[128], 5120u);
|
||||
uint16_t dcrc = wave_store_crc(&s_img[160], 5120u);
|
||||
CHECK((s_img[len - 2u] == (uint8_t)(dcrc & 0xFFu)) && (s_img[len - 1u] == (uint8_t)(dcrc >> 8)),
|
||||
"数据 CRC 覆盖数据区、低字节在前、贴在文件尾");
|
||||
}
|
||||
@@ -566,8 +660,8 @@ int main(void) {
|
||||
{
|
||||
uint32_t len = 0u;
|
||||
int rc = 0;
|
||||
CHECK(pack_whole(128u, &len, &rc) == 0, "128 字节分片(= 整头那么大)也能跑完");
|
||||
CHECK(len == 5250u, "128 分片总长仍 5250(产出与分片大小无关)");
|
||||
CHECK(pack_whole(160u, &len, &rc) == 0, "160 字节分片(= 整头那么大)也能跑完");
|
||||
CHECK(len == 5282u, "160 分片总长仍 5282(产出与分片大小无关)");
|
||||
}
|
||||
{
|
||||
uint32_t len = 0u;
|
||||
@@ -579,10 +673,10 @@ int main(void) {
|
||||
uint32_t n = 99u;
|
||||
int rc;
|
||||
CHECK(wave_store_pack_start(&ctx, &s_meta, fake_reader, NULL) == WAVE_ST_OK, "pack_start OK");
|
||||
CHECK(wave_store_pack_next(&ctx, s_img, 127u, &n) == WAVE_ST_E_PARAM, "头一步容量不足 -> E_PARAM");
|
||||
CHECK(wave_store_pack_next(&ctx, s_img, 159u, &n) == WAVE_ST_E_PARAM, "头一步容量不足 -> E_PARAM");
|
||||
CHECK(n == 0u, "拒绝时一个字节都不产(不写半截头)");
|
||||
rc = wave_store_pack_next(&ctx, s_img, 256u, &n);
|
||||
CHECK((rc == WAVE_ST_OK) && (n == 128u), "同一游标重试成功(拒绝不留副作用)");
|
||||
CHECK((rc == WAVE_ST_OK) && (n == 160u), "同一游标重试成功(拒绝不留副作用)");
|
||||
rc = wave_store_pack_next(&ctx, s_img, 1u, &n);
|
||||
CHECK(rc == WAVE_ST_E_PARAM, "数据区容量装不下一个样本 -> 拒");
|
||||
CHECK(n == 0u, "同样不产半个样本的字节");
|
||||
@@ -603,7 +697,7 @@ int main(void) {
|
||||
int rc;
|
||||
CHECK(wave_store_pack_start(&ctx, &s_meta, NULL, NULL) == WAVE_ST_OK, "无数据源也能 start(只产头)");
|
||||
rc = wave_store_pack_next(&ctx, s_img, 256u, &n);
|
||||
CHECK((rc == WAVE_ST_OK) && (n == 128u), "头能产");
|
||||
CHECK((rc == WAVE_ST_OK) && (n == 160u), "头能产");
|
||||
rc = wave_store_pack_next(&ctx, s_img, 256u, &n);
|
||||
CHECK((rc == WAVE_ST_E_STATE) && (n == 0u),
|
||||
"没有数据源却进数据区 -> 拒且不产空字节(产空字节 = 伪造一条直线)");
|
||||
@@ -742,7 +836,7 @@ int main(void) {
|
||||
char path[512];
|
||||
FILE *fp;
|
||||
size_t wrote;
|
||||
CHECK(len == 5250u, "产物长度 5250");
|
||||
CHECK(len == 5282u, "产物长度 5282");
|
||||
if ((tmp != NULL) && (strlen(tmp) < 400u)) {
|
||||
strcpy(path, tmp);
|
||||
strcat(path, "\\wave_algo_synth8.bin");
|
||||
@@ -751,8 +845,8 @@ int main(void) {
|
||||
wrote = fwrite(s_img, 1u, len, fp);
|
||||
(void)fclose(fp);
|
||||
CHECK(wrote == (size_t)len, "合成段落盘成功");
|
||||
CHECK(s_img[WAVE_ST_OFF_ENG] == expect_eng(s_img[WAVE_ST_OFF_FLAGS]),
|
||||
"互验产物自洽:这份构造段的单位标签与逐路有效位图对得上(真机写得出)");
|
||||
CHECK(head_eng_consistent(s_img) != 0,
|
||||
"互验产物自洽:这份构造段的单位标签与逐路变比对得上(真机写得出)");
|
||||
/* 形态在日志里说清楚:本套是「同时带有效与削顶」的构造形态,
|
||||
* 本波真值形态(逐路有效位图全零、片内 ADC 只带削顶位)由 wave_trig 那套给 */
|
||||
printf(" [INFO] 互验产物(构造形态 = 已标定后仍削顶:逐路有效位图 0xFF、avail 0x01 / 0x03、"
|
||||
|
||||
Reference in New Issue
Block a user