#define PPP_OPTIMIZED_UART_WRITE_TIMEOUT 200 /* UART写超时优化: 1000ms -> 200ms */
#define PPP_OPTIMIZED_UART_READ_TIMEOUT 100 /* UART读超时优化: 200ms -> 100ms */
#if defined(CONFIG_UART_SUPPORT_DMA)
-#define UART_DMA_WIDTH 0
-#define UART_DMA_BURST_LENGTH 2
-#define UART_DMA_PRIORITY 0
-#define UART_DMA_TX_ENABLE 1
+/*
+
+uint8_t src_width; 源端传输数据宽度 - 0: 1字节
+ * - 1: 2字节
+ * - 2: 4字节
+uint8_t dest_width; 目的端传输数据宽度 - 0: 1字节
+ * - 1: 2字节
+ * - 2: 4字节
+uint8_t burst_length; - 0: burst长度是1
+ * - 1: burst长度是4
+ * - 2: burst长度是8
+ * - 3: burst长度是16
+uint8_t priority; 传输通道优先级(最小为0以及最大为3)
+*/
+#define UART_DMA_WIDTH 2
+#define UART_DMA_BURST_LENGTH 3
+#define UART_DMA_PRIORITY 2
+#define UART_DMA_TX_ENABLE 0
#define UART_DMA_RX_ENABLE 1
#endif
/* 串口上下文结构 - 优化缓存机制 */
uint32_t rx_tail;
uint32_t rx_count;
- /* PPP模式的发送缓冲区 */
- uint8_t *tx_buffer;
- uint32_t tx_buffer_size;
- uint32_t tx_head;
- uint32_t tx_tail;
- uint32_t tx_count;
-
/* 同步对象 */
osal_mutex rx_mutex; // 改为结构体而不是指针
osal_semaphore rx_semaphore; // 改为结构体而不是指针
- osal_mutex tx_mutex; // 发送缓冲区互斥锁
/* 回调函数 */
ppp_serial_rx_callback_t rx_callback;
static void ppp_serial_rx_callback(const void *buffer, uint16_t length, bool remaining);
static uint32_t ppp_serial_buffer_available_space(void);
static uint32_t ppp_serial_buffer_data_count(void);
-static uint32_t ppp_serial_tx_buffer_available_space(void);
-static uint32_t ppp_serial_tx_buffer_data_count(void);
-static ppp_error_t ppp_serial_flush_tx_buffer_internal(void);
static bool ppp_serial_is_ppp_control_packet(const uint8_t *data, uint32_t length);
-static bool ppp_serial_should_immediate_flush(const uint8_t *data, uint32_t length, uint32_t buffered_count);
static uint32_t ppp_serial_get_current_time_ms(void);
static ppp_error_t ppp_serial_register_irq(void);
static ppp_error_t ppp_serial_unregister_irq(void);
PPP_DEBUG_DEBUG(" - TX Pin: %u", config->tx_pin);
PPP_DEBUG_DEBUG(" - RX Pin: %u", config->rx_pin);
PPP_DEBUG_DEBUG(" - RX Buffer Size: %u bytes", config->rx_buffer_size);
- PPP_DEBUG_DEBUG(" - TX Buffer Size: %u bytes", config->tx_buffer_size);
PPP_DEBUG_DEBUG(" - RX Callback: %s", config->rx_callback ? "Set" : "NULL");
/* 配置UART参数 */
}
PPP_DEBUG_DEBUG("RX buffer allocated: %u bytes at 0x%p", g_serial_ctx.rx_buffer_size, g_serial_ctx.rx_buffer);
- /* 动态分配发送缓冲区 */
- g_serial_ctx.tx_buffer_size = config->tx_buffer_size;
- g_serial_ctx.tx_buffer = (uint8_t *)osal_kmalloc(g_serial_ctx.tx_buffer_size, OSAL_GFP_KERNEL);
- if (g_serial_ctx.tx_buffer == NULL) {
- PPP_DEBUG_ERROR("Failed to allocate TX buffer (%u bytes)", g_serial_ctx.tx_buffer_size);
- osal_kfree(g_serial_ctx.rx_buffer);
- g_serial_ctx.rx_buffer = NULL;
- return PPP_ERR_MEMORY;
- }
- PPP_DEBUG_DEBUG("TX buffer allocated: %u bytes at 0x%p", g_serial_ctx.tx_buffer_size, g_serial_ctx.tx_buffer);
-
- /* 创建发送缓冲区互斥锁 */
- if (osal_mutex_init(&g_serial_ctx.tx_mutex) != OSAL_SUCCESS) {
- PPP_DEBUG_ERROR("Failed to create TX mutex");
- osal_kfree(g_serial_ctx.rx_buffer);
- g_serial_ctx.rx_buffer = NULL;
- osal_kfree(g_serial_ctx.tx_buffer);
- g_serial_ctx.tx_buffer = NULL;
- uapi_uart_deinit(g_serial_ctx.uart_bus);
- return PPP_ERR_MEMORY;
- }
- PPP_DEBUG_DEBUG("TX mutex created successfully");
-
/* 配置UART使用我们分配的接收缓冲区 */
g_serial_ctx.buffer_config.rx_buffer = g_serial_ctx.rx_buffer;
g_serial_ctx.buffer_config.rx_buffer_size = g_serial_ctx.rx_buffer_size;
PPP_DEBUG_DEBUG("UART buffer config:");
PPP_DEBUG_DEBUG(" - RX Buffer Address: 0x%p", g_serial_ctx.buffer_config.rx_buffer);
PPP_DEBUG_DEBUG(" - RX Buffer Size: %u", g_serial_ctx.buffer_config.rx_buffer_size);
- PPP_DEBUG_DEBUG("PPP TX buffer (software managed):");
- PPP_DEBUG_DEBUG(" - TX Buffer Address: 0x%p", g_serial_ctx.tx_buffer);
- PPP_DEBUG_DEBUG(" - TX Buffer Size: %u", g_serial_ctx.tx_buffer_size);
// errcode_t rett = uapi_uart_deinit(g_serial_ctx.uart_bus);
// if (rett != ERRCODE_SUCC) {
/* 初始化UART */
PPP_DEBUG_DEBUG("Calling uapi_uart_init...");
- #if defined(PPP_USE_INTERRUPT_MODE) && (PPP_USE_INTERRUPT_MODE == 0)
- // 注意:uart_porting.c中已经做了UART初始化,这里只需要设置属性
-
+ // ⚠️ 修复:区分轮询模式和中断模式的UART初始化策略
+ // - 轮询模式(SUPPORT_PPP_SERVICE_POLLING):uart_porting.c中UART_BUS_0的pin=PIN_NONE,
+ // 未在启动时初始化,需要在这里完整初始化UART(但DMA已在chip_init.c中初始化)
+ // - 中断模式(SUPPORT_PPP_SERVICE_INTERRUPT):uart_porting.c中已完整初始化UART,
+ // 这里只需要设置波特率
-
+ #if defined(SUPPORT_PPP_SERVICE_POLLING)
+ // 轮询模式:完整初始化UART(注意:DMA已在chip_init.c:152-153初始化,不要重复调用)
+ PPP_DEBUG_WARN("Polling mode: Initializing UART for the first time");
#if defined(CONFIG_UART_SUPPORT_DMA)
g_serial_ctx.extra_attr.tx_dma_enable = UART_DMA_TX_ENABLE;
g_serial_ctx.extra_attr.tx_int_threshold = 0;
g_serial_ctx.extra_attr.rx_dma_enable = UART_DMA_RX_ENABLE;
g_serial_ctx.extra_attr.rx_int_threshold = 0;
- uapi_dma_init();
- uapi_dma_open();
+ PPP_DEBUG_WARN("Polling mode with DMA: TX DMA and RX DMA both enabled");
errcode_t ret = uapi_uart_init(g_serial_ctx.uart_bus,
&g_serial_ctx.pin_config,
&g_serial_ctx.uart_attr,
NULL,
&g_serial_ctx.buffer_config);
#endif
-
+ #elif defined(SUPPORT_PPP_SERVICE_INTERRUPT)
+ // 中断模式:UART已在uart_porting.c:uart_config_init()中初始化,只设置波特率
+ PPP_DEBUG_WARN("Interrupt mode: UART already initialized, updating baudrate");
+ errcode_t ret = uapi_uart_set_attr(g_serial_ctx.uart_bus, &g_serial_ctx.uart_attr);
#else
-
- // 注意:uart_porting.c中已经做了UART初始化,这里只需要设置属性
- // 需要配置 SUPPORT_PPP_SERVICE_INTERRUPT 才在uart_porting里初始化uart
- errcode_t ret = uapi_uart_set_attr(g_serial_ctx.uart_bus, &g_serial_ctx.uart_attr);
-
+ #error "Either SUPPORT_PPP_SERVICE_POLLING or SUPPORT_PPP_SERVICE_INTERRUPT must be defined"
#endif
if (ret != ERRCODE_SUCC) {
PPP_DEBUG_ERROR("Failed to initialize UART: error code = %d (0x%x)", ret, ret);
g_serial_ctx.uart_bus, config->tx_pin, config->rx_pin, config->baudrate);
osal_kfree(g_serial_ctx.rx_buffer);
g_serial_ctx.rx_buffer = NULL;
- osal_kfree(g_serial_ctx.tx_buffer);
- g_serial_ctx.tx_buffer = NULL;
- osal_mutex_destroy(&g_serial_ctx.tx_mutex);
return PPP_ERR_UART;
}
PPP_DEBUG_INFO("UART initialized successfully (error code = %d)", ret);
PPP_DEBUG_ERROR("Failed to create RX mutex");
osal_kfree(g_serial_ctx.rx_buffer);
g_serial_ctx.rx_buffer = NULL;
- osal_kfree(g_serial_ctx.tx_buffer);
- g_serial_ctx.tx_buffer = NULL;
uapi_uart_deinit(g_serial_ctx.uart_bus);
- osal_mutex_destroy(&g_serial_ctx.tx_mutex);
return PPP_ERR_MEMORY;
}
PPP_DEBUG_DEBUG("RX mutex created successfully");
osal_mutex_destroy(&g_serial_ctx.rx_mutex);
osal_kfree(g_serial_ctx.rx_buffer);
g_serial_ctx.rx_buffer = NULL;
- osal_kfree(g_serial_ctx.tx_buffer);
- g_serial_ctx.tx_buffer = NULL;
uapi_uart_deinit(g_serial_ctx.uart_bus);
- osal_mutex_destroy(&g_serial_ctx.tx_mutex);
return PPP_ERR_MEMORY;
}
PPP_DEBUG_DEBUG("RX semaphore created successfully");
g_serial_ctx.rx_head = 0;
g_serial_ctx.rx_tail = 0;
g_serial_ctx.rx_count = 0;
- g_serial_ctx.tx_head = 0;
- g_serial_ctx.tx_tail = 0;
- g_serial_ctx.tx_count = 0;
g_serial_ctx.rx_callback = config->rx_callback;
g_serial_ctx.rx_callback_arg = config->rx_callback_arg;
PPP_DEBUG_DEBUG("Buffer state initialized:");
PPP_DEBUG_DEBUG(" - RX Head/Tail/Count: %u/%u/%u", g_serial_ctx.rx_head, g_serial_ctx.rx_tail, g_serial_ctx.rx_count);
- PPP_DEBUG_DEBUG(" - TX Head/Tail/Count: %u/%u/%u", g_serial_ctx.tx_head, g_serial_ctx.tx_tail, g_serial_ctx.tx_count);
PPP_DEBUG_DEBUG(" - Current Mode: %d (AT)", g_serial_ctx.current_mode);
PPP_DEBUG_DEBUG(" - Initialized Flag: %s", g_serial_ctx.initialized ? "true" : "false");
g_serial_ctx.rx_count = 0;
osal_mutex_unlock(&g_serial_ctx.rx_mutex);
- /* 清空发送缓冲区 */
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
- g_serial_ctx.tx_head = 0;
- g_serial_ctx.tx_tail = 0;
- g_serial_ctx.tx_count = 0;
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
- PPP_DEBUG_DEBUG("TX buffer cleared for mode switch");
-
/* PPP数据模式:使用优化的直接UART读取,增加超时时间获取完整数据 */
PPP_DEBUG_DEBUG("PPP Data Mode: Using optimized direct UART read with longer timeout");
PPP_DEBUG_DEBUG("This approach is more reliable than callback mechanism");
osal_mutex_unlock(&g_serial_ctx.rx_mutex);
PPP_DEBUG_INFO("RX buffer cleared (discarded %u bytes)", old_rx_count);
- /* 清空发送缓冲区 */
- PPP_DEBUG_DEBUG("Clearing TX buffer...");
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
- uint32_t old_tx_count = g_serial_ctx.tx_count;
- g_serial_ctx.tx_head = 0;
- g_serial_ctx.tx_tail = 0;
- g_serial_ctx.tx_count = 0;
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
- PPP_DEBUG_INFO("TX buffer cleared (discarded %u bytes)", old_tx_count);
-
/* 从PPP数据模式切换回AT模式 */
if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_PPP_DATA) {
PPP_DEBUG_DEBUG("Switching from PPP data mode to AT mode");
*bytes_read = 0;
if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_PPP_DATA) {
- /* PPP数据模式:使用1ms超时快速读取,类似SLIP的sio_tryread */
-
+ /* PPP数据模式:混合策略(先轮询检测,有数据时用 DMA) */
#if defined(CONFIG_UART_SUPPORT_DMA)
- uart_write_dma_config_t dma_cfg = {
- .src_width = UART_DMA_WIDTH,
- .dest_width = UART_DMA_WIDTH,
- .burst_length = UART_DMA_BURST_LENGTH,
- .priority = UART_DMA_PRIORITY
- };
- int32_t read_result = uapi_uart_read_by_dma(g_serial_ctx.uart_bus, buffer, buffer_size,&dma_cfg);
+ // ⚠️ 核心问题:uapi_uart_read_by_dma 会阻塞 1 秒等待数据,不适合无数据时的轮询
+ // 解决方案:先用普通读取(timeout=0)快速检测,有数据时再用 DMA 批量读取
+
+ // 第 1 步:非阻塞检测是否有数据(立即返回)
+ uint8_t probe_buf[8];
+ int32_t probe_result = uapi_uart_read(g_serial_ctx.uart_bus, probe_buf, sizeof(probe_buf), 0);
+
+ int32_t read_result = 0;
+
+ if (probe_result > 0) {
+ // 有数据!先复制探测数据,再用 DMA 读取剩余数据
+ static uint32_t dma_call_count = 0;
+ static uint32_t dma_success_count = 0;
+ // 复制探测数据
+ if ((uint32_t)probe_result <= buffer_size) {
+ memcpy(buffer, probe_buf, probe_result);
+ read_result = probe_result;
+ }
+
+ // 如果 buffer 还有空间,尝试用 DMA 批量读取剩余数据
+ if ((uint32_t)probe_result < buffer_size) {
+ uint32_t remaining = buffer_size - probe_result;
+ // DMA 读取策略:既然已确认有数据,就充分利用 DMA 批量传输能力
+ // 只对足够大的块使用 DMA(>=64字节),小块数据用 DMA 开销反而更大
+ uint32_t dma_size = (remaining >= 64) ? remaining : 0;
+
+ if (dma_size > 0) {
+ uart_write_dma_config_t dma_cfg = {
+ .src_width = UART_DMA_WIDTH,
+ .dest_width = UART_DMA_WIDTH,
+ .burst_length = UART_DMA_BURST_LENGTH,
+ .priority = UART_DMA_PRIORITY
+ };
+
+ dma_call_count++;
+ if (dma_call_count == 1) {
+ PPP_DEBUG_WARN("=== Hybrid Mode: Poll + DMA ===");
+ PPP_DEBUG_WARN("Poll detects data (instant), DMA reads bulk (8-64 bytes)");
+ }
+
+ int32_t dma_result = uapi_uart_read_by_dma(g_serial_ctx.uart_bus,
+ buffer + probe_result,
+ dma_size, &dma_cfg);
+
+ if (dma_result > 0) {
+ read_result += dma_result;
+ dma_success_count++;
+ if (dma_success_count == 1 || dma_success_count % 50 == 0) {
+ PPP_DEBUG_WARN("DMA Success #%u: poll %d + DMA %d = %d bytes",
+ dma_success_count, probe_result, dma_result, read_result);
+ }
+ } else if (dma_result < 0 && dma_call_count <= 5) {
+ PPP_DEBUG_ERROR("DMA failed (%d), but poll got %d bytes",
+ dma_result, probe_result);
+ }
+ }
+ }
+ } else {
+ // 没有数据,立即返回(无阻塞)
+ read_result = 0;
+ }
+
#else
int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 0);
#endif
}
}
-/**
- * @brief 智能flush决策函数
- */
-static bool ppp_serial_should_immediate_flush(const uint8_t *data, uint32_t length, uint32_t buffered_count)
-{
- uint32_t current_time = ppp_serial_get_current_time_ms();
- uint32_t time_since_last_tx = current_time - g_serial_ctx.last_tx_time;
-
- // 1. PPP控制包立即发送(最高优先级)
- if (ppp_serial_is_ppp_control_packet(data, length)) {
- PPP_DEBUG_INFO("PPP control packet detected, immediate flush");
- return true;
- }
-
- // 2. 缓冲区接近满(87.5%阈值,比原来的75%更保守)
- if (buffered_count >= (g_serial_ctx.tx_buffer_size * 7 / 8)) {
- PPP_DEBUG_INFO("Buffer nearly full (%u/%u), immediate flush",
- buffered_count, g_serial_ctx.tx_buffer_size);
- return true;
- }
-
- // 3. 大包立即发送(降低阈值到128字节,避免分片)
- if (length >= 128) {
- PPP_DEBUG_INFO("Large packet (%u bytes), immediate flush", length);
- return true;
- }
-
- // 4. 空闲时间超过阈值
- if (time_since_last_tx >= g_serial_ctx.idle_flush_threshold) {
- PPP_DEBUG_INFO("Idle timeout (%u ms), immediate flush", time_since_last_tx);
- return true;
- }
-
- // 5. 连续小包累积策略
- if (length <= 32) {
- g_serial_ctx.consecutive_small_packets++;
- if (g_serial_ctx.consecutive_small_packets >= 3) {
- PPP_DEBUG_INFO("Multiple small packets accumulated (%u), immediate flush",
- g_serial_ctx.consecutive_small_packets);
- g_serial_ctx.consecutive_small_packets = 0;
- return true;
- }
- } else {
- g_serial_ctx.consecutive_small_packets = 0;
- }
-
- return false;
-}
-
/**
* @brief 定时flush检查函数
*/
-ppp_error_t ppp_serial_periodic_flush(void)
-{
- if (!g_serial_ctx.initialized || g_serial_ctx.current_mode != PPP_SERIAL_MODE_PPP_DATA) {
- return PPP_ERR_INVALID_PARAM;
- }
-
- uint32_t current_time = ppp_serial_get_current_time_ms();
- uint32_t time_since_last_tx = current_time - g_serial_ctx.last_tx_time;
-
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
- uint32_t buffered_count = g_serial_ctx.tx_count;
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
-
- // 如果有缓冲数据且空闲时间超过阈值,强制flush
- if (buffered_count > 0 && time_since_last_tx >= g_serial_ctx.idle_flush_threshold) {
- PPP_DEBUG_INFO("Periodic flush: %u bytes after %u ms idle",
- buffered_count, time_since_last_tx);
- g_serial_ctx.last_tx_time = current_time;
- return ppp_serial_flush_tx();
- }
-
- return PPP_ERR_OK;
-}
-
/**
* @brief 清空接收缓冲区
*/
osal_kfree(g_serial_ctx.rx_buffer);
g_serial_ctx.rx_buffer = NULL;
}
- if (g_serial_ctx.tx_buffer) {
- osal_kfree(g_serial_ctx.tx_buffer);
- g_serial_ctx.tx_buffer = NULL;
- }
/* 销毁同步对象 */
osal_mutex_destroy(&g_serial_ctx.rx_mutex);
osal_sem_destroy(&g_serial_ctx.rx_semaphore);
- osal_mutex_destroy(&g_serial_ctx.tx_mutex);
/* 清理上下文 */
memset_s(&g_serial_ctx, sizeof(g_serial_ctx), 0, sizeof(g_serial_ctx));
stats->rx_buffer_size = g_serial_ctx.rx_buffer_size;
osal_mutex_unlock(&g_serial_ctx.rx_mutex);
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
- stats->tx_buffer_usage = g_serial_ctx.tx_count;
- stats->tx_buffer_size = g_serial_ctx.tx_buffer_size;
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
+ // TX buffer removed - no longer used (direct UART write)
+ stats->tx_buffer_usage = 0;
+ stats->tx_buffer_size = 0;
return PPP_ERR_OK;
}
return g_serial_ctx.rx_count;
}
-/**
- * @brief 获取发送缓冲区可用空间
- */
-static uint32_t ppp_serial_tx_buffer_available_space(void)
-{
- return g_serial_ctx.tx_buffer_size - g_serial_ctx.tx_count;
-}
-
-/**
- * @brief 获取发送缓冲区数据数量
- */
-static uint32_t ppp_serial_tx_buffer_data_count(void)
-{
- return g_serial_ctx.tx_count;
-}
-
-/**
- * @brief 清空发送缓冲区
- */
-static ppp_error_t ppp_serial_flush_tx_buffer_internal(void)
-{
- if (!g_serial_ctx.initialized) {
- return PPP_ERR_INVALID_PARAM;
- }
-
- PPP_DEBUG_INFO("Flushing TX buffer...");
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
-
- uint32_t old_count = g_serial_ctx.tx_count;
- g_serial_ctx.tx_head = 0;
- g_serial_ctx.tx_tail = 0;
- g_serial_ctx.tx_count = 0;
-
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
- PPP_DEBUG_INFO("TX buffer flushed (discarded %u bytes)", old_count);
- return PPP_ERR_OK;
-}
-
-
-/**
- * @brief 强制发送缓冲区中的所有数据
- */
-ppp_error_t ppp_serial_flush_tx(void)
-{
- if (!g_serial_ctx.initialized) {
- PPP_DEBUG_ERROR("PPP serial not initialized");
- return PPP_ERR_INVALID_PARAM;
- }
-
- PPP_DEBUG_INFO("=== TX Buffer Flush Start ===");
-
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
-
- uint32_t data_count = ppp_serial_tx_buffer_data_count();
- if (data_count == 0) {
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
- PPP_DEBUG_INFO("TX buffer is empty, nothing to flush");
- PPP_DEBUG_INFO("=== TX Buffer Flush End ===");
- return PPP_ERR_OK;
- }
-
- PPP_DEBUG_INFO("Flushing %u bytes from TX buffer", data_count);
-
- /* 创建临时缓冲区来存储要发送的数据 */
- uint8_t *temp_buffer = (uint8_t *)osal_kmalloc(data_count, OSAL_GFP_KERNEL);
- if (temp_buffer == NULL) {
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
- PPP_DEBUG_ERROR("Failed to allocate temporary buffer for flush");
- return PPP_ERR_MEMORY;
- }
-
- /* 从环形缓冲区复制数据到临时缓冲区 */
- for (uint32_t i = 0; i < data_count; i++) {
- temp_buffer[i] = g_serial_ctx.tx_buffer[g_serial_ctx.tx_tail];
- g_serial_ctx.tx_tail = (g_serial_ctx.tx_tail + 1) % g_serial_ctx.tx_buffer_size;
- g_serial_ctx.tx_count--;
- }
-
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
-
- /* 发送数据 */
- PPP_DEBUG_INFO("Calling uapi_uart_write(bus=%u, data=%p, len=%u, timeout=1000)...",
- g_serial_ctx.uart_bus, temp_buffer, data_count);
- // PPP_DEBUG_HEXDUMP(temp_buffer, data_count);
-
- int32_t write_result = uapi_uart_write(g_serial_ctx.uart_bus, temp_buffer, data_count, 1000);
- PPP_DEBUG_INFO("uapi_uart_write returned: %d (expected: %u)", write_result, data_count);
-
- ppp_error_t result = PPP_ERR_OK;
- if (write_result != (int32_t)data_count) {
- PPP_DEBUG_ERROR("UART write failed during flush: returned %d, expected %u", write_result, data_count);
- PPP_DEBUG_ERROR("Possible causes: UART not initialized, hardware error, or timeout");
- g_serial_ctx.tx_errors++;
- result = PPP_ERR_UART;
- } else {
- g_serial_ctx.tx_bytes += data_count;
- PPP_DEBUG_INFO("Flushed %u bytes successfully (total tx: %u bytes)",
- data_count, g_serial_ctx.tx_bytes);
- }
-
- /* 释放临时缓冲区 */
- osal_kfree(temp_buffer);
-
- PPP_DEBUG_INFO("Flush result: %s (error code: %d)",
- result == PPP_ERR_OK ? "SUCCESS" : "FAILED", result);
- PPP_DEBUG_INFO("=== TX Buffer Flush End ===");
-
- return result;
-}
-
-/**
- * @brief 清空发送缓冲区(丢弃数据)
- */
-void ppp_serial_flush_tx_discard(void)
-{
- if (!g_serial_ctx.initialized) {
- return;
- }
-
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
- uint32_t old_count = g_serial_ctx.tx_count;
- g_serial_ctx.tx_head = 0;
- g_serial_ctx.tx_tail = 0;
- g_serial_ctx.tx_count = 0;
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
-
- PPP_DEBUG_INFO("TX buffer discarded (%u bytes)", old_count);
-}
-
-/**
- * @brief 获取发送缓冲区使用情况
- */
-uint32_t ppp_serial_tx_available(void)
-{
- if (!g_serial_ctx.initialized) {
- return 0;
- }
-
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
- uint32_t count = ppp_serial_tx_buffer_data_count();
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
-
- return count;
-}
-
/**
* @brief 重置串口状态
+ * @note TX buffer 已移除 - 发送改为直接UART写入
*/
ppp_error_t ppp_serial_reset(void)
{
return PPP_ERR_INVALID_STATE;
}
- // 1. æ¸\85空æ\89\80æ\9c\89缓冲区
- PPP_DEBUG_INFO("Clearing all buffers...");
+ // 1. æ¸\85空æ\8e¥æ\94¶缓冲区
+ PPP_DEBUG_INFO("Clearing RX buffer...");
osal_mutex_lock(&g_serial_ctx.rx_mutex);
g_serial_ctx.rx_head = 0;
g_serial_ctx.rx_tail = 0;
g_serial_ctx.rx_count = 0;
osal_mutex_unlock(&g_serial_ctx.rx_mutex);
- osal_mutex_lock(&g_serial_ctx.tx_mutex);
- g_serial_ctx.tx_head = 0;
- g_serial_ctx.tx_tail = 0;
- g_serial_ctx.tx_count = 0;
- osal_mutex_unlock(&g_serial_ctx.tx_mutex);
-
// 2. 重置统计信息
g_serial_ctx.tx_bytes = 0;
g_serial_ctx.rx_bytes = 0;