实施A2/A3/A4并通过真机验证:net_task失败重试自检、ch395f有限超时故障锁存、remo_send短写阻断;@test 7/7,A1含配置持久化闭环

This commit is contained in:
2026-10-03 09:05:57 +08:00
parent ddbba714f7
commit 1780e5320b
8 changed files with 165 additions and 33 deletions
+47 -8
View File
@@ -12,6 +12,9 @@
* 2026-09-10 王建锋 改为双端共用:底层改用 net_* API + 平台后端;接收改为逐字节
* 状态机(失步自动重同步);断开/网络重建后经 net_get_sock 判活
* 并重建监听(修复 MCU 单连接模型断线后无法重连的隐患)
* 2026-10-02 王建锋 E-04:remo_send 校验 net_send 返回值(原丢弃)——短写/失败
* 告警,连续 3 次失败阻断推送,新连接/网络重建解除阻断
* (MCU 单连接模型不得 net_close 数据 fd,会连监听一起毁掉)
*/
#include "ui_net_sink.h"
@@ -23,6 +26,10 @@
#include "test_config.h" /* TEST_LATENCY_PROBE(链路时延探针编译开关) */
#include "net_latency_test.h" /* M3 探针:prod_cycle_mcu(LCDMEM 处理净成本) */
/* E-04(2026-10-02):发送短写/失败告警(MCU=控制台日志,模拟器=printf 桩) */
#define DBG_TAG "[UI_NET_SINK]"
#include "dbg_log.h"
/* RemoDispBus 标签与命令(与 ui_net_sink.h 的 UI_REMO_* 常量对齐) */
#define TAG_CLIENT UI_REMO_TAG_CLIENT
#define TAG_DEVICE UI_REMO_TAG_DEVICE
@@ -47,6 +54,8 @@ static int g_listen = -1; /* 监听 Socket fd(未启动或已停止时
static int g_client = -1; /* 当前客户端 Socket fd(无连接时为 -1) */
static uint16_t g_port; /* 监听端口(网络重建 / 断线后重监听用) */
static uint32_t g_gen; /* 建立监听时的网络代次号(变化 = 网络已重建) */
static uint8_t s_send_fail_run; /* 连续发送失败计数(E-04:0 = 正常) */
static uint8_t s_sink_blocked; /* 推送阻断标志(1 = 停发帧,等客户端重连解除) */
/*
* 函数功能:计算 RemoDispBus 帧 payload 的 CRC 校验值
@@ -95,16 +104,25 @@ static void put_u32(uint8_t *p, uint32_t v) {
/*
* 函数功能:构造并发送一帧 RemoDispBus 响应(设备→客户端)
* 入口参数:cmd - 命令码;data - payload 指针(len 非 0 时须非空);len - payload 长度
* 返回值:无
* 返回值:0 - 整帧发出;-1 - 发送失败/短写/推送已阻断
* 限定条件:g_tx 空间足够容纳 4+len+1 字节;g_client >= 0(已有连接)
* 函数说明:帧格式 [TAG_DEVICE][CMD][LEN_H][LEN_LO][DATA][CRC];CRC 为 payload 异或;
* 无连接时直接返回
* E-04(2026-10-02):校验 net_send 返回值(原丢弃)——短写 = 客户端收到坏帧
* (CRC 不符 → 画面卡死黑屏,而设备侧日志全正常);连续 3 次失败 →
* 停发:客户端察觉无帧自行重连,芯片侧 DISCONNECT/TIMEOUT 自动重开
* 监听重建连接;MCU 单连接模型严禁 net_close 数据 fd(会连监听一起毁)
*/
static void remo_send(uint8_t cmd, const uint8_t *data, uint16_t len) {
static int remo_send(uint8_t cmd, const uint8_t *data, uint16_t len) {
uint8_t *p;
int total;
int ret;
if (g_client < 0) {
return;
return -1;
}
if (s_sink_blocked) {
return -1; /* 推送已阻断:等客户端重连解除 */
}
p = g_tx;
@@ -116,7 +134,24 @@ static void remo_send(uint8_t cmd, const uint8_t *data, uint16_t len) {
memcpy(p + 4, data, len);
}
p[4 + len] = remo_crc(data, len);
net_send(g_client, p, (int)(4 + len + 1), 0);
total = (int)(4 + len + 1);
ret = net_send(g_client, p, total, 0);
if (ret == total) {
s_send_fail_run = 0U;
return 0;
}
/* 短写/发送失败:告警 + 累计连续失败数 */
if (s_send_fail_run < 255U) {
s_send_fail_run++;
}
DBG_ERROR("remo send short: ret=%d/%d run=%u", ret, total,
(unsigned)s_send_fail_run);
if (s_send_fail_run >= 3U) {
s_sink_blocked = 1U;
DBG_ERROR("remo sink blocked, await client reconnect");
}
return -1;
}
/*
@@ -135,7 +170,7 @@ static void remo_send_init(void) {
put_u16(init, UI_W);
put_u16(init + 2, UI_H);
put_u32(init + 4, UI_MEMSIZE);
remo_send(CMD_INIT, init, 8);
(void)remo_send(CMD_INIT, init, 8);
}
/*
@@ -196,7 +231,7 @@ static void remo_handle(const uint8_t *f, int n) {
switch (cmd) {
case CMD_KEEPLIVE:
/* 心跳保活:原样回显一个空 KEEPLIVE 帧,维持连接活性 */
remo_send(CMD_KEEPLIVE, NULL, 0);
(void)remo_send(CMD_KEEPLIVE, NULL, 0);
break;
case CMD_INIT:
/* 查询屏幕参数:回送 [宽u16][高u16][帧字节数u32](大端,共 6 字节) */
@@ -208,7 +243,7 @@ static void remo_handle(const uint8_t *f, int n) {
ui_net_sink_inject_key(data[0]);
}
/* 回空帧作“已接收”确认(LEN=0,CRC=0) */
remo_send(CMD_KEY, NULL, 0);
(void)remo_send(CMD_KEY, NULL, 0);
break;
case CMD_LCDMEM: {
/* 读取显存:数据段为 4 字节大端起始偏移,不足 4 字节判非法丢弃 */
@@ -236,7 +271,7 @@ static void remo_handle(const uint8_t *f, int n) {
if (ui_net_sink_get_lcdmem(g_lcdmem_data + 4, UI_MEMSIZE) == 0) {
/* 应答数据段 = [偏移u32(回填请求原值)] + [1bpp 位图 3200B] */
memcpy(g_lcdmem_data, data, 4);
remo_send(CMD_LCDMEM, g_lcdmem_data, (uint16_t)(4 + UI_MEMSIZE));
(void)remo_send(CMD_LCDMEM, g_lcdmem_data, (uint16_t)(4 + UI_MEMSIZE));
}
#if defined(TEST_LATENCY_PROBE)
lat_probe_add_seg("prod_cycle_mcu", lat_mark_us(&tm));
@@ -433,6 +468,8 @@ void ui_net_sink_poll(void) {
}
g_client = -1;
rm_parser_reset();
s_send_fail_run = 0U; /* 网络重建:失败累计清零、解除推送阻断(E-04) */
s_sink_blocked = 0U;
(void)ui_net_sink_start(g_port);
return;
}
@@ -449,6 +486,8 @@ void ui_net_sink_poll(void) {
if (c >= 0) {
g_client = c;
rm_parser_reset();
s_send_fail_run = 0U; /* 新连接:失败累计清零、解除推送阻断(E-04) */
s_sink_blocked = 0U;
}
return;
}