Commit bb8d4efb authored by Wenxi XU's avatar Wenxi XU
Browse files

修改串口if,减少无用帧头

parent 6d084531
Loading
Loading
Loading
Loading
+90 −150
Original line number Diff line number Diff line
@@ -10,167 +10,73 @@
#include <zephyr/net_buf.h>

#include "ares/interface/ares_interface.h"
#include "uart.h"
#include "uart.h" // 确保包含了上面修改后的头文件
#include "zephyr/sys/ring_buffer.h"
#include <ares/protocol/ares_protocol.h>

// Define a log level for this module
#ifndef CONFIG_ARES_UART_LOG_LEVEL
#define CONFIG_ARES_UART_LOG_LEVEL LOG_LEVEL_DBG
#endif
LOG_MODULE_REGISTER(ares_uart, CONFIG_ARES_UART_LOG_LEVEL);
LOG_MODULE_REGISTER(ares_uart, LOG_LEVEL_INF); // 日志级别可以按需调整

/* === Pipeline and Threading Configuration === */
/* === 配置常量 === */
#define ARES_UART_PROCESSING_THREAD_STACK_SIZE CONFIG_ARES_UART_THREAD_STACK_SIZE
#define ARES_UART_PROCESSING_THREAD_PRIORITY   K_PRIO_PREEMPT(5)
#define ARES_UART_INCOMING_MSGQ_MAX_MSGS       20
#define ARES_UART_RX_INACTIVE_TIMEOUT          10

NET_BUF_POOL_DEFINE(uart_net_buf_pool, 10, 64, 4, NULL);

// Message queue to hold incoming net_buf pointers from ISR to thread
K_MSGQ_DEFINE(incoming_data_msgq, sizeof(struct net_buf *), ARES_UART_INCOMING_MSGQ_MAX_MSGS, 4);

#define ARES_UART_IF_FRAME_HEAD 0x5533
K_MEM_SLAB_DEFINE(uart_rx_slab, ARES_UART_BLOCK_SIZE, 6, 4);

// 帧头常量 (Big Endian)
#define FRAME_SYNC_BYTE_1   0x55
#define FRAME_SYNC_BYTE_2   0x33
#define FRAME_RESERVED_BYTE 0x00
NET_BUF_POOL_DEFINE(uart_net_buf_pool, 8, 64, 4, NULL);
K_MEM_SLAB_DEFINE(uart_rx_slab, ARES_UART_BLOCK_SIZE, 8, 4);

/**
 * @brief 初始化帧解析器
 * @param parser 指向要初始化的解析器实例的指针
 */
void frame_parser_init(frame_parser_t *parser)
{
	if (parser == NULL) {
		return;
	}
	parser->state = STATE_WAIT_SYNC_1;
	parser->payload_len = 0;
	parser->payload_received_count = 0;
}

/**
 * @brief 从 ring_buf 中处理数据,寻找并解析数据帧
 * @brief 发送一个数据包到队列中
 *
 * @param parser 指向解析器实例的指针
 * @param rb 指向包含原始数据的 ring buffer 的指针
 * 这个函数现在是非阻塞的。它将数据包(net_buf)放入发送队列后立即返回。
 * 真正的发送操作由 ares_uart_tx_thread_entry 线程完成。
 * @param interface 接口实例
 * @param buf 包含载荷数据的 net_buf
 * @return 0 on success, -ENOMEM if the queue is full.
 */
void frame_parser_process(struct AresInterface *interface, frame_parser_t *parser,
			  struct ring_buf *rb)
int ares_uart_send(struct AresInterface *interface, struct net_buf *buf)
{
	uint8_t byte;

	// 只要 ring_buf 中有数据,就持续处理
	while (ring_buf_get(rb, &byte, 1) > 0) {
		LOG_DBG("Received byte: 0x%02X\n", byte);
		switch (parser->state) {
		case STATE_WAIT_SYNC_1:
			if (byte == FRAME_SYNC_BYTE_1) {
				parser->state = STATE_WAIT_SYNC_2;
				LOG_DBG("Received sync byte 1: 0x%02X\n", byte);
			}
			break;

		case STATE_WAIT_SYNC_2:
			if (byte == FRAME_SYNC_BYTE_2) {
				parser->state = STATE_WAIT_LENGTH;
				LOG_DBG("Received sync byte 2: 0x%02X\n", byte);
			} else {
				// 如果第二个字节不是 0x33,退回初始状态
				// (优化:如果这个字节恰好是0x55,可以直接进入STATE_WAIT_SYNC_2,但简单地重置更健壮)
				frame_parser_init(parser);
			}
			break;

		case STATE_WAIT_LENGTH:
			parser->payload_len = byte;
			parser->payload_received_count = 0;
			// 检查载荷长度是否有效
			if (parser->payload_len > MAX_FRAME_PAYLOAD_SIZE) {
				LOG_ERR("Invalid payload length: %u\n", parser->payload_len);
				frame_parser_init(parser); // 长度无效,重置状态机
			} else {
				parser->state = STATE_WAIT_RESERVED;
				LOG_DBG("Payload length: %u\n", parser->payload_len);
			}
			break;
	struct AresUartInterface *uart_if = interface->priv_data;

		case STATE_WAIT_RESERVED:
			if (byte == FRAME_RESERVED_BYTE) {
				// 保留字节正确
				if (parser->payload_len == 0) {
					// 如果载荷长度为0,我们已经有了一个完整的帧
					struct net_buf *buf = net_buf_alloc_with_data(
						&uart_net_buf_pool, parser->payload_buffer,
						parser->payload_len, K_NO_WAIT);
					interface->protocol->api->handle(interface->protocol, buf);
	if (k_msgq_put(&uart_if->tx_msgq, &buf, K_NO_WAIT) != 0) {
		LOG_ERR("TX message queue is full. Dropping packet!");
		net_buf_unref(buf);
					frame_parser_init(parser); // 重置以寻找下一帧
				} else {
					// 准备接收载荷
					parser->state = STATE_RECEIVING_PAYLOAD;
		return -ENOMEM;
	}
			} else {
				// 保留字节错误,说明这不是一个有效的帧头,重置
				LOG_ERR("Invalid reserved byte: 0x%02X\n", byte);
				frame_parser_init(parser);
			}
			break;

		case STATE_RECEIVING_PAYLOAD:
			// 将接收到的字节存入载荷缓冲区
			parser->payload_buffer[parser->payload_received_count] = byte;
			parser->payload_received_count++;

			// 检查是否已接收完所有载荷数据
			if (parser->payload_received_count >= parser->payload_len) {
				LOG_DBG("Payload received: %u\n", parser->payload_received_count);
				// 载荷接收完毕,一个完整的帧已找到
				struct net_buf *buf = net_buf_alloc_with_data(
					&uart_net_buf_pool, parser->payload_buffer,
					parser->payload_len, K_NO_WAIT);
				interface->protocol->api->handle(interface->protocol, buf);
				net_buf_unref(buf);

				// 重置状态机,准备寻找下一个帧
				frame_parser_init(parser);
	return 0;
}
			break;

		default:
			// 不应该发生的状态,安全起见重置
			LOG_ERR("Invalid state: %d", parser->state);
			frame_parser_init(parser);
			break;
		}
	}
struct net_buf *ares_uart_interface_alloc_buf(struct AresInterface *interface)
{
	struct net_buf *buf = net_buf_alloc(&uart_net_buf_pool, K_NO_WAIT);
	return buf;
}

int ares_uart_tx_without_lock(struct AresInterface *interface, struct net_buf *buf)
/**
 * @brief (新增) 发送线程入口函数
 *
 * 该线程是数据发送的唯一执行者。它从队列中获取数据,
 * 并通过信号量与 UART TX 完成中断同步,实现流量控制。
 */
static void ares_uart_tx_thread_entry(void *p1, void *p2, void *p3)
{
	struct AresInterface *interface = p1;
	struct AresUartInterface *uart_if = interface->priv_data;
	uint8_t len = buf->len;
	net_buf_push_u8(buf, 0);
	net_buf_push_u8(buf, len);
	net_buf_push_be16(buf, ARES_UART_IF_FRAME_HEAD);
	struct net_buf *buf;
	int err;

	int err = uart_tx(uart_if->uart_dev, buf->data, buf->len, 0);
	while (1) {
		k_msgq_get(&uart_if->tx_msgq, &buf, K_FOREVER);
		k_sem_take(&uart_if->tx_sem, K_FOREVER);
		uart_if->current_tx_buf = buf;
		err = uart_tx(uart_if->uart_dev, buf->data, buf->len, SYS_FOREVER_US);
		if (err != 0) {
		LOG_ERR("Failed to send data.");
		return err;
			LOG_ERR("uart_tx failed with error %d, even with flow control!", err);
			k_sem_give(&uart_if->tx_sem);
			net_buf_unref(uart_if->current_tx_buf);
			uart_if->current_tx_buf = NULL;
		}
	net_buf_unref(buf);
	return 0;
	}

struct net_buf *ares_uart_interface_alloc_buf(struct AresInterface *interface)
{
	struct net_buf *buf = net_buf_alloc(&uart_net_buf_pool, K_NO_WAIT);
	return buf;
}

// async serial callback
@@ -180,35 +86,41 @@ static void uart_callback(const struct device *dev, struct uart_event *evt, void
	int err;

	switch (evt->type) {
	/* --- TX 事件处理 --- */
	case UART_TX_DONE:
		// LOG_INF("Tx sent %d bytes\n", evt->data.tx.len);
		if (uart_if->current_tx_buf != NULL) {
			net_buf_unref(uart_if->current_tx_buf);
			uart_if->current_tx_buf = NULL;
		}
		k_sem_give(&uart_if->tx_sem);
		break;

	case UART_TX_ABORTED:
		// LOG_INF("Tx aborted. Is the serial fast enough?\n");
		LOG_WRN("UART TX aborted");
		if (uart_if->current_tx_buf != NULL) {
			net_buf_unref(uart_if->current_tx_buf);
			uart_if->current_tx_buf = NULL;
		}
		k_sem_give(&uart_if->tx_sem);
		break;

	/* --- RX 事件处理 (保持不变) --- */
	case UART_RX_RDY: {
		LOG_DBG("Received data %d bytes\n", evt->data.rx.len);

		if (evt->data.rx.len > 0) {
			ring_buf_put(&uart_if->uart_rb, evt->data.rx.buf + evt->data.rx.offset,
				     evt->data.rx.len);
			k_sem_give(&uart_if->sem);
		}

		break;
	}

	case UART_RX_BUF_REQUEST: {
		uint8_t *buf;

		err = k_mem_slab_alloc(&uart_rx_slab, (void **)&buf, K_NO_WAIT);
		if (err != 0) {
			LOG_ERR("Failed to allocate memory for RX buffer.");
			return;
		}

		err = uart_rx_buf_rsp(uart_if->uart_dev, buf, ARES_UART_BLOCK_SIZE);
		if (err != 0) {
			LOG_ERR("Failed to provide new buffer.");
@@ -230,6 +142,16 @@ static void uart_callback(const struct device *dev, struct uart_event *evt, void
	}
}

void frame_parser_process(struct AresInterface *interface, struct ring_buf *rb)
{
	uint8_t byte;

	while (ring_buf_get(rb, &byte, 1) > 0) {
		interface->protocol->api->handle_byte(interface->protocol, byte);
	}
}

// 接收线程入口函数 (保持不变)
void ares_uart_thread_entry(void *p1, void *p2, void *p3)
{
	struct AresInterface *interface = p1;
@@ -237,7 +159,7 @@ void ares_uart_thread_entry(void *p1, void *p2, void *p3)

	while (1) {
		k_sem_take(&uart_if->sem, K_FOREVER);
		frame_parser_process(interface, &uart_if->parser, &uart_if->uart_rb);
		frame_parser_process(interface, &uart_if->uart_rb);
	}
}

@@ -247,7 +169,7 @@ void ares_uart_init_dev(struct AresInterface *interface, const struct device *ua
	uart_if->uart_dev = (struct device *)uart_dev;
}

// 初始化函数
// 初始化函数 (修改)
int ares_uart_init(struct AresInterface *interface)
{
	struct AresUartInterface *uart_if = interface->priv_data;
@@ -259,12 +181,16 @@ int ares_uart_init(struct AresInterface *interface)

	int err = 0;

	/* --- 初始化 RX 部分 (和原来一样) --- */
	ring_buf_init(&uart_if->uart_rb, sizeof(uart_if->uart_rb_buf), uart_if->uart_rb_buf);
	k_sem_init(&uart_if->sem, 0, 1);

	err = uart_callback_set(uart_if->uart_dev, uart_callback, (void *)uart_if);
	if (err) {
		LOG_ERR("uart_callback_set failed: %d", err);
		return err;
	}

	// allocate buffer and start rx
	uint8_t *buf;
	err = k_mem_slab_alloc(&uart_rx_slab, (void **)&buf, K_NO_WAIT);
	__ASSERT(err == 0, "Failed to alloc slab");
@@ -275,9 +201,23 @@ int ares_uart_init(struct AresInterface *interface)
	k_thread_create(&uart_if->thread, uart_if->thread_stack,
			ARES_UART_PROCESSING_THREAD_STACK_SIZE, ares_uart_thread_entry,
			(void *)interface, NULL, NULL, ARES_UART_PROCESSING_THREAD_PRIORITY, 0,
			K_MSEC(100));
	__ASSERT(uart_if->thread != NULL, "Failed to create thread");
			K_NO_WAIT);
	k_thread_name_set(&uart_if->thread, "ares_uart_rx");
	k_thread_start(&uart_if->thread);

	/* --- 新增: 初始化 TX 部分 --- */
	uart_if->current_tx_buf = NULL;
	k_msgq_init(&uart_if->tx_msgq, uart_if->tx_msgq_buffer, sizeof(struct net_buf *),
		    ARES_UART_TX_QUEUE_SIZE);
	k_sem_init(&uart_if->tx_sem, 1, 1);

	k_thread_create(&uart_if->tx_thread, uart_if->tx_thread_stack,
			ARES_UART_TX_THREAD_STACK_SIZE, ares_uart_tx_thread_entry,
			(void *)interface, NULL, NULL, ARES_UART_PROCESSING_THREAD_PRIORITY, 0,
			K_NO_WAIT);
	k_thread_name_set(&uart_if->tx_thread, "ares_uart_tx");
	k_thread_start(&uart_if->tx_thread);

	LOG_INF("Ares UART Interface initialized with TX queue.");
	return 0;
}
 No newline at end of file
+11 −20
Original line number Diff line number Diff line
@@ -15,32 +15,18 @@
#include "ares/interface/ares_interface.h"

int ares_uart_init(struct AresInterface *interface);
int ares_uart_tx_without_lock(struct AresInterface *interface, struct net_buf *buf);
int ares_uart_send(struct AresInterface *interface, struct net_buf *buf);
struct net_buf *ares_uart_interface_alloc_buf(struct AresInterface *interface);

void ares_uart_init_dev(struct AresInterface *interface, const struct device *uart_dev);

#define ARES_UART_PROCESSING_THREAD_STACK_SIZE CONFIG_ARES_UART_THREAD_STACK_SIZE

// 解析器状态机
typedef enum {
	STATE_WAIT_SYNC_1,      // 等待第一个同步字节 0x55
	STATE_WAIT_SYNC_2,      // 已收到 0x55, 等待 0x33
	STATE_WAIT_LENGTH,      // 已收到帧头, 等待长度字节
	STATE_WAIT_RESERVED,    // 已收到长度, 等待保留字节 0x00
	STATE_RECEIVING_PAYLOAD // 正在接收载荷数据
} frame_parser_state_t;
#define ARES_UART_TX_THREAD_STACK_SIZE CONFIG_ARES_UART_THREAD_STACK_SIZE

#define ARES_UART_BLOCK_SIZE    72
#define MAX_FRAME_PAYLOAD_SIZE  ARES_UART_BLOCK_SIZE
#define ARES_UART_TX_QUEUE_SIZE 10

// 帧解析器结构体
typedef struct {
	frame_parser_state_t state;                     // 当前状态
	uint8_t payload_len;                            // 当前帧期望的载荷长度
	uint16_t payload_received_count;                // 当前已接收的载荷字节数
	uint8_t payload_buffer[MAX_FRAME_PAYLOAD_SIZE]; // 用于组装载荷的缓冲区
} frame_parser_t;

struct AresUartInterface {
	struct AresInterface *interface;
@@ -57,13 +43,18 @@ struct AresUartInterface {
	struct k_thread thread;
	k_thread_stack_t thread_stack[ARES_UART_PROCESSING_THREAD_STACK_SIZE];

	frame_parser_t parser;
	struct k_msgq tx_msgq;                 // 发送消息队列
    char __aligned(4) tx_msgq_buffer[sizeof(struct net_buf *) * ARES_UART_TX_QUEUE_SIZE];
    struct k_sem tx_sem;                   // 用于发送流控制的信号量
    struct net_buf *current_tx_buf;        // 指向当前正在发送的buf
	struct k_thread tx_thread;             // 发送线程的句柄
    k_thread_stack_t tx_thread_stack[ARES_UART_TX_THREAD_STACK_SIZE]; // 发送线程的栈
};

#define ARES_UART_INTERFACE_DEFINE(Interface_name)                                                 \
	struct AresInterfaceAPI ares_uart_interface_api = {                                        \
		.init = ares_uart_init,                                                            \
		.send = ares_uart_tx_without_lock,                                                           \
		.send = ares_uart_send,                                                           \
		.alloc_buf = ares_uart_interface_alloc_buf,                                             \
	};                                                                                         \
	struct AresUartInterface Internal_##Interface_name = {NULL};                               \