实施A2/A3/A4并通过真机验证:net_task失败重试自检、ch395f有限超时故障锁存、remo_send短写阻断;@test 7/7,A1含配置持久化闭环
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user