修复 P0-a 重传周期 200ms 与 P0-b per-recv 日志,台架重锁 M2/M3 基线并复验

This commit is contained in:
2026-09-22 11:36:16 +08:00
parent 2cffd1d2cf
commit 06d4064366
11 changed files with 4144 additions and 88 deletions
+17
View File
@@ -9,6 +9,8 @@
* 2026-09-10 王建锋 清理未引用宏(TCP Server 监听 Socket 索引、收发缓冲、
* 连接/接受超时、select/队列/轮询);KeepAlive 三宏改为
* 实际生效值 60s/5s/3 并在 net_socket.c 引用(原宏为无效遗留值)
* 2026-09-22 新增 NET_RETRANS_COUNT/NET_RETRANS_PERIOD_MS(P0-a:重传周期
* 500→200ms 治 D1 症状),net_socket.c 的字面量 8/500 移入本文件
*/
#ifndef NET_CONFIG_H
@@ -37,6 +39,21 @@ extern "C" {
#define NET_RECV_TIMEOUT_MS 30000 /* 接收超时(30秒,0=无限等待) */
#endif
/*
* TCP 重传配置(由 net_socket.c 的 net_init() 在 ch395f_init() 之前下发)
* P0-a(2026-09-22):周期 500→200ms——单次丢包代价 500→200ms(治 D1 症状),
* 总窗口 8×200=1.6s,链路真断时判失败更快(对远端显示重连有利)。
* 手册 §5.18 仅标注上限(≤1000ms)未标注下限;200ms 已经台架验证芯片接受
*(GET_CMD_STATUS=0x00 + 全套件无回归,见《链路延迟测试说明.md》§10.2 记录)。
*/
#ifndef NET_RETRANS_COUNT
#define NET_RETRANS_COUNT 8 /* 重传次数(手册:最大 20,默认 12) */
#endif
#ifndef NET_RETRANS_PERIOD_MS
#define NET_RETRANS_PERIOD_MS 200 /* 重传周期 ms(手册:最大 1000,默认 500) */
#endif
/*
* TCP KeepAlive 配置(单位 ms;须为 500 的倍数且 IDLE > INTVL)
* 由 net_socket.c 的 net_init() 在 ch395f_init() 之前下发
+53 -3
View File
@@ -40,6 +40,7 @@
static net_sock_t s_net_socks[NET_MAX_SOCKETS]; /* Socket 控制块数组 */
static int s_net_errno = 0; /* 最后错误码 */
static uint8_t s_net_initialized = 0; /* 初始化标志 */
static uint8_t s_retrans_cmd_status = 0xFFU; /* P0-a:重传周期 GET_CMD_STATUS 验收结果(0xFF=未采集) */
static uint8_t s_local_ip[4]; /* 本机 IP 缓存(网络序,net_getsockname 用) */
static uint16_t s_dynamic_port = 49152; /* 动态端口分配起始值 */
static volatile uint32_t s_net_generation = 0; /* 网络代次号:网络重建完成时递增(服务据此重建监听) */
@@ -147,8 +148,30 @@ static bool s_mac_is_zero(const uint8_t *p_mac) {
ch395f_set_tcp_mss(CH395F_TCP_MSS);
/* 设置 TCP 重传参数(必须在 INIT_CH395 之前调用*/
ch395f_set_retrans_count(8); /* 重传 8 次*/
ch395f_set_retrans_period(500); /* 每次间隔 500ms,总计 4s 重传窗口 */
ch395f_set_retrans_count(NET_RETRANS_COUNT);
ch395f_set_retrans_period(NET_RETRANS_PERIOD_MS);
/* P0-a 一次性验收(手册无重传参数回读命令):设置命令之后查 GET_CMD_STATUS。
* 实测(2026-09-22 台架,500ms 合法值与 2000ms 超限值行为完全一致):
* SET 类命令不更新状态寄存器——读到的是 RESET_ALL 的 0x10(BUSY) 陈旧残留
* (ch395f_reset 只延时 20ms、不轮询状态);INIT 类长命令才重写寄存器。
* 故 3 次 × 20ms 轮询即可捕获真正的值/参数错误码(0x19/0x1A 等),
* 0x10 只证明"寄存器未更新",不构成值判据——值的接受性以
* 手册范围(≤1000ms)+ 全套件无回归 + 与 500ms 行为一致为准。
* 注意:此处只静默捕获状态,不打日志——本窗口与 testTask 启动日志并发,
* 并发 printf 会因非重入 UART 发送丢整行(2026-09-22 台架实测);
* 打印延迟到 net_stack_bring_up 的 PHY 行之后(net_retrans_status_log)。 */
{
uint8_t rto_st = CH395F_ERR_BUSY;
for (uint32_t i = 0U; i < 3U; i++) {
osDelay(20U);
rto_st = ch395f_get_cmd_status();
if (rto_st != CH395F_ERR_BUSY) {
break;
}
}
s_retrans_cmd_status = rto_st;
}
/* 设置 TCP KeepAlive 参数(必须在 INIT_CH395 之前,单位 ms,必须为 500 的倍数,且 IDLE > INTVL)
* 值来自 net_config.h 的 NET_KEEPALIVE_*(60s/5s/3)*/
@@ -216,6 +239,34 @@ static bool s_mac_is_zero(const uint8_t *p_mac) {
return 0;
}
/*
* 函数功能:打印 P0-a 重传周期芯片验收证据行(一次性)
* 入口参数:无
* 返 回 值:无
* 限定条件:net_init 之后调用;建议放在 net_stack_bring_up 的 PHY 行之后
* (启动日志低并发窗口)——net_init 尾部与其它任务启动日志并发时,
* 非重入 UART 发送会丢整行(2026-09-22 台架实测)
* 函数说明:三分支判读(实测 2026-09-22:SET 类命令不更新状态寄存器):
* 0x00 = 芯片明确报告接受;0x10 = 陈旧 BUSY 残留(无判别力,INFO 级,
* 避免健康启动误触 [ERR] 标记);其它状态码 = 真值/参数错误(ERROR 级)
*/
void net_retrans_status_log(void) {
if (s_retrans_cmd_status == 0xFFU) {
return; /* 本次启动未走 NET 层 bring_up(如硬件层测试模式) */
}
if (s_retrans_cmd_status == CH395F_ERR_SUCCESS) {
DBG_INFO("net_init: retrans %u x %u ms accepted by chip (status=0x00)",
(unsigned)NET_RETRANS_COUNT, (unsigned)NET_RETRANS_PERIOD_MS);
} else if (s_retrans_cmd_status == CH395F_ERR_BUSY) {
DBG_INFO("net_init: retrans %u x %u ms set (status 0x10 = stale residue, inconclusive)",
(unsigned)NET_RETRANS_COUNT, (unsigned)NET_RETRANS_PERIOD_MS);
} else {
DBG_ERROR("net_init: retrans period %u ms REJECTED by chip (cmd status=0x%02X)",
(unsigned)NET_RETRANS_PERIOD_MS, (unsigned)s_retrans_cmd_status);
}
s_retrans_cmd_status = 0xFFU; /* 只打印一次 */
}
/*
* 函数功能:取网络代次号
* 入口参数:无
@@ -1112,7 +1163,6 @@ static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags,
int recv_len = ch395f_get_recv_len(sockfd);
if (recv_len > 0) {
int read_len = (recv_len > len) ? len : recv_len;
DBG_INFO("recv sock%d len=%d", sockfd, recv_len);
ch395f_read_recv_buf(sockfd, (uint8_t *)buf, (uint16_t)read_len);
p_sock->recv_bytes += (uint32_t)read_len;
p_sock->readable = 0; /* 已消费数据(注:部分读受 Trap 13 限制,下一次 RECV_OK 会重新置位) */
+11
View File
@@ -74,6 +74,17 @@ typedef struct {
*/
int net_init(const char *ip, const char *mask, const char *gateway, const uint8_t *mac);
/*
* 函数功能:打印 P0-a 重传周期芯片验收证据行(一次性)
* 入口参数:无
* 返回值:无
* 限定条件:net_init() 之后;建议放在 net_stack_bring_up() 的 PHY 行之后
* 函数说明:net_init 在设置重传参数后立即静默查询 GET_CMD_STATUS(手册无回读
* 命令,此状态是"芯片是否接受该周期"的唯一证据);打印延迟到 PHY 行
* 之后,避开启动期多任务并发 printf 丢行
*/
void net_retrans_status_log(void);
/*
* 函数功能:取网络代次号
* 入口参数:无