This commit is contained in:
2026-03-14 11:48:02 +08:00
parent fbe2e121db
commit c1121aecd6
5 changed files with 398 additions and 38 deletions
@@ -167,13 +167,17 @@ void qdx_port_sock_recv_notify(uint8_t sockid)
/* Read data from WCHNET into ring buffer */
uint8_t tmp[512];
uint32_t len;
uint32_t total = 0;
while (1) {
len = sizeof(tmp);
uint8_t err = WCHNET_SocketRecv(sockid, tmp, &len);
if (len == 0) break;
ring_write(&ctx->rx_ring, tmp, (uint16_t)len);
total += len;
if (err != WCHNET_ERR_SUCCESS) break;
}
DBG_PORT("recv_notify sock%d: %lu bytes, ring=%d\r\n",
sockid, total, ring_available(&ctx->rx_ring));
/* Wake blocking recv thread */
xSemaphoreGive(ctx->rx_sem);
}
@@ -183,6 +187,7 @@ void qdx_port_sock_connect_notify(uint8_t sockid)
SocketCtx_t *ctx = find_ctx_by_wchnet_id(sockid);
if (!ctx) return;
ctx->connected = 1;
DBG_PORT("connect_notify sock%d\r\n", sockid);
xSemaphoreGive(ctx->connect_sem);
}
@@ -191,6 +196,7 @@ void qdx_port_sock_disconnect_notify(uint8_t sockid)
SocketCtx_t *ctx = find_ctx_by_wchnet_id(sockid);
if (!ctx) return;
ctx->connected = 0;
DBG_PORT("disconnect_notify sock%d\r\n", sockid);
/* Wake recv thread so it can detect disconnect */
xSemaphoreGive(ctx->rx_sem);
}
@@ -203,6 +209,7 @@ void qdx_port_init(void)
{
memset(g_sock_ctx, 0, sizeof(g_sock_ctx));
g_wchnet_mutex = xSemaphoreCreateMutex();
DBG_PORT("init done, mutex=%p\r\n", g_wchnet_mutex);
}
/* ============================================================
@@ -261,6 +268,8 @@ int8_t qdx_port_thread_create(const char *name, qdx_thread_entry_t entry,
BaseType_t ret = xTaskCreate((TaskFunction_t)entry, name,
(uint16_t)stack_words, arg,
(UBaseType_t)priority, NULL);
DBG_PORT("thread_create \"%s\" stack=%lu pri=%d -> %s\r\n",
name, stack_words, priority, (ret == pdPASS) ? "OK" : "FAIL");
return (ret == pdPASS) ? 0 : -1;
}
@@ -272,13 +281,15 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port)
{
uint8_t dest_ip[4];
if (parse_ip(ip, dest_ip) != 0) {
printf("qdx_port: bad IP \"%s\"\r\n", ip);
DBG_PORT("bad IP \"%s\"\r\n", ip);
return NULL;
}
DBG_PORT("connecting to %s:%d\r\n", ip, port);
SocketCtx_t *ctx = alloc_sock_ctx();
if (!ctx) {
printf("qdx_port: no free SocketCtx\r\n");
DBG_PORT("no free SocketCtx\r\n");
return NULL;
}
@@ -289,6 +300,12 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port)
sock_inf.DesPort = port;
memcpy(sock_inf.IPAddr, dest_ip, 4);
DBG_PORT("SOCK_INF: proto=%d dst=%d.%d.%d.%d:%d\r\n",
sock_inf.ProtoType,
sock_inf.IPAddr[0], sock_inf.IPAddr[1],
sock_inf.IPAddr[2], sock_inf.IPAddr[3],
sock_inf.DesPort);
uint8_t wchnet_id = 0;
xSemaphoreTake(g_wchnet_mutex, portMAX_DELAY);
@@ -296,10 +313,11 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port)
xSemaphoreGive(g_wchnet_mutex);
if (err != WCHNET_ERR_SUCCESS) {
printf("qdx_port: SocketCreat fail %02X\r\n", err);
DBG_PORT("SocketCreat fail %02X\r\n", err);
free_sock_ctx(ctx);
return NULL;
}
DBG_PORT("SocketCreat OK, wchnet_id=%d\r\n", wchnet_id);
ctx->wchnet_sock_id = wchnet_id;
@@ -312,19 +330,27 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port)
xSemaphoreGive(g_wchnet_mutex);
if (err != WCHNET_ERR_SUCCESS) {
printf("qdx_port: SocketConnect fail %02X\r\n", err);
DBG_PORT("SocketConnect fail %02X\r\n", err);
WCHNET_SocketClose(wchnet_id, 0);
free_sock_ctx(ctx);
return NULL;
}
DBG_PORT("SocketConnect OK (err=0x%02X), waiting connect_sem (5s)...\r\n", err);
/* Block until SINT_STAT_CONNECT or 5s timeout */
if (xSemaphoreTake(ctx->connect_sem, pdMS_TO_TICKS(5000)) != pdTRUE) {
printf("qdx_port: connect timeout\r\n");
uint32_t t0 = xTaskGetTickCount();
BaseType_t sem_ret = xSemaphoreTake(ctx->connect_sem, pdMS_TO_TICKS(5000));
uint32_t elapsed = (xTaskGetTickCount() - t0) * portTICK_PERIOD_MS;
if (sem_ret != pdTRUE) {
DBG_PORT("connect_sem TIMEOUT after %lu ms -> %d.%d.%d.%d:%d\r\n",
elapsed, dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3], port);
DBG_PORT(" ctx->connected=%d wchnet_id=%d\r\n", ctx->connected, wchnet_id);
WCHNET_SocketClose(wchnet_id, 0);
free_sock_ctx(ctx);
return NULL;
}
DBG_PORT("connect_sem got after %lu ms, connected=%d\r\n", elapsed, ctx->connected);
if (!ctx->connected) {
WCHNET_SocketClose(wchnet_id, 0);
@@ -336,7 +362,7 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port)
WCHNET_SocketSetKeepLive(wchnet_id, ENABLE);
#endif
printf("qdx_port: connected sock %d -> %d.%d.%d.%d:%d\r\n",
DBG_PORT("connected sock %d -> %d.%d.%d.%d:%d\r\n",
wchnet_id, dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3], port);
return (qdx_socket_t)ctx;
}
@@ -11,11 +11,37 @@
#define QDX_PORT_H
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ============================================================
* Debug Print Macros (set to 0 to disable, 1 to enable)
* ============================================================ */
#define QDX_DEBUG_PORT 1 /* qdx_port.c: socket/mutex/thread ops */
#define QDX_DEBUG_LOGIC 1 /* qdx_tcp_logic.c: protocol/TLV parsing */
#define QDX_DEBUG_APP 1 /* main.c: application-level events */
#if QDX_DEBUG_PORT
#define DBG_PORT(fmt, ...) printf("[PORT] " fmt, ##__VA_ARGS__)
#else
#define DBG_PORT(fmt, ...) ((void)0)
#endif
#if QDX_DEBUG_LOGIC
#define DBG_LOGIC(fmt, ...) printf("[LOGIC] " fmt, ##__VA_ARGS__)
#else
#define DBG_LOGIC(fmt, ...) ((void)0)
#endif
#if QDX_DEBUG_APP
#define DBG_APP(fmt, ...) printf("[APP] " fmt, ##__VA_ARGS__)
#else
#define DBG_APP(fmt, ...) ((void)0)
#endif
/* ============================================================
* Time & Delay
* ============================================================ */
@@ -55,7 +55,7 @@ static struct {
/* Server endpoint prototype - user would configure these, but we map to demo
* defaults */
static const char *SERVER_IP = "127.0.0.1";
static const char *SERVER_IP = "192.168.7.50";
static const uint16_t CONTROL_PORT = 5511;
static const uint16_t DATA_PORT = 5512;
@@ -69,6 +69,7 @@ static void tcp_stream_init(TcpStreamCtx_t *ctx, const char *label) {
}
static void tcp_stream_disconnect(TcpStreamCtx_t *ctx) {
DBG_LOGIC("[%s] disconnecting\r\n", ctx->label);
ctx->is_connected = 0;
if (ctx->sock) {
qdx_port_tcp_close(ctx->sock);
@@ -78,14 +79,18 @@ static void tcp_stream_disconnect(TcpStreamCtx_t *ctx) {
static int8_t tcp_stream_connect(TcpStreamCtx_t *ctx, const char *ip,
uint16_t port) {
DBG_LOGIC("[%s] connecting %s:%d...\r\n", ctx->label, ip, port);
ctx->sock = qdx_port_tcp_connect(ip, port);
if (ctx->sock == NULL)
if (ctx->sock == NULL) {
DBG_LOGIC("[%s] connect FAILED\r\n", ctx->label);
return -1;
}
ctx->is_connected = 1;
ctx->last_activity_ms = qdx_port_get_tick_ms();
ctx->last_heartbeat_ms = ctx->last_activity_ms;
ctx->recv_len = 0;
DBG_LOGIC("[%s] connected OK\r\n", ctx->label);
return 0;
}
@@ -116,6 +121,7 @@ static int32_t tcp_send_frame(TcpStreamCtx_t *ctx, uint8_t msg_class,
}
static void tcp_send_handshake(TcpStreamCtx_t *ctx) {
DBG_LOGIC("[%s] sending handshake\r\n", ctx->label);
uint8_t payload[54];
memset(payload, 0, sizeof(payload));
qdx_write_u16_le(payload + 0, 0x0200);
@@ -135,6 +141,7 @@ static void tcp_send_handshake(TcpStreamCtx_t *ctx) {
}
static void tcp_send_heartbeat(TcpStreamCtx_t *ctx) {
DBG_LOGIC("[%s] heartbeat\r\n", ctx->label);
uint8_t payload[6];
qdx_write_u32_le(payload + 0, qdx_port_get_tick_ms());
payload[4] = 10; /* Placeholder CpuLoad */
@@ -244,19 +251,18 @@ static void parse_and_dispatch_tlv(TcpStreamCtx_t *ctx, const uint8_t *packet,
uint8_t cfg_updated = 0;
//printf("\n[DEBUG][%s] 收到 TLV 包: Seq=%d, PayloadLen=%d\n", ctx->label,
// hdr_seq, payload_len);
DBG_LOGIC("[%s] TLV pkt: Seq=%d, PayloadLen=%d\r\n", ctx->label,
hdr_seq, payload_len);
while (parsed_len <= payload_len - 3) {
uint8_t type = packet[offset];
uint16_t len = qdx_read_u16_le(packet + offset + 1);
//printf("[DEBUG][%s] -> 解析 TLV: Type=0x%02X, Len=%d\n", ctx->label, type,
//len);
DBG_LOGIC("[%s] TLV: Type=0x%02X, Len=%d\r\n", ctx->label, type, len);
if (parsed_len + 3 + len > payload_len) {
//printf("[DEBUG][%s] ! 结构错误: 剩余长度不足 (需 %d, 剩 %d)\n",
//ctx->label, len, payload_len - parsed_len - 3);
DBG_LOGIC("[%s] ! TLV truncated (need %d, have %d)\r\n",
ctx->label, len, payload_len - parsed_len - 3);
break; /* Malformed */
}
@@ -283,15 +289,15 @@ static void parse_and_dispatch_tlv(TcpStreamCtx_t *ctx, const uint8_t *packet,
}
case TYPE_CONFIG_2D: {
if (len >= sizeof(Config2D_t)) {
//printf("[DEBUG][%s] * 解析 Config2D 成功\n", ctx->label);
DBG_LOGIC("[%s] Config2D parsed OK\r\n", ctx->label);
qdx_port_mutex_lock(g_TcpLogic.config_mutex);
qdx_deserialize_config2d(&g_TcpLogic.cached_cfg2d, value);
g_TcpLogic.has_valid_config = 1; /* 任意配置到达即标记有效 */
cfg_updated = 1;
qdx_port_mutex_unlock(g_TcpLogic.config_mutex);
} else {
//printf("[DEBUG][%s] ! Config2D 长度不对: len=%d, sizeof=%d\n",
//ctx->label, len, (int)sizeof(Config2D_t));
DBG_LOGIC("[%s] ! Config2D bad len=%d (need %d)\r\n",
ctx->label, len, (int)sizeof(Config2D_t));
}
break;
}
@@ -379,19 +385,16 @@ static void tcp_process_rx_buffer(TcpStreamCtx_t *ctx) {
uint16_t length = qdx_read_u16_le(ctx->recv_buffer + 3);
if (version != PROTO_VERSION || length < HEADER_SIZE + CRC_SIZE) {
/* 丢弃 Magic 标记,缓冲区内部左移 2 字节 */
//printf("\n[DEBUG][%s] 错误: Header 验证失败! Version=0x%02X "
//"(Expected=0x%02X), Length=%d\n",
//ctx->label, version, PROTO_VERSION, length);
DBG_LOGIC("[%s] bad header: ver=0x%02X(exp 0x%02X) len=%d\r\n",
ctx->label, version, PROTO_VERSION, length);
memmove(ctx->recv_buffer, ctx->recv_buffer + 2, ctx->recv_len - 2);
ctx->recv_len -= 2;
continue;
}
if (length > sizeof(ctx->recv_buffer)) {
/* Frame too large, drop entirely */
//printf("\n[DEBUG][%s] 错误: 帧长度超限 (length=%d, max=%d)\n", ctx->label,
//length, (int)sizeof(ctx->recv_buffer));
DBG_LOGIC("[%s] frame too large: %d > %d\r\n", ctx->label,
length, (int)sizeof(ctx->recv_buffer));
ctx->recv_len = 0;
break;
}
@@ -408,9 +411,8 @@ static void tcp_process_rx_buffer(TcpStreamCtx_t *ctx) {
/* 3. Dispatch */
parse_and_dispatch_tlv(ctx, ctx->recv_buffer, length);
} else {
//printf("\n[DEBUG][%s] 错误: CRC 校验失败! Calc=0x%04X, Recv=0x%04X "
//"(Len=%d)\n",
//ctx->label, calculated_crc, received_crc, length);
DBG_LOGIC("[%s] CRC fail: calc=0x%04X recv=0x%04X len=%d\r\n",
ctx->label, calculated_crc, received_crc, length);
}
/* 4. 移除已处理帧(缓冲区内部左移,必须 memmove) */
+16 -10
View File
@@ -101,10 +101,10 @@ static void Config_Flash_SRAM(FLASH_SRAM_DEFIN mode)
}
u8 MACAddr[6];
u8 IPAddr[4] = {192, 168, 1, 10};
u8 GWIPAddr[4] = {192, 168, 1, 1};
u8 IPAddr[4] = {192, 168, 7, 10};
u8 GWIPAddr[4] = {192, 168, 7, 1};
u8 IPMask[4] = {255, 255, 255, 0};
u8 DESIP[4] = {192, 168, 1, 50};
u8 DESIP[4] = {192, 168, 7, 50};
u16 desport = 5512;
u16 srcport = 5511;
@@ -145,6 +145,7 @@ extern void qdx_port_init(void);
void WCHNET_HandleSockInt(u8 socketid, u8 intstat)
{
DBG_APP("SockInt: id=%d stat=0x%02X\r\n", socketid, intstat);
if (intstat & SINT_STAT_RECV)
{
qdx_port_sock_recv_notify(socketid);
@@ -153,17 +154,17 @@ void WCHNET_HandleSockInt(u8 socketid, u8 intstat)
{
WCHNET_ModifyRecvBuf(socketid, (u32)SocketRecvBuf[socketid], RECE_BUF_LEN);
qdx_port_sock_connect_notify(socketid);
printf("TCP Connected, socket %d\r\n", socketid);
DBG_APP("TCP Connected, socket %d\r\n", socketid);
}
if (intstat & SINT_STAT_DISCONNECT)
{
qdx_port_sock_disconnect_notify(socketid);
printf("TCP Disconnected, socket %d\r\n", socketid);
DBG_APP("TCP Disconnected, socket %d\r\n", socketid);
}
if (intstat & SINT_STAT_TIM_OUT)
{
qdx_port_sock_disconnect_notify(socketid);
printf("TCP Timeout, socket %d\r\n", socketid);
DBG_APP("TCP Timeout, socket %d\r\n", socketid);
}
}
@@ -173,11 +174,13 @@ void WCHNET_HandleGlobalInt(void)
u16 i;
u8 socketint;
intstat = WCHNET_GetGlobalInt();
if (intstat & GINT_STAT_UNREACH) printf("GINT_STAT_UNREACH\r\n");
if (intstat & GINT_STAT_IP_CONFLI) printf("GINT_STAT_IP_CONFLI\r\n");
DBG_APP("GlobalInt: 0x%02X\r\n", intstat);
if (intstat & GINT_STAT_UNREACH) DBG_APP("GINT_STAT_UNREACH\r\n");
if (intstat & GINT_STAT_IP_CONFLI) DBG_APP("GINT_STAT_IP_CONFLI\r\n");
if (intstat & GINT_STAT_PHY_CHANGE) {
if (WCHNET_GetPHYStatus() & PHY_Linked_Status)
printf("PHY Link Success\r\n");
i = WCHNET_GetPHYStatus();
DBG_APP("PHY_CHANGE: status=0x%04X %s\r\n", i,
(i & PHY_Linked_Status) ? "LINK_UP" : "LINK_DOWN");
}
if (intstat & GINT_STAT_SOCKET) {
for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) {
@@ -301,11 +304,14 @@ int main(void)
TcpLogic_Init(MACAddr, NULL);
TcpLogic_RegisterConfigCallback(OnConfigUpdate);
TcpLogic_RegisterDetectionCallback(OnDetectionResult);
DBG_APP("TcpLogic_Start...\r\n");
TcpLogic_Start();
DBG_APP("Creating RTOS tasks...\r\n");
xTaskCreate(task_wchnet_entry, "wchnet", 512, NULL, 6, NULL);
xTaskCreate(task_business_entry, "business", 512, NULL, 5, NULL);
xTaskCreate(task_heartbeat_entry, "hb", 256, NULL, 3, NULL);
DBG_APP("Starting scheduler\r\n");
vTaskStartScheduler();
/* Should never reach here */