3.27_433:实现并验证RF433模块接收相应指令:新增UART路由核心模块,使程序能响应RF433/RS485指令,并向UART2输出LOG(RS485由于硬件原因未验证)
This commit is contained in:
222
Core/Src/cmd_router.c
Normal file
222
Core/Src/cmd_router.c
Normal file
@ -0,0 +1,222 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file cmd_router.c
|
||||
* @brief 指令路由与响应分发模块实现
|
||||
* @author Application Layer
|
||||
* @version 1.0
|
||||
******************************************************************************
|
||||
* @attention
|
||||
* 本模块实现指令路由与响应分发功能
|
||||
* 设计依据:多通信接口统一指令处理系统开发计划 第3.2节
|
||||
*
|
||||
* 核心职责:
|
||||
* - 从各UART端口读取数据并喂入解析器
|
||||
* - 根据指令来源端口路由响应
|
||||
* - 管理响应路由表
|
||||
*
|
||||
* 工作流程:
|
||||
* 1. 中断中将接收字节写入对应端口的环形缓冲区
|
||||
* 2. 主循环中CmdRouter_Task轮询各端口缓冲区
|
||||
* 3. 读取字节喂入CmdParser解析器
|
||||
* 4. 解析完成后通过回调发送响应到源端口
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "cmd_router.h"
|
||||
#include "multi_uart_router.h"
|
||||
#include "cmd_parser.h"
|
||||
#include "uart2_print.h"
|
||||
#include "debug_log.h"
|
||||
#include <string.h>
|
||||
|
||||
#define DEBUG_CMD_ROUTER 1
|
||||
|
||||
#if DEBUG_CMD_ROUTER
|
||||
#define ROUTER_LOG(fmt, ...) UART2_Print_Printf("[ROUTER] " fmt "\r\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define ROUTER_LOG(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define RX_LOG_BUFFER_SIZE 128
|
||||
|
||||
typedef struct {
|
||||
uint8_t source_port;
|
||||
uint32_t last_feed_tick;
|
||||
uint32_t rx_count;
|
||||
bool active;
|
||||
} port_parser_state_t;
|
||||
|
||||
static port_parser_state_t g_port_states[PORT_COUNT];
|
||||
|
||||
static cmd_response_handler_t g_response_handler = NULL;
|
||||
|
||||
static uint32_t g_processed_count = 0;
|
||||
static uint32_t g_routed_count = 0;
|
||||
|
||||
static uint8_t g_current_parsing_port = PORT_UART2;
|
||||
|
||||
static uint8_t g_rx_log_buffer[PORT_COUNT][RX_LOG_BUFFER_SIZE];
|
||||
static uint16_t g_rx_log_len[PORT_COUNT];
|
||||
static uint32_t g_rx_log_last_tick[PORT_COUNT];
|
||||
#define RX_LOG_TIMEOUT_MS 50
|
||||
|
||||
static void flush_rx_log(port_id_t port_id)
|
||||
{
|
||||
if (g_rx_log_len[port_id] == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
UART2_Print_Printf("[ROUTER] %s RX: \"", MultiUART_GetPortName(port_id));
|
||||
|
||||
for (uint16_t i = 0; i < g_rx_log_len[port_id]; i++) {
|
||||
uint8_t c = g_rx_log_buffer[port_id][i];
|
||||
if (c >= 0x20 && c < 0x7F) {
|
||||
UART2_Print_Send(&c, 1);
|
||||
} else if (c == '\r') {
|
||||
UART2_Print_Send((const uint8_t *)"\\r", 2);
|
||||
} else if (c == '\n') {
|
||||
UART2_Print_Send((const uint8_t *)"\\n", 2);
|
||||
} else {
|
||||
char hex[4];
|
||||
snprintf(hex, sizeof(hex), "\\x%02X", c);
|
||||
UART2_Print_Send((const uint8_t *)hex, 4);
|
||||
}
|
||||
}
|
||||
|
||||
UART2_Print_String("\"\r\n");
|
||||
|
||||
g_rx_log_len[port_id] = 0;
|
||||
}
|
||||
|
||||
static void append_rx_log(port_id_t port_id, uint8_t byte)
|
||||
{
|
||||
if (g_rx_log_len[port_id] < RX_LOG_BUFFER_SIZE) {
|
||||
g_rx_log_buffer[port_id][g_rx_log_len[port_id]++] = byte;
|
||||
}
|
||||
g_rx_log_last_tick[port_id] = HAL_GetTick();
|
||||
}
|
||||
|
||||
static void cmd_parser_response_callback(uint8_t source_port, const char *response)
|
||||
{
|
||||
if (g_response_handler != NULL) {
|
||||
g_response_handler((port_id_t)source_port, response, strlen(response));
|
||||
g_routed_count++;
|
||||
} else {
|
||||
MultiUART_SendString((port_id_t)source_port, response);
|
||||
g_routed_count++;
|
||||
}
|
||||
|
||||
LOG_INFO("ROUTER", "TX[%s]: %s",
|
||||
MultiUART_GetPortName((port_id_t)source_port), response);
|
||||
}
|
||||
|
||||
void CmdRouter_Init(void)
|
||||
{
|
||||
for (port_id_t i = 0; i < PORT_COUNT; i++) {
|
||||
g_port_states[i].source_port = i;
|
||||
g_port_states[i].last_feed_tick = 0;
|
||||
g_port_states[i].rx_count = 0;
|
||||
g_port_states[i].active = false;
|
||||
|
||||
g_rx_log_len[i] = 0;
|
||||
g_rx_log_last_tick[i] = 0;
|
||||
}
|
||||
|
||||
g_response_handler = NULL;
|
||||
g_processed_count = 0;
|
||||
g_routed_count = 0;
|
||||
g_current_parsing_port = PORT_UART2;
|
||||
|
||||
CmdParser_SetResponseCallback(cmd_parser_response_callback);
|
||||
|
||||
ROUTER_LOG("Init OK, %d ports registered", PORT_COUNT);
|
||||
}
|
||||
|
||||
void CmdRouter_Task(void)
|
||||
{
|
||||
uint32_t current_tick = HAL_GetTick();
|
||||
|
||||
for (port_id_t port_id = 0; port_id < PORT_COUNT; port_id++) {
|
||||
if (port_id == PORT_UART2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rx_log_len[port_id] > 0 &&
|
||||
(current_tick - g_rx_log_last_tick[port_id]) >= RX_LOG_TIMEOUT_MS) {
|
||||
flush_rx_log(port_id);
|
||||
}
|
||||
}
|
||||
|
||||
for (port_id_t port_id = 0; port_id < PORT_COUNT; port_id++) {
|
||||
if (port_id == PORT_UART2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint16_t rx_count = MultiUART_GetRxCount(port_id);
|
||||
|
||||
if (rx_count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
g_current_parsing_port = port_id;
|
||||
CmdParser_SetSourcePort(port_id);
|
||||
|
||||
uint8_t byte;
|
||||
while (MultiUART_ReadByte(port_id, &byte) > 0) {
|
||||
append_rx_log(port_id, byte);
|
||||
CmdParser_FeedByte(byte, HAL_GetTick());
|
||||
g_port_states[port_id].rx_count++;
|
||||
}
|
||||
|
||||
if (CmdParser_HasCompleteFrame(NULL)) {
|
||||
flush_rx_log(port_id);
|
||||
g_processed_count++;
|
||||
g_port_states[port_id].active = true;
|
||||
}
|
||||
}
|
||||
|
||||
CmdParser_Task();
|
||||
}
|
||||
|
||||
void CmdRouter_SetResponseHandler(cmd_response_handler_t handler)
|
||||
{
|
||||
g_response_handler = handler;
|
||||
ROUTER_LOG("Response handler %s", handler ? "set" : "cleared");
|
||||
}
|
||||
|
||||
void CmdRouter_SendResponse(port_id_t port, const char *response, uint16_t len)
|
||||
{
|
||||
if (port >= PORT_COUNT || response == NULL || len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
MultiUART_Send(port, (const uint8_t *)response, len);
|
||||
g_routed_count++;
|
||||
|
||||
LOG_INFO("ROUTER", "SendResponse[%s]: %.*s",
|
||||
MultiUART_GetPortName(port), len, response);
|
||||
}
|
||||
|
||||
void CmdRouter_BroadcastResponse(const char *response, uint16_t len)
|
||||
{
|
||||
if (response == NULL || len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (port_id_t port = 0; port < PORT_COUNT; port++) {
|
||||
MultiUART_Send(port, (const uint8_t *)response, len);
|
||||
g_routed_count++;
|
||||
}
|
||||
|
||||
LOG_INFO("ROUTER", "Broadcast: %.*s", len, response);
|
||||
}
|
||||
|
||||
uint32_t CmdRouter_GetProcessedCount(void)
|
||||
{
|
||||
return g_processed_count;
|
||||
}
|
||||
|
||||
uint32_t CmdRouter_GetRoutedCount(void)
|
||||
{
|
||||
return g_routed_count;
|
||||
}
|
||||
Reference in New Issue
Block a user