feat(N34): E6 插桩 NET_U15_PROBE(U15 失配频率,默认关零成本)

实验方案 docs/网络/N34-自愈审计/实验方案.md §E6:验证「RX 非空但
readable=0」(RECV_OK 中断丢失的数据面形态)是否在生产真实发生,
门禁阶段 3 项 4(U15 内化)做不做。

- net_poll 末尾独立探测环:每 32 轮对在用 fd 发 GET_RECV_LEN,
  RX>0 且 readable=0 → 计数 + 低频日志(首次必打,此后每小时 ≤1 条)
- bring_up 尾部 armed 日志(挂机期间核对烧录身份)
- 宏默认 0:产品构建编译剔除,实测体积与上一构建逐字节一致
  (Code=211348 RO=18756 RW=1104 ZI=154232)

判据:24h 常态+E1 压测命中>0 → 项 4 立项;=0 → 盲收保留现状、
U15 登记观察项。
This commit is contained in:
2026-10-13 15:15:22 +08:00
parent f51c0833ae
commit 123d80afc7
+46
View File
@@ -361,6 +361,11 @@ static bool s_mac_is_zero(const uint8_t *p_mac) {
s_net_initialized = 1;
#if NET_U15_PROBE
/* E6:确认插桩固件已生效(挂机期间据此核对烧录身份) */
DBG_INFO("U15 probe armed: period=%u log_per_h=1", (unsigned int)NET_U15_PROBE_PERIOD);
#endif
return 0;
}
@@ -419,6 +424,21 @@ static void net_bench_cmd_log(char tag, int sock, int detail) {
}
#endif
/* N34 E6 实验插桩(U15 失配频率,docs/网络/N34-自愈审计/实验方案.md §E6):
* 假设=「RX 非空但 readable=0」(RECV_OK 中断丢失的数据面形态)在生产真实
* 发生。置 1 烧实验固件:net_poll 每 32 轮对在用 fd 发一条 GET_RECV_LEN,
* 命中计数 + 低频日志(每小时 ≤1 条防刷屏);跑 24h 常态 + E1 压测。
* 判据:命中 >0 → 阶段 3 项 4(U15 内化)立项;=0(含压测)→ 上层 32 轮
* 盲收保留现状、U15 登记观察项。**默认 0 = 产品构建零成本(编译剔除)**。 */
#define NET_U15_PROBE 0
#if NET_U15_PROBE
#define NET_U15_PROBE_PERIOD 32U /* 每 32 轮 net_poll 探测一次(≈32ms) */
#define NET_U15_PROBE_LOG_MS 3600000U /* 命中日志每小时至多 1 条 */
static uint32_t s_u15_round; /* net_poll 轮次计数 */
static uint32_t s_u15_hits; /* 累计命中次数(判据数据) */
static uint32_t s_u15_last_log; /* 上次命中日志时刻(tick) */
#endif
/*
* 函数功能:轮询 CH395F 中断状态,更新 Socket 连接状态并处理事件
* 入口参数:无
@@ -555,6 +575,32 @@ int net_poll(void) {
}
}
#if NET_U15_PROBE
/* E6 探测(宏说明见文件上方):RX 非空而 readable=0 = RECV_OK 中断丢失
* 的数据面形态。独立于上面的缓存刷新环:GET_RECV_LEN 是独立 SPI。 */
s_u15_round++;
if ((s_u15_round % NET_U15_PROBE_PERIOD) == 0U) {
for (int i = 0; i < NET_MAX_SOCKETS; i++) {
uint16_t rlen;
if (s_net_socks[i].in_use == 0U) {
continue;
}
rlen = ch395f_get_recv_len((uint8_t)i);
if ((rlen > 0U) && (s_net_socks[i].readable == 0U)) {
s_u15_hits++;
/* 首次命中必打(last_log=0 会被 uptime<1h 抑制);此后每小时 ≤1 条 */
if ((s_u15_hits == 1U) ||
((uint32_t)(HAL_GetTick() - s_u15_last_log) >= NET_U15_PROBE_LOG_MS)) {
s_u15_last_log = HAL_GetTick();
DBG_INFO("U15 probe: sock%d rx=%u readable=0 hits=%lu",
i, (unsigned int)rlen, (unsigned long)s_u15_hits);
}
}
}
}
#endif
/* 返回本次累计发生的事件数量(0 表示无事件) */
return event_count;
}