test(NETCFG,CFG): P1①四个主机单测模块,并修 net_cfg 的 WAIT 契约与定长错记
按 docs/测试说明/主机单测覆盖率口径.md §9 的清单吃 P1 第①批「配置与工具」四块, 新增 4 个主机单测模块共 104 条断言,全部 MSVC 编译通过并 PASS: - test/host/net_cfg/(45 条):出厂默认可用、注册幂等与内容、load 报 -1 仍返回 0 (RAM 恒有效契约)、跨任务保存交接状态机 IDLE/WAIT/OK/FAIL、MAC 三态优先级、 IPv4 定长格式化。 - test/host/ftp_cfg/(16 条):[ftp] 段注册(**p_cb 必须为 NULL**,口令下次登录才 生效)、默认口令判定大小写不敏感、NULL 一律判不等(fail-closed)。 - test/host/prot_set_store/(16 条):blob 返回码分流 1 无档 / 0 成功 / **2 换代 (只打 INFO)** / -1 损坏;写盘失败必须回置脏标志(否则定值静默丢失)。 - test/host/task_prof/(27 条):无效样本闸门(防 DWT 复位把 max 抬到 2^32)、 未 enter 就 exit 不记账、首次 5s + 每 2s 节流、环形缓冲与裸发两通道、 周期→微秒换算随 SystemCoreClock 变。 覆盖率收益(已 --update-baseline 登记):套件 16 → 20 全绿;files_tested 19 → 23; 未触及 125 → 121 个文件(.c 47 → 43、9,657 → 9,228 行);分母 2,893 → 3,163 插桩 行;line=2811/3163(88.9%)、func=225/240(93.8%)。§9 的恒等式同步更新且仍咬合: 43 = 9(P1 剩) + 5(P2) + 29(P3)、9,228 = 2,188 + 2,226 + 4,814。 新单测照出并修掉两处真问题(都在 net_cfg,不是测试写错): 1. 实现违反自己的文档契约:net_cfg.h 明写"属主任务写盘中显示 WAIT",但 net_cfg_save_run 为了不丢新请求会先清 pending 再写盘 → 写盘那几百毫秒里 UI 保存行退回上一轮的 OK/IDLE(第一次保存按 ENTER 后屏幕上还是 ENTER),用户只 会再按一次。补 s_save_busy 标志,TC-NETCFG-028/026/030 钉死(含失败路径必须 清 busy,否则 UI 永久卡 WAIT)。 2. "定长 11 字符"是错的:%03u.%03u.%03u.%03u = 4 段×3 位 + 3 个点 = **15**。这个数 错了 4 处(net_cfg.h、net_cfg.c、网络配置说明.md 两处)——是我照抄它才撞上 FAIL,错在文档不是代码。已全部更正,并确认 len ≥ 16 的要求与 UI_BUF_STRLEN=32 本来就没问题(无截断风险)。 桩的口径(沿用既有模块,不另起一套):真实头优先——cfg_file.h / cfg_file_store.h / console_log.h / prot_set.h 全用真头(接口一漂移就编译期报错),只有 main.h 必须桩 (真实 main.h 拉整棵 HAL 头树,PC 上编不动;桩里字段名与位掩码宏名与 CMSIS 一致)。 prot_set_store 连真实 prot_set.c 一起编:blob 的编解码与脏标志在它里面,只有拿真 serialize 产出的 blob 才能造出"换代"与"损坏"两种真实形态,手搓等于测自己的桩。 配置引擎本身(解析/写盘/沉降)归 test/host/cfg_file 的 103 条,本批不重复测。 编号门禁:按 2026-10-21 批 3 的 B 层口径补建 4 族 TC-HOST-*(NETCFG 游标 056 / FTPCFG 014 / PROTSTOR 016 / TASKPROF 020,代码即属主登记处)。这一步不是走形式: 建族之前文档里引用 TC-NETCFG-028 被判「台账之外新账」直接卡提交,建族后才通过; 编号规范 §8.4 变更记录加一行说明族数 9 → 13。id_registry.json 只做增量插入(+88 行, 无重排)。 自查(提交时 pre-commit run --all-files,**仅 3 条失败且都与本分支改动无关**): - mem-numbers / mem-budget:本 worktree 因需验证代码改动而 @build 过,新生成的 .map 与 docs/内存管理 受管快照漂移。实测增量 ER_IROM1 +12 B、RW_IRAM1 +8 B、Flash +16 B、**CCM 0**,水位百分比全不变(改动 = 1 个静态字节 + 几条指令)。按并行分支 约定**不在分支里 --write**,台账由 Lead 合并后统一回填。 - ui-golden:simulator/tests/ref/*.bin 写在 .gitignore 里(黄金参考是本地生成物), 新建的 worktree 天生没有,报的是"缺黄金参考"而非像素差异;本分支零 UI 文件改动。 - 其余全部 Passed,含 @build 0 错误 0 警告、test-cppcheck(它抓到过我一条 p!=NULL 后又解引用的写法,已改为断言+显式守卫)、coding-standard、doc-links(35 处=存量)、 id-check --strict、mojibake 与 BOM/CR/U+FFFD/行尾逐项卫生。 - 自审修掉自己写的两条恒真断言(形如 x==0?1:1 的假绿)与一个重复编号标签。 - 4 个新模块**尚未挂 pre-commit 钩子**:.pre-commit-config.yaml 是单写文件,任务工作 树内不改;覆盖率脚本按 test/host/**/run_unit_test.py 自动发现,已实跑 20/20。 - 未跑 @test:改动仅 1 个静态字节 + UI 保存行的显示时序,无硬件语义变化。
This commit is contained in:
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* 模块名称:任务耗时探针(task_prof)主机侧单元测试
|
||||
* 模块功能:在 PC 上离线验证 App/util/task_prof.c 的**样本有效性闸门、enter/exit
|
||||
* 配对、上报节流与通道选择、周期→微秒换算、glitch 汇总**。
|
||||
*
|
||||
* 被测对象:真实源文件 ../../../App/util/task_prof.c(#include 原样纳入)。桩:
|
||||
* - stub/main.h:DWT/CoreDebug/SystemCoreClock/HAL_GetTick(本目录,
|
||||
* 真实 main.h 拉整棵 HAL 头树无法在 PC 上编);
|
||||
* - console_log.h 用**真实头**(App/log),两个出口函数
|
||||
* dbg_console_write_line / dbg_console_write_raw 由本文件实现并**留档
|
||||
* 内容**——报告行是要被人读的,所以断言直接盯字符串本身。
|
||||
*
|
||||
* 为什么要主机侧单测(而不是只靠真机日志):
|
||||
* 这个模块是"性能问题的唯一现场证据",它自己错了所有 PROF 行就都是假的:
|
||||
* 1. **无效样本闸门**(cyc==0 或 ≥ SystemCoreClock×10):漏了它,一次 DWT 复位
|
||||
* 就把 max 抬到 ~2^32 周期,之后所有"最坏耗时"永久失真(真机上没人会去翻
|
||||
* gl= 计数发现)。这条只能构造样本测。
|
||||
* 2. **未 enter 就 exit 必须直接返回**:周期测量写成"先 exit 再 enter"时,首轮
|
||||
* 会把 0 当起点,记下一次几秒的虚假超大样本——真机上表现为"偶发一条离谱
|
||||
* PROF 行",查半年。
|
||||
* 3. 节流契约(首次 5 s、之后每 2 s)与**两条通道的选择**(report 走环形缓冲、
|
||||
* report_raw 走裸发):错了要么刷屏挤掉正事,要么停摆现场那一行发不出去。
|
||||
* 4. 周期→微秒换算依赖 SystemCoreClock,改时钟树(比如 168→180 MHz)忘了同步
|
||||
* 就会整表偏移;这条在真机上看不出来(没人对着示波器量 PROF)。
|
||||
*
|
||||
* 覆盖点:
|
||||
* TC-TASKPROF-001 有效样本:count+1 / last=样本 / max=样本
|
||||
* TC-TASKPROF-002 更小样本不改 max(max 只增不减)
|
||||
* TC-TASKPROF-003 cyc=0 只累加 glitch,不动 count/last/max(计数器复位防线)
|
||||
* TC-TASKPROF-004 cyc ≥ SystemCoreClock×10 同样只累加 glitch
|
||||
* TC-TASKPROF-005 id 越界(=COUNT 与 +1)安全返回,不碰任何槽
|
||||
* TC-TASKPROF-006 首次取时基即惰性使能 DWT(TRCENA + CYCCNTENA 读回)
|
||||
* TC-TASKPROF-007 enter 置 in_seg 并记下起点
|
||||
* TC-TASKPROF-008 exit 结算 Δ、清 in_seg、count+1
|
||||
* TC-TASKPROF-009 **未 enter 直接 exit 不记账**(防首轮 0 起点造出假超大样本)
|
||||
* TC-TASKPROF-010 重复 exit 不重复记账
|
||||
* TC-TASKPROF-011 首次 5 s 之前一条都不发
|
||||
* TC-TASKPROF-012 到点后发两行([PROF] + [PROF2]),走环形缓冲通道
|
||||
* TC-TASKPROF-013 之后不足 2 s 不发(节流)
|
||||
* TC-TASKPROF-014 满 2 s 再发两行
|
||||
* TC-TASKPROF-015 report_raw 无视节流,恒发两行且走**裸发**通道
|
||||
* TC-TASKPROF-016 行格式:以 [PROF]/[PROF2] 开头、以 \r\n 结尾
|
||||
* TC-TASKPROF-017 周期→微秒换算按 SystemCoreClock(168 MHz 下 1680 周期 = 10 us)
|
||||
* TC-TASKPROF-018 gl= 是所有槽 glitch 的汇总,不是单槽
|
||||
* TC-TASKPROF-019 段内进行时的 n= 字段非零(此刻仍在段内的可视性)
|
||||
* TC-TASKPROF-020 count 是累计值,上报不清零
|
||||
*
|
||||
* 通过:全部 TC PASS(main 返回 0)。
|
||||
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
|
||||
*
|
||||
* 创建日期:2026-10-23
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "console_log.h" /* 真实头:DBG_CON_LINE_MAX + 两个出口 */
|
||||
#include "task_prof.h"
|
||||
|
||||
#include "task_prof.c"
|
||||
|
||||
/* ===================== 断言框架 ===================== */
|
||||
|
||||
static int s_total;
|
||||
static int s_passed;
|
||||
static int s_failed;
|
||||
|
||||
#define CHECK(cond, name) do { \
|
||||
s_total++; \
|
||||
if (cond) { s_passed++; printf(" PASS %s\n", name); } \
|
||||
else { s_failed++; printf(" FAIL %s (line %d)\n", name, __LINE__); } \
|
||||
} while (0)
|
||||
|
||||
/* ===================== 桩实体 ===================== */
|
||||
|
||||
static tp_coredebug_t g_coredebug;
|
||||
static tp_dwt_t g_dwt;
|
||||
tp_coredebug_t *const CoreDebug = &g_coredebug;
|
||||
tp_dwt_t *const DWT = &g_dwt;
|
||||
|
||||
uint32_t SystemCoreClock = 168000000u; /* 真机口径:168 MHz */
|
||||
|
||||
static uint32_t g_tick; /* HAL_GetTick 的可控值 */
|
||||
|
||||
uint32_t HAL_GetTick(void)
|
||||
{
|
||||
return g_tick;
|
||||
}
|
||||
|
||||
/* 出口留档:两条通道分别计数;**每一行都单独留档**(一次上报会连发
|
||||
* [PROF] 与 [PROF2] 两行,只存"最后一行"就没法断言第一行的字段) */
|
||||
#define CAP_MAX 8
|
||||
static int g_line_calls;
|
||||
static int g_raw_calls;
|
||||
static char g_line[CAP_MAX][DBG_CON_LINE_MAX];
|
||||
|
||||
static void cap(int slot, const char *src, unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (slot >= CAP_MAX) {
|
||||
return;
|
||||
}
|
||||
for (i = 0u; (i < len) && (i + 1u < DBG_CON_LINE_MAX); i++) {
|
||||
g_line[slot][i] = src[i];
|
||||
}
|
||||
g_line[slot][i] = '\0';
|
||||
}
|
||||
|
||||
int dbg_console_write_line(const char *line, unsigned len)
|
||||
{
|
||||
cap(g_line_calls + g_raw_calls, line, len);
|
||||
g_line_calls++;
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
void dbg_console_write_raw(const char *buf, unsigned len)
|
||||
{
|
||||
cap(g_line_calls + g_raw_calls, buf, len);
|
||||
g_raw_calls++;
|
||||
}
|
||||
|
||||
void dbg_console_writer_attach(void) { }
|
||||
uint8_t dbg_console_writer_ready(void) { return 1u; }
|
||||
|
||||
/* ===================== 辅助 ===================== */
|
||||
|
||||
static void reset_all(void)
|
||||
{
|
||||
(void)memset(s_prof, 0, sizeof(s_prof));
|
||||
(void)memset(&g_coredebug, 0, sizeof(g_coredebug));
|
||||
(void)memset(&g_dwt, 0, sizeof(g_dwt));
|
||||
s_dwt_ok = 0u;
|
||||
s_prof_reported = 0u;
|
||||
s_prof_last = 0u;
|
||||
g_tick = 0u;
|
||||
g_line_calls = 0;
|
||||
g_raw_calls = 0;
|
||||
(void)memset(g_line, 0, sizeof(g_line));
|
||||
}
|
||||
|
||||
static void set_cyc(uint32_t v)
|
||||
{
|
||||
g_dwt.CYCCNT = v;
|
||||
}
|
||||
|
||||
/* 从指定行的键上取整数值;键不存在或其后不是数字则返回 -1(断言因此会响)。
|
||||
* 手写解析而不用 sscanf:后者在 MSVC 下触发 C4996(弃用告警),门禁输出要干净 */
|
||||
static long field_of(int slot, const char *p_key)
|
||||
{
|
||||
const char *p;
|
||||
long v = 0;
|
||||
int digits = 0;
|
||||
|
||||
if (slot >= CAP_MAX) {
|
||||
return -1L;
|
||||
}
|
||||
p = strstr(g_line[slot], p_key);
|
||||
if (p == NULL) {
|
||||
return -1L;
|
||||
}
|
||||
p += strlen(p_key);
|
||||
while ((*p >= '0') && (*p <= '9')) {
|
||||
v = (v * 10) + (long)(*p - '0');
|
||||
p++;
|
||||
digits++;
|
||||
}
|
||||
return (digits > 0) ? v : -1L;
|
||||
}
|
||||
|
||||
/* ===================== 样本闸门 ===================== */
|
||||
|
||||
static void tc_sample_gate(void)
|
||||
{
|
||||
printf("-- TC-TASKPROF-001..005 sample gate --\n");
|
||||
reset_all();
|
||||
task_prof_sample(TASK_PROF_UI_PERIOD, 500u);
|
||||
CHECK((s_prof[TASK_PROF_UI_PERIOD].count == 1u) &&
|
||||
(s_prof[TASK_PROF_UI_PERIOD].last == 500u) &&
|
||||
(s_prof[TASK_PROF_UI_PERIOD].max == 500u),
|
||||
"TC-TASKPROF-001 有效样本记 count/last/max");
|
||||
|
||||
task_prof_sample(TASK_PROF_UI_PERIOD, 300u);
|
||||
CHECK((s_prof[TASK_PROF_UI_PERIOD].max == 500u) &&
|
||||
(s_prof[TASK_PROF_UI_PERIOD].last == 300u) &&
|
||||
(s_prof[TASK_PROF_UI_PERIOD].count == 2u),
|
||||
"TC-TASKPROF-002 更小样本不改 max");
|
||||
|
||||
reset_all();
|
||||
task_prof_sample(TASK_PROF_UI_PERIOD, 0u);
|
||||
CHECK((s_prof[TASK_PROF_UI_PERIOD].glitch == 1u) &&
|
||||
(s_prof[TASK_PROF_UI_PERIOD].count == 0u) &&
|
||||
(s_prof[TASK_PROF_UI_PERIOD].max == 0u),
|
||||
"TC-TASKPROF-003 cyc=0 只累加 glitch(DWT 复位防线)");
|
||||
|
||||
reset_all();
|
||||
task_prof_sample(TASK_PROF_UI_PERIOD, SystemCoreClock * 10u);
|
||||
CHECK((s_prof[TASK_PROF_UI_PERIOD].glitch == 1u) &&
|
||||
(s_prof[TASK_PROF_UI_PERIOD].count == 0u),
|
||||
"TC-TASKPROF-004 超上界样本只累加 glitch");
|
||||
|
||||
reset_all();
|
||||
task_prof_sample((task_prof_id_t)TASK_PROF_ID_COUNT, 100u);
|
||||
task_prof_sample((task_prof_id_t)(TASK_PROF_ID_COUNT + 1), 100u);
|
||||
task_prof_enter((task_prof_id_t)TASK_PROF_ID_COUNT);
|
||||
task_prof_exit((task_prof_id_t)TASK_PROF_ID_COUNT);
|
||||
CHECK((s_prof[0].count == 0u) && (s_prof[TASK_PROF_ID_COUNT - 1].count == 0u),
|
||||
"TC-TASKPROF-005 id 越界安全返回,不碰任何槽");
|
||||
}
|
||||
|
||||
/* ===================== 时基与 enter/exit 配对 ===================== */
|
||||
|
||||
static void tc_enter_exit(void)
|
||||
{
|
||||
printf("-- TC-TASKPROF-006..010 dwt enable + enter/exit --\n");
|
||||
reset_all();
|
||||
set_cyc(1000u);
|
||||
(void)task_prof_cyc();
|
||||
CHECK(((g_coredebug.DEMCR & CoreDebug_DEMCR_TRCENA_Msk) != 0u) &&
|
||||
((g_dwt.CTRL & DWT_CTRL_CYCCNTENA_Msk) != 0u) &&
|
||||
(s_dwt_ok == 1u),
|
||||
"TC-TASKPROF-006 首次取时基即惰性使能 DWT");
|
||||
|
||||
reset_all();
|
||||
set_cyc(2000u);
|
||||
task_prof_enter(TASK_PROF_UI_WORK);
|
||||
CHECK((s_prof[TASK_PROF_UI_WORK].in_seg == 1u) &&
|
||||
(s_prof[TASK_PROF_UI_WORK].t_start == 2000u),
|
||||
"TC-TASKPROF-007 enter 置 in_seg 并记起点");
|
||||
|
||||
set_cyc(2640u);
|
||||
task_prof_exit(TASK_PROF_UI_WORK);
|
||||
CHECK((s_prof[TASK_PROF_UI_WORK].in_seg == 0u) &&
|
||||
(s_prof[TASK_PROF_UI_WORK].last == 640u) &&
|
||||
(s_prof[TASK_PROF_UI_WORK].count == 1u),
|
||||
"TC-TASKPROF-008 exit 结算 Δ 并清 in_seg");
|
||||
|
||||
reset_all();
|
||||
task_prof_exit(TASK_PROF_ADC_BEAT);
|
||||
CHECK((s_prof[TASK_PROF_ADC_BEAT].count == 0u) &&
|
||||
(s_prof[TASK_PROF_ADC_BEAT].glitch == 0u),
|
||||
"TC-TASKPROF-009 未 enter 直接 exit 不记账(防 0 起点假超大样本)");
|
||||
|
||||
reset_all();
|
||||
set_cyc(100u);
|
||||
task_prof_enter(TASK_PROF_NET_POLL);
|
||||
set_cyc(150u);
|
||||
task_prof_exit(TASK_PROF_NET_POLL);
|
||||
task_prof_exit(TASK_PROF_NET_POLL);
|
||||
CHECK(s_prof[TASK_PROF_NET_POLL].count == 1u, "TC-TASKPROF-010 重复 exit 不重复记账");
|
||||
}
|
||||
|
||||
/* ===================== 上报节流与通道 ===================== */
|
||||
|
||||
static void tc_report_throttle(void)
|
||||
{
|
||||
printf("-- TC-TASKPROF-011..015 report throttle + channels --\n");
|
||||
reset_all();
|
||||
g_tick = 4999u;
|
||||
task_prof_report();
|
||||
CHECK((g_line_calls == 0) && (g_raw_calls == 0), "TC-TASKPROF-011 首 5 s 前不发");
|
||||
|
||||
g_tick = 5000u;
|
||||
task_prof_report();
|
||||
CHECK((g_line_calls == 2) && (g_raw_calls == 0),
|
||||
"TC-TASKPROF-012 到点发两行走环形缓冲");
|
||||
|
||||
g_tick = 6999u;
|
||||
task_prof_report();
|
||||
CHECK(g_line_calls == 2, "TC-TASKPROF-013 不足 2 s 不发");
|
||||
|
||||
g_tick = 7000u;
|
||||
task_prof_report();
|
||||
CHECK(g_line_calls == 4, "TC-TASKPROF-014 满 2 s 再发两行");
|
||||
|
||||
g_line_calls = 0;
|
||||
g_raw_calls = 0;
|
||||
task_prof_report_raw();
|
||||
CHECK((g_raw_calls == 2) && (g_line_calls == 0),
|
||||
"TC-TASKPROF-015 report_raw 无视节流且走裸发通道");
|
||||
}
|
||||
|
||||
/* ===================== 行内容与换算 ===================== */
|
||||
|
||||
static void tc_line_format(void)
|
||||
{
|
||||
printf("-- TC-TASKPROF-016..020 line content --\n");
|
||||
|
||||
/* 016:一次上报连发两行;行首前缀是采集脚本的抓取依据,行尾必须是 CRLF */
|
||||
reset_all();
|
||||
g_tick = 5000u;
|
||||
task_prof_report();
|
||||
CHECK((g_line_calls == 2) &&
|
||||
(strncmp(g_line[0], "[PROF] ", 7) == 0) &&
|
||||
(strncmp(g_line[1], "[PROF2] ", 8) == 0),
|
||||
"TC-TASKPROF-016 两行行首分别是 [PROF] / [PROF2]");
|
||||
CHECK((strstr(g_line[0], "\r\n") != NULL) &&
|
||||
(strstr(g_line[1], "\r\n") != NULL),
|
||||
"TC-TASKPROF-016b 两行都以 CRLF 结尾");
|
||||
CHECK(field_of(0, "uip=") == 0L, "TC-TASKPROF-016c 未采样的槽打印 0");
|
||||
|
||||
/* 017:打印的是**微秒**,分母是 SystemCoreClock —— 断言落在打印字段上 */
|
||||
reset_all();
|
||||
task_prof_sample(TASK_PROF_UI_PERIOD, 1680u); /* 168 MHz → 10 us */
|
||||
task_prof_sample(TASK_PROF_ADC_BEAT, 3360u); /* 168 MHz → 20 us */
|
||||
g_tick = 5000u;
|
||||
task_prof_report();
|
||||
CHECK(field_of(0, "uip=") == 10L,
|
||||
"TC-TASKPROF-017 168 MHz:1680 周期的 max 打印成 uip=10");
|
||||
CHECK(field_of(0, "adcm=") == 20L,
|
||||
"TC-TASKPROF-017b 同频:3360 周期的 max 打印成 adcm=20");
|
||||
SystemCoreClock = 84000000u; /* 改时钟树而忘了同步 → 整表偏移,这里必须显式跟着变 */
|
||||
g_tick = 7000u;
|
||||
task_prof_report();
|
||||
CHECK(field_of(2, "uip=") == 20L,
|
||||
"TC-TASKPROF-017c 84 MHz 下同一批周期数打印成 20");
|
||||
SystemCoreClock = 168000000u;
|
||||
|
||||
/* 018:gl= 是**所有槽**的 glitch 汇总,不是当前槽 */
|
||||
reset_all();
|
||||
task_prof_sample(TASK_PROF_UI_PERIOD, 0u);
|
||||
task_prof_sample(TASK_PROF_ADC_BEAT, 0u);
|
||||
task_prof_sample(TASK_PROF_NET_POLL, 0u);
|
||||
g_tick = 5000u;
|
||||
task_prof_report();
|
||||
CHECK(field_of(0, "gl=") == 3L, "TC-TASKPROF-018 gl= 汇总所有槽的 glitch");
|
||||
|
||||
/* 019:段未结算时,"此刻已在段内多久"要看得见(uipn / netn 两个字段) */
|
||||
/* 字段口径 = 上报时刻的 CYCCNT 减去各自的进段时刻(**不是**样本值):
|
||||
* UI_PERIOD 进段 @1000、NET_POLL 进段 @10000,上报时 CYCCNT=51680
|
||||
* uipn = (51680-1000)/168 = 301 netn = (51680-10000)/168 = 248 */
|
||||
reset_all();
|
||||
set_cyc(1000u);
|
||||
task_prof_enter(TASK_PROF_UI_PERIOD);
|
||||
set_cyc(10000u);
|
||||
task_prof_enter(TASK_PROF_NET_POLL);
|
||||
set_cyc(51680u);
|
||||
g_tick = 5000u;
|
||||
task_prof_report();
|
||||
CHECK(field_of(0, "uipn=") == 301L,
|
||||
"TC-TASKPROF-019 UI_PERIOD 段内:uipn= 上报此刻已停留的 us");
|
||||
CHECK(field_of(1, "netn=") == 248L,
|
||||
"TC-TASKPROF-019b NET_POLL 段内:[PROF2] 的 netn= 同步可见");
|
||||
CHECK(field_of(0, "adcn=") == 0L,
|
||||
"TC-TASKPROF-019c 未进段的 ADC_BEAT 打印 0(不串用别的槽)");
|
||||
CHECK(s_prof[TASK_PROF_UI_PERIOD].in_seg == 1u,
|
||||
"TC-TASKPROF-019d 上报不消费段状态(只观测)");
|
||||
|
||||
/* 020:count 是累计量,两轮上报之间不能清零 */
|
||||
reset_all();
|
||||
task_prof_sample(TASK_PROF_UI_WORK, 100u);
|
||||
g_tick = 5000u;
|
||||
task_prof_report();
|
||||
g_tick = 7000u;
|
||||
task_prof_report();
|
||||
CHECK((s_prof[TASK_PROF_UI_WORK].count == 1u) && (field_of(2, "uic=") == 0L) &&
|
||||
(field_of(0, "uic=") == 0L),
|
||||
"TC-TASKPROF-020 上报不清零(UI_WORK 不在 uic= 字段,仍为累计 1)");
|
||||
}
|
||||
|
||||
|
||||
/* ===================== 入口 ===================== */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("=== Task Prof Tests ===\n");
|
||||
|
||||
tc_sample_gate();
|
||||
tc_enter_exit();
|
||||
tc_report_throttle();
|
||||
tc_line_format();
|
||||
|
||||
printf("\n=== Task Prof Tests: %d/%d PASSED (failed=%d) ===\n",
|
||||
s_passed, s_total, s_failed);
|
||||
return (s_failed == 0) ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user