优化ppp 串口操作 2228/1 2228/head 2229/target/1 2230/target/1
author孙春阳 <snickersun@163.com>
Thu, 11 Sep 2025 09:25:50 +0000 (17:25 +0800)
committer孙春阳 <snickersun@163.com>
Thu, 11 Sep 2025 09:25:50 +0000 (17:25 +0800)
code/sdk/zhihui/ppp/include/ppp_config.h
code/sdk/zhihui/ppp/include/ppp_serial.h
code/sdk/zhihui/ppp/src/ppp_api.c
code/sdk/zhihui/ppp/src/ppp_lwip.c
code/sdk/zhihui/ppp/src/ppp_serial.c

index 0149970..62bb67b 100644 (file)
@@ -25,8 +25,8 @@ extern "C" {
 #endif
 
 /* 支持的波特率列表(自适应模式) */
-#define PPP_BAUDRATE_AUTO_LIST      {9600, 57600, 115200}
-#define PPP_BAUDRATE_AUTO_COUNT     3
+#define PPP_BAUDRATE_AUTO_LIST      {9600, 57600, 115200 , 2000000}
+#define PPP_BAUDRATE_AUTO_COUNT     4
 
 /* 支持的固定波特率列表 */
 #define PPP_BAUDRATE_FIXED_LIST     {4800, 9600, 57600, 115200, 230400, 460800, 750000, 921600, 1000000, 2000000, 4000000}
index 064e5f2..274a37a 100644 (file)
@@ -1,3 +1,7 @@
+/**
+ * @brief PPP串口模块头文件 - 恢复缓存机制
+ */
+
 #ifndef PPP_SERIAL_H
 #define PPP_SERIAL_H
 
@@ -8,24 +12,34 @@ extern "C" {
 #include <stdint.h>
 #include <stdbool.h>
 #include "ppp_types.h"
-#include "lwip/sio.h"
 
 /* 串口接收回调函数类型 */
 typedef void (*ppp_serial_rx_callback_t)(const uint8_t *data, uint16_t length, void *arg);
 
-/* 串口配置结构 */
+/* 串口工作模式 */
+typedef enum {
+    PPP_SERIAL_MODE_NONE = 0,    // 未初始化
+    PPP_SERIAL_MODE_AT,          // AT命令模式(使用普通UART)
+    PPP_SERIAL_MODE_PPP_DATA     // PPP数据模式(使用普通UART + 缓存)
+} ppp_serial_mode_t;
+
+/**
+ * @brief 串口配置结构
+ */
 typedef struct {
-    uint8_t uart_bus;                                   // 串口总线号
+    uint8_t uart_bus;                                   // UART总线号
     uint32_t baudrate;                                  // 波特率
-    uint8_t tx_pin;                                     // TX引脚
-    uint8_t rx_pin;                                     // RX引脚
+    uint8_t tx_pin;                                     // 发送引脚
+    uint8_t rx_pin;                                     // 接收引脚
     uint32_t rx_buffer_size;                            // 接收缓冲区大小
     uint32_t tx_buffer_size;                            // 发送缓冲区大小
     ppp_serial_rx_callback_t rx_callback;              // 接收回调函数
     void *rx_callback_arg;                              // 回调函数参数
 } ppp_serial_config_t;
 
-/* 串口统计信息结构 */
+/**
+ * @brief 串口统计信息
+ */
 typedef struct {
     uint32_t tx_bytes;                                  // 发送字节数
     uint32_t rx_bytes;                                  // 接收字节数
@@ -36,38 +50,56 @@ typedef struct {
 } ppp_serial_stats_t;
 
 /**
- * @brief 初始化PPP串口
+ * @brief 初始化PPP串口(AT命令模式,准备缓存机制)
  * @param config 串口配置
- * @return PPP错误码
+ * @return 错误码
  */
 ppp_error_t ppp_serial_init(const ppp_serial_config_t *config);
 
 /**
- * @brief å\8f\8d初始化PPP串口
+ * @brief å\8e»初始化PPP串口
  */
 void ppp_serial_deinit(void);
 
 /**
- * @brief 发送数据
+ * @brief 切换到PPP数据模式(启用缓存机制)
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_switch_to_ppp_mode(void);
+
+/**
+ * @brief 切换回AT命令模式(禁用缓存机制)
+ * @return 错误码
+ */
+ppp_error_t ppp_serial_switch_to_at_mode(void);
+
+/**
+ * @brief 获取当前串口模式
+ * @return 当前模式
+ */
+ppp_serial_mode_t ppp_serial_get_mode(void);
+
+/**
+ * @brief 发送数据(根据模式选择直接发送或缓存发送)
  * @param data 数据指针
  * @param length 数据长度
- * @return PPP错误码
+ * @return 错误码
  */
 ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length);
 
 /**
- * @brief 读取数据
+ * @brief 读取数据(根据模式选择直接读取或从缓存读取)
  * @param buffer 接收缓冲区
  * @param buffer_size 缓冲区大小
- * @param bytes_read 实际读取的字节数
- * @return PPP错误码
+ * @param bytes_read 实际读取字节数
+ * @return 错误码
  */
 ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *bytes_read);
 
 /**
  * @brief 等待数据接收
  * @param timeout_ms 超时时间(毫秒)
- * @return PPP错误码
+ * @return 错误码
  */
 ppp_error_t ppp_serial_wait_data(uint32_t timeout_ms);
 
@@ -83,11 +115,12 @@ uint32_t ppp_serial_available(void);
 void ppp_serial_flush_rx(void);
 
 /**
- * @brief 设置串口波特率
- * @param baudrate 波特率
- * @return PPP错误码
+ * @brief 设置接收回调函数
+ * @param callback 回调函数
+ * @param arg 回调函数参数
+ * @return 错误码
  */
-ppp_error_t ppp_serial_set_baudrate(uint32_t baudrate);
+ppp_error_t ppp_serial_set_rx_callback(ppp_serial_rx_callback_t callback, void *arg);
 
 /**
  * @brief 获取统计信息
@@ -95,12 +128,6 @@ ppp_error_t ppp_serial_set_baudrate(uint32_t baudrate);
  */
 void ppp_serial_get_stats(ppp_serial_stats_t *stats);
 
-/**
- * @brief 获取PPP模块SIO句柄
- * @return SIO句柄,如果未初始化则返回NULL
- */
-sio_fd_t ppp_get_sio_fd(void);
-
 #ifdef __cplusplus
 }
 #endif
index 8ccff1c..db3f220 100644 (file)
@@ -60,55 +60,68 @@ errcode_t ppp_start_dial(void)
     // 2. 等待4G模块启动
     osal_msleep(2000);
 
-    // 3. 初始化AT命令处理(AT命令模式)
-    ppp_error_t ret = ppp_at_handler_init(SIO_UART_BUS);
+    // 3. 初始化串口(AT命令模式)
+    ppp_serial_config_t serial_config = {
+        .uart_bus = SIO_UART_BUS,
+        .baudrate = g_ppp_config.baudrate,
+        .tx_pin = SIO_UART_TX_PIN,
+        .rx_pin = SIO_UART_RX_PIN,
+        .rx_buffer_size = PPP_RX_BUFFER_SIZE,
+        .tx_buffer_size = PPP_TX_BUFFER_SIZE,
+        .rx_callback = NULL,
+        .rx_callback_arg = NULL
+    };
+    
+    ppp_error_t ret = ppp_serial_init(&serial_config);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_PRINT("Failed to initialize serial for AT mode: %d\n", ret);
+        return ERRCODE_FAIL;
+    }
+
+    // 4. 初始化AT命令处理器(使用串口AT模式)
+    ret = ppp_at_handler_init(SIO_UART_BUS);
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to initialize AT handler: %d\n", ret);
+        ppp_serial_deinit();
         return ERRCODE_FAIL;
     }
 
-    // 4. 执行波特率握手(如果启用自动波特率)
+    // 5. 执行波特率握手(如果启用自动波特率)
     if (g_ppp_config.auto_baudrate) {
         ret = ppp_at_baudrate_handshake();
         if (ret != PPP_ERR_OK) {
             PPP_DEBUG_PRINT("Baudrate handshake failed: %d\n", ret);
+            ppp_at_handler_deinit();
+            ppp_serial_deinit();
             return ERRCODE_FAIL;
         }
     }
 
-    // 5. 执行完整的AT指令序列(对应chat文件)
+    // 6. 执行完整的AT指令序列(对应chat文件)
     ret = ppp_at_complete_dial_sequence(g_ppp_config.apn);
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("PPP dial sequence failed: %d\n", ret);
+        ppp_at_handler_deinit();
+        ppp_serial_deinit();
         g_ppp_state = PPP_STATE_ERROR;
         return ERRCODE_FAIL;
     }
 
     PPP_DEBUG_PRINT("AT dial sequence completed - switching to PPP data mode\n");
 
-    // 6. 关闭AT命令处理器(释放UART资源)
+    // 7. 关闭AT命令处理器(AT阶段结束)
     ppp_at_handler_deinit();
-    PPP_DEBUG_PRINT("AT handler deinitialized - UART released\n");
+    PPP_DEBUG_PRINT("AT handler deinitialized\n");
 
-    // 7. 初始化SIO串口(PPP数据模式)
-    ppp_serial_config_t serial_config = {
-        .uart_bus = SIO_UART_BUS,
-        .baudrate = g_ppp_config.baudrate,
-        .tx_pin = SIO_UART_TX_PIN,
-        .rx_pin = SIO_UART_RX_PIN,
-        .rx_buffer_size = PPP_RX_BUFFER_SIZE,
-        .tx_buffer_size = PPP_TX_BUFFER_SIZE,
-        .rx_callback = NULL,  // 将在PPP数据接收线程中设置
-        .rx_callback_arg = NULL
-    };
-    
-    ret = ppp_serial_init(&serial_config);
+    // 8. 切换串口到PPP数据模式
+    ret = ppp_serial_switch_to_ppp_mode();
     if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_PRINT("Failed to initialize serial for PPP data mode: %d\n", ret);
+        PPP_DEBUG_PRINT("Failed to switch serial to PPP data mode: %d\n", ret);
+        ppp_serial_deinit();
         return ERRCODE_FAIL;
     }
 
-    // 8. 初始化lwIP PPP协议栈
+    // 9. 初始化lwIP PPP协议栈
     ret = ppp_lwip_init();
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to initialize lwIP PPP: %d\n", ret);
@@ -116,7 +129,7 @@ errcode_t ppp_start_dial(void)
         return ERRCODE_FAIL;
     }
 
-    // 9. 启动PPP连接
+    // 10. 启动PPP连接
     ret = ppp_lwip_connect();
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to start PPP connection: %d\n", ret);
@@ -125,7 +138,7 @@ errcode_t ppp_start_dial(void)
         return ERRCODE_FAIL;
     }
 
-    // 10. 启动PPP数据接收处理
+    // 11. 启动PPP数据接收处理
     ret = ppp_start_data_receive_thread();
     if (ret != PPP_ERR_OK) {
         PPP_DEBUG_PRINT("Failed to start PPP data receive thread: %d\n", ret);
@@ -162,29 +175,35 @@ errcode_t ppp_stop_dial(void)
     // 3. 清理lwIP PPP资源
     ppp_lwip_deinit();
 
-    // 4. 关闭SIO串口(释放串口资源)
-    ppp_serial_deinit();
-    PPP_DEBUG_PRINT("SIO serial deinitialized - switching back to AT mode\n");
-
-    // 5. 重新初始化AT命令处理器(切换回AT命令模式)
-    ppp_error_t ret = ppp_at_handler_init(SIO_UART_BUS);
+    // 4. 切换串口回AT命令模式(用于发送挂断命令)
+    ppp_error_t ret = ppp_serial_switch_to_at_mode();
     if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_ERROR("Failed to reinitialize AT handler: %d", ret);
-        g_ppp_state = PPP_STATE_ERROR;
-        return ERRCODE_FAIL;
-    }
-
-    // 6. 发送PPP挂断命令(切换回命令模式)
-    ret = ppp_at_hangup_ppp();
-    if (ret != PPP_ERR_OK) {
-        PPP_DEBUG_WARN("Failed to send hangup command: %d", ret);
-        // 继续执行,不返回错误
+        PPP_DEBUG_ERROR("Failed to switch serial to AT mode: %d", ret);
+        // 继续执行,尝试清理其他资源
+    } else {
+        PPP_DEBUG_PRINT("Serial switched back to AT mode\n");
+
+        // 5. 重新初始化AT命令处理器(用于发送挂断命令)
+        ret = ppp_at_handler_init(SIO_UART_BUS);
+        if (ret == PPP_ERR_OK) {
+            // 6. 发送PPP挂断命令(切换回命令模式)
+            ret = ppp_at_hangup_ppp();
+            if (ret != PPP_ERR_OK) {
+                PPP_DEBUG_WARN("Failed to send hangup command: %d", ret);
+                // 继续执行,不返回错误
+            }
+
+            // 7. 关闭AT命令处理器
+            ppp_at_handler_deinit();
+        } else {
+            PPP_DEBUG_WARN("Failed to reinitialize AT handler for hangup: %d", ret);
+        }
     }
 
-    // 7. 关闭AT命令处理器
-    ppp_at_handler_deinit();
+    // 8. 关闭串口
+    ppp_serial_deinit();
 
-    // 8. 关闭4G电源
+    // 9. 关闭4G电源
     cat1_api_enable_cat1(false);
 
     g_ppp_state = PPP_STATE_INITIALIZED;
index 845c056..521d9e4 100644 (file)
@@ -152,16 +152,31 @@ ppp_error_t ppp_lwip_connect(void)
         return PPP_ERR_OK;
     }
 
-    PPP_DEBUG_INFO("Connecting PPP");
+    PPP_DEBUG_INFO("Connecting PPP using custom serial interface");
+
+    /* 创建PPPoS连接,使用自定义输出回调 */
+    g_lwip_ctx.ppp_pcb = pppos_create(&g_lwip_ctx.netif,
+                                      ppp_lwip_output_callback,  // 自定义输出回调
+                                      ppp_lwip_status_callback,
+                                      &g_lwip_ctx);
+    if (g_lwip_ctx.ppp_pcb == NULL) {
+        PPP_DEBUG_ERROR("Failed to create PPPoS connection");
+        return PPP_ERR_MEMORY;
+    }
+
+    /* 设置认证信息 */
+    ppp_set_auth(g_lwip_ctx.ppp_pcb, PPPAUTHTYPE_NONE, "", "");
 
     /* 启动PPP连接 */
     err_t err = ppp_connect(g_lwip_ctx.ppp_pcb, 0);
     if (err != ERR_OK) {
         PPP_DEBUG_ERROR("Failed to start PPP connection: %d", err);
+        ppp_free(g_lwip_ctx.ppp_pcb);
+        g_lwip_ctx.ppp_pcb = NULL;
         return PPP_ERR_DIAL_FAILED;
     }
 
-    PPP_DEBUG_INFO("PPP connection started");
+    PPP_DEBUG_INFO("PPP connection initiated with custom serial interface");
     return PPP_ERR_OK;
 #endif
 }
@@ -369,7 +384,7 @@ static void ppp_lwip_link_status_callback(ppp_pcb *pcb, int err_code, void *ctx)
 }
 
 /**
- * @brief PPP输出回调函数 - 使用SIO接口,像SLIP一样
+ * @brief PPP输出回调函数 - 使用自定义串口接口,不依赖SIO
  */
 static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
 {
@@ -379,19 +394,13 @@ static u32_t ppp_lwip_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void
     PPP_DEBUG_DEBUG("PPP output %u bytes", len);
     PPP_DEBUG_HEXDUMP(data, len);
 
-    /* 通过SIO接口发送数据,像SLIP一样 */
-    sio_fd_t sio_fd = ppp_get_sio_fd();
-    if (sio_fd == NULL) {
-        PPP_DEBUG_ERROR("SIO interface not initialized");
-        return 0;
-    }
-
-    u32_t sent = sio_write(sio_fd, data, len);
-    if (sent != len) {
-        PPP_DEBUG_ERROR("Failed to send PPP data via SIO: %u/%u", sent, len);
+    /* 直接使用我们自己的串口写函数,不依赖SIO */
+    ppp_error_t ret = ppp_serial_write(data, len);
+    if (ret != PPP_ERR_OK) {
+        PPP_DEBUG_ERROR("Failed to send PPP data via custom serial: %d", ret);
         return 0;
     }
 
-    return sent;
+    return len;
 }
 #endif /* LWIP_PPP_SUPPORT */ 
\ No newline at end of file
index d3b112d..fe33775 100644 (file)
@@ -2,7 +2,7 @@
 #include "ppp_config.h"
 #include "ppp_types.h"
 #include "ppp_debug.h"
-#include "uart.h"
+#include "driver/uart.h"  // 使用完整路径
 #include "schedule/osal_task.h"
 #include "semaphore/osal_semaphore.h"
 #include "lock/osal_mutex.h"
 #include "securec.h"
 #include <string.h>
 
-// 添加SIO相关头文件,让PPP像SLIP一样使用SIO接口
-#include "lwip/sio.h"
-#include "lwip/opt.h"
-
-/* 串口上下文结构 */
+/* 串口上下文结构 - 恢复缓存机制 */
 typedef struct {
     bool initialized;
+    ppp_serial_mode_t current_mode;
     uint8_t uart_bus;
+    
+    /* UART配置参数 */
     uart_pin_config_t pin_config;
     uart_attr_t uart_attr;
     uart_buffer_config_t buffer_config;
     
-    /* SIO接口句柄 */
-    sio_fd_t sio_fd;
-    
-    /* 接收缓冲区 */
+    /* 接收缓冲区(用于PPP数据模式) */
     uint8_t *rx_buffer;
     uint32_t rx_buffer_size;
     uint32_t rx_head;
     uint32_t rx_tail;
     uint32_t rx_count;
     
-    /* 发送缓冲区 */
+    /* 发送缓冲区(用于PPP数据模式) */
     uint8_t *tx_buffer;
     uint32_t tx_buffer_size;
     
     /* 同步对象 */
-    osal_mutex *rx_mutex;
-    osal_semaphore *rx_semaphore;
+    osal_mutex rx_mutex;        // 改为结构体而不是指针
+    osal_semaphore rx_semaphore; // 改为结构体而不是指针
     
     /* 回调函数 */
     ppp_serial_rx_callback_t rx_callback;
@@ -60,7 +56,7 @@ static uint32_t ppp_serial_buffer_available_space(void);
 static uint32_t ppp_serial_buffer_data_count(void);
 
 /**
- * @brief 初始化PPP串口
+ * @brief 初始化PPP串口 - AT命令模式,准备缓存机制
  */
 ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
 {
@@ -68,95 +64,272 @@ ppp_error_t ppp_serial_init(const ppp_serial_config_t *config)
         return PPP_ERR_INVALID_PARAM;
     }
 
-    PPP_DEBUG_INFO("Initializing PPP serial using SIO interface like SLIP");
+    PPP_DEBUG_INFO("Initializing PPP serial in AT command mode with buffer support");
 
-    /* 打开SIO接口,使用与SLIP相同的方式但不同的设备号 */
-    g_serial_ctx.sio_fd = sio_open(PPP_IFNUM);
-    if (g_serial_ctx.sio_fd == NULL) {
-        PPP_DEBUG_ERROR("Failed to open SIO interface for PPP, device=%d", PPP_IFNUM);
+    /* 配置UART参数 */
+    g_serial_ctx.uart_bus = config->uart_bus;
+    g_serial_ctx.pin_config.tx_pin = config->tx_pin;
+    g_serial_ctx.pin_config.rx_pin = config->rx_pin;
+    g_serial_ctx.uart_attr.baud_rate = config->baudrate;
+    g_serial_ctx.uart_attr.data_bits = UART_DATA_BIT_8;
+    g_serial_ctx.uart_attr.stop_bits = UART_STOP_BIT_1;
+    g_serial_ctx.uart_attr.parity = UART_PARITY_NONE;
+
+    /* 配置UART缓冲区 */
+    static uint8_t uart_rx_buffer[256];
+    g_serial_ctx.buffer_config.rx_buffer = uart_rx_buffer;
+    g_serial_ctx.buffer_config.rx_buffer_size = sizeof(uart_rx_buffer);
+
+    /* 初始化UART(AT命令模式) */
+    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);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to initialize UART for AT mode: %d", ret);
         return PPP_ERR_UART;
     }
 
-    /* 配置基本参数 */
-    g_serial_ctx.uart_bus = config->uart_bus;
+    /* 分配PPP数据模式的接收缓冲区 */
     g_serial_ctx.rx_buffer_size = config->rx_buffer_size;
+    g_serial_ctx.rx_buffer = (uint8_t *)osal_kmalloc(g_serial_ctx.rx_buffer_size, OSAL_GFP_KERNEL);
+    if (g_serial_ctx.rx_buffer == NULL) {
+        PPP_DEBUG_ERROR("Failed to allocate RX buffer");
+        uapi_uart_deinit(g_serial_ctx.uart_bus);
+        return PPP_ERR_MEMORY;
+    }
+
+    /* 分配PPP数据模式的发送缓冲区 */
     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");
+        osal_kfree(g_serial_ctx.rx_buffer);
+        uapi_uart_deinit(g_serial_ctx.uart_bus);
+        return PPP_ERR_MEMORY;
+    }
+
+    /* 创建同步对象 */
+    if (osal_mutex_init(&g_serial_ctx.rx_mutex) != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create RX mutex");
+        osal_kfree(g_serial_ctx.tx_buffer);
+        osal_kfree(g_serial_ctx.rx_buffer);
+        uapi_uart_deinit(g_serial_ctx.uart_bus);
+        return PPP_ERR_MEMORY;
+    }
+
+    if (osal_sem_init(&g_serial_ctx.rx_semaphore, 0) != OSAL_SUCCESS) {
+        PPP_DEBUG_ERROR("Failed to create RX semaphore");
+        osal_mutex_destroy(&g_serial_ctx.rx_mutex);
+        osal_kfree(g_serial_ctx.tx_buffer);
+        osal_kfree(g_serial_ctx.rx_buffer);
+        uapi_uart_deinit(g_serial_ctx.uart_bus);
+        return PPP_ERR_MEMORY;
+    }
+
+    /* 初始化缓冲区状态 */
+    g_serial_ctx.rx_head = 0;
+    g_serial_ctx.rx_tail = 0;
+    g_serial_ctx.rx_count = 0;
     g_serial_ctx.rx_callback = config->rx_callback;
     g_serial_ctx.rx_callback_arg = config->rx_callback_arg;
 
-    }
+    g_serial_ctx.initialized = true;
+    g_serial_ctx.current_mode = PPP_SERIAL_MODE_AT;
 
-    memset_s(&g_serial_ctx, sizeof(g_serial_ctx), 0, sizeof(g_serial_ctx));
-    PPP_DEBUG_INFO("PPP serial deinitialized");
+    /* 重置统计信息 */
+    g_serial_ctx.tx_bytes = 0;
+    g_serial_ctx.rx_bytes = 0;
+    g_serial_ctx.tx_errors = 0;
+    g_serial_ctx.rx_errors = 0;
+
+    PPP_DEBUG_INFO("PPP serial initialized in AT command mode with buffer support");
+    return PPP_ERR_OK;
 }
 
 /**
- * @brief å\8f\91é\80\81æ\95°æ\8d®
+ * @brief å\88\87æ\8d¢å\88°PPPæ\95°æ\8d®æ¨¡å¼\8f - å\90¯ç\94¨ç¼\93å­\98æ\9cºå\88¶å\92\8cUARTæ\8e¥æ\94¶å\9b\9eè°\83
  */
-ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length)
+ppp_error_t ppp_serial_switch_to_ppp_mode(void)
 {
-    if (!g_serial_ctx.initialized || !data || length == 0) {
+    if (!g_serial_ctx.initialized) {
         return PPP_ERR_INVALID_PARAM;
     }
 
-    if (g_serial_ctx.sio_fd == NULL) {
-        PPP_DEBUG_ERROR("SIO interface not initialized");
-        return PPP_ERR_UART;
+    if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_PPP_DATA) {
+        PPP_DEBUG_WARN("Already in PPP data mode");
+        return PPP_ERR_OK;
     }
 
-    PPP_DEBUG_DEBUG("Sending %u bytes via SIO", length);
-    PPP_DEBUG_HEXDUMP(data, length);
+    PPP_DEBUG_INFO("Switching serial from AT mode to PPP data mode (enable buffering)");
 
-    /* 通过SIO接口发送数据,像SLIP一样 */
-    u32_t bytes_written = sio_write(g_serial_ctx.sio_fd, (u8_t*)data, length);
-    
-    if (bytes_written != length) {
-        PPP_DEBUG_ERROR("SIO write failed: %u/%u bytes", bytes_written, length);
-        g_serial_ctx.tx_errors++;
+    /* 清空接收缓冲区 */
+    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);
+
+    /* 注册UART接收回调,启用缓存机制 */
+    errcode_t ret = uapi_uart_register_rx_callback(g_serial_ctx.uart_bus, 
+                                                   UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
+                                                   g_serial_ctx.rx_buffer_size,
+                                                   ppp_serial_rx_callback);
+    if (ret != ERRCODE_SUCC) {
+        PPP_DEBUG_ERROR("Failed to register UART RX callback: %d", ret);
         return PPP_ERR_UART;
     }
-
-    g_serial_ctx.tx_bytes += bytes_written;
-    PPP_DEBUG_DEBUG("Sent %u bytes successfully via SIO", bytes_written);
-
+    
+    g_serial_ctx.current_mode = PPP_SERIAL_MODE_PPP_DATA;
+    PPP_DEBUG_INFO("Successfully switched to PPP data mode with buffering enabled");
     return PPP_ERR_OK;
 }
 
 /**
- * @brief 读取数据
+ * @brief 切换回AT命令模式 - 禁用缓存机制和UART接收回调
  */
-ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *bytes_read)
+ppp_error_t ppp_serial_switch_to_at_mode(void)
 {
-    if (!g_serial_ctx.initialized || !buffer || !bytes_read || buffer_size == 0) {
+    if (!g_serial_ctx.initialized) {
         return PPP_ERR_INVALID_PARAM;
     }
 
-    *bytes_read = 0;
+    if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_AT) {
+        PPP_DEBUG_WARN("Already in AT command mode");
+        return PPP_ERR_OK;
+    }
+
+    PPP_DEBUG_INFO("Switching serial from PPP data mode to AT mode (disable buffering)");
+
+    /* 取消注册UART接收回调,禁用缓存机制 */
+    uapi_uart_unregister_rx_callback(g_serial_ctx.uart_bus);
+
+    /* 清空接收缓冲区 */
+    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.rx_mutex);
+    g_serial_ctx.current_mode = PPP_SERIAL_MODE_AT;
+    PPP_DEBUG_INFO("Successfully switched back to AT command mode");
+    return PPP_ERR_OK;
+}
 
-    uint32_t available = ppp_serial_buffer_data_count();
-    if (available == 0) {
-        osal_mutex_unlock(g_serial_ctx.rx_mutex);
-        return PPP_ERR_OK; // 没有数据可读
+/**
+ * @brief 发送数据 - 根据模式选择直接发送或缓存发送
+ */
+ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length)
+{
+    if (!g_serial_ctx.initialized || !data || length == 0) {
+        return PPP_ERR_INVALID_PARAM;
     }
 
-    uint32_t to_read = (available < buffer_size) ? available : buffer_size;
-    
-    for (uint32_t i = 0; i < to_read; i++) {
-        buffer[i] = g_serial_ctx.rx_buffer[g_serial_ctx.rx_tail];
-        g_serial_ctx.rx_tail = (g_serial_ctx.rx_tail + 1) % g_serial_ctx.rx_buffer_size;
-        g_serial_ctx.rx_count--;
+    ppp_error_t result = PPP_ERR_OK;
+
+    switch (g_serial_ctx.current_mode) {
+        case PPP_SERIAL_MODE_AT:
+            /* AT命令模式:直接使用UART发送 */
+            PPP_DEBUG_DEBUG("Sending %u bytes via UART (AT mode)", length);
+            PPP_DEBUG_HEXDUMP(data, length);
+            
+            if (uapi_uart_write(g_serial_ctx.uart_bus, data, length, 1000) != (int32_t)length) {
+                PPP_DEBUG_ERROR("UART write failed in AT mode");
+                g_serial_ctx.tx_errors++;
+                result = PPP_ERR_UART;
+            } else {
+                g_serial_ctx.tx_bytes += length;
+                PPP_DEBUG_DEBUG("Sent %u bytes successfully via UART", length);
+            }
+            break;
+
+        case PPP_SERIAL_MODE_PPP_DATA:
+            /* PPP数据模式:直接使用UART发送(PPP数据通常需要立即发送) */
+            PPP_DEBUG_DEBUG("Sending %u bytes via UART (PPP data mode)", length);
+            PPP_DEBUG_HEXDUMP(data, length);
+            
+            if (uapi_uart_write(g_serial_ctx.uart_bus, data, length, 1000) != (int32_t)length) {
+                PPP_DEBUG_ERROR("UART write failed in PPP data mode");
+                g_serial_ctx.tx_errors++;
+                result = PPP_ERR_UART;
+            } else {
+                g_serial_ctx.tx_bytes += length;
+                PPP_DEBUG_DEBUG("Sent %u bytes successfully via UART", length);
+            }
+            break;
+
+        default:
+            PPP_DEBUG_ERROR("Invalid serial mode: %d", g_serial_ctx.current_mode);
+            result = PPP_ERR_INVALID_PARAM;
+            break;
     }
 
-    *bytes_read = to_read;
+    return result;
+}
 
-    osal_mutex_unlock(g_serial_ctx.rx_mutex);
+/**
+ * @brief 读取数据 - 根据模式选择直接读取或从缓存读取
+ */
+ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *bytes_read)
+{
+    if (!g_serial_ctx.initialized || !buffer || !bytes_read || buffer_size == 0) {
+        return PPP_ERR_INVALID_PARAM;
+    }
 
-    PPP_DEBUG_DEBUG("Read %u bytes", to_read);
-    PPP_DEBUG_HEXDUMP(buffer, to_read);
+    *bytes_read = 0;
+    ppp_error_t result = PPP_ERR_OK;
+
+    switch (g_serial_ctx.current_mode) {
+        case PPP_SERIAL_MODE_AT:
+            /* AT命令模式:直接从UART读取 */
+            {
+                int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 100);
+                if (read_result > 0) {
+                    *bytes_read = (uint32_t)read_result;
+                    g_serial_ctx.rx_bytes += *bytes_read;
+                    PPP_DEBUG_DEBUG("Read %u bytes via UART (AT mode)", *bytes_read);
+                    PPP_DEBUG_HEXDUMP(buffer, *bytes_read);
+                } else if (read_result < 0) {
+                    PPP_DEBUG_ERROR("UART read error in AT mode: %d", read_result);
+                    g_serial_ctx.rx_errors++;
+                    result = PPP_ERR_UART;
+                }
+            }
+            break;
+
+        case PPP_SERIAL_MODE_PPP_DATA:
+            /* PPP数据模式:从缓存读取 */
+            osal_mutex_lock(&g_serial_ctx.rx_mutex);
+
+            uint32_t available = ppp_serial_buffer_data_count();
+            if (available == 0) {
+                osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+                return PPP_ERR_OK; // 没有数据可读
+            }
+
+            uint32_t to_read = (available < buffer_size) ? available : buffer_size;
+            
+            for (uint32_t i = 0; i < to_read; i++) {
+                buffer[i] = g_serial_ctx.rx_buffer[g_serial_ctx.rx_tail];
+                g_serial_ctx.rx_tail = (g_serial_ctx.rx_tail + 1) % g_serial_ctx.rx_buffer_size;
+                g_serial_ctx.rx_count--;
+            }
+
+            *bytes_read = to_read;
+            osal_mutex_unlock(&g_serial_ctx.rx_mutex);
+
+            PPP_DEBUG_DEBUG("Read %u bytes from buffer (PPP data mode)", to_read);
+            PPP_DEBUG_HEXDUMP(buffer, to_read);
+            break;
+
+        default:
+            PPP_DEBUG_ERROR("Invalid serial mode: %d", g_serial_ctx.current_mode);
+            result = PPP_ERR_INVALID_PARAM;
+            break;
+    }
 
-    return PPP_ERR_OK;
+    return result;
 }
 
 /**
@@ -169,16 +342,16 @@ ppp_error_t ppp_serial_wait_data(uint32_t timeout_ms)
     }
 
     /* 检查是否已有数据 */
-    osal_mutex_lock(g_serial_ctx.rx_mutex);
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
     bool has_data = (g_serial_ctx.rx_count > 0);
-    osal_mutex_unlock(g_serial_ctx.rx_mutex);
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
 
     if (has_data) {
         return PPP_ERR_OK;
     }
 
     /* 等待数据到达 */
-    if (osal_sem_wait(g_serial_ctx.rx_semaphore, timeout_ms) != OSAL_SUCCESS) {
+    if (osal_sem_wait(&g_serial_ctx.rx_semaphore, timeout_ms) != OSAL_SUCCESS) {
         return PPP_ERR_TIMEOUT;
     }
 
@@ -194,9 +367,9 @@ uint32_t ppp_serial_available(void)
         return 0;
     }
 
-    osal_mutex_lock(g_serial_ctx.rx_mutex);
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
     uint32_t count = ppp_serial_buffer_data_count();
-    osal_mutex_unlock(g_serial_ctx.rx_mutex);
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
 
     return count;
 }
@@ -210,36 +383,75 @@ void ppp_serial_flush_rx(void)
         return;
     }
 
-    osal_mutex_lock(g_serial_ctx.rx_mutex);
+    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_unlock(&g_serial_ctx.rx_mutex);
 
     PPP_DEBUG_DEBUG("RX buffer flushed");
 }
 
 /**
- * @brief 设置串口波特率
+ * @brief 设置接收回调函数
  */
-ppp_error_t ppp_serial_set_baudrate(uint32_t baudrate)
+ppp_error_t ppp_serial_set_rx_callback(ppp_serial_rx_callback_t callback, void *arg)
 {
     if (!g_serial_ctx.initialized) {
         return PPP_ERR_INVALID_PARAM;
     }
 
-    PPP_DEBUG_INFO("Setting baudrate to %u", baudrate);
+    g_serial_ctx.rx_callback = callback;
+    g_serial_ctx.rx_callback_arg = arg;
 
-    g_serial_ctx.uart_attr.baud_rate = baudrate;
-    
-    errcode_t ret = uapi_uart_set_attr(g_serial_ctx.uart_bus, &g_serial_ctx.uart_attr);
-    if (ret != ERRCODE_SUCC) {
-        PPP_DEBUG_ERROR("Failed to set baudrate: %d", ret);
-        return PPP_ERR_UART;
+    return PPP_ERR_OK;
+}
+
+/**
+ * @brief 去初始化PPP串口
+ */
+void ppp_serial_deinit(void)
+{
+    if (!g_serial_ctx.initialized) {
+        return;
     }
 
-    PPP_DEBUG_INFO("Baudrate set to %u successfully", baudrate);
-    return PPP_ERR_OK;
+    PPP_DEBUG_INFO("Deinitializing PPP serial, current mode: %d", g_serial_ctx.current_mode);
+
+    /* 取消注册UART接收回调 */
+    if (g_serial_ctx.current_mode == PPP_SERIAL_MODE_PPP_DATA) {
+        uapi_uart_unregister_rx_callback(g_serial_ctx.uart_bus);
+    }
+
+    /* 关闭UART */
+    uapi_uart_deinit(g_serial_ctx.uart_bus);
+
+    /* 释放缓冲区 */
+    if (g_serial_ctx.rx_buffer) {
+        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);
+
+    /* 清理上下文 */
+    memset_s(&g_serial_ctx, sizeof(g_serial_ctx), 0, sizeof(g_serial_ctx));
+    PPP_DEBUG_INFO("PPP serial deinitialized");
+}
+
+/**
+ * @brief 获取当前串口模式
+ */
+ppp_serial_mode_t ppp_serial_get_mode(void)
+{
+    return g_serial_ctx.current_mode;
 }
 
 /**
@@ -257,7 +469,7 @@ void ppp_serial_get_stats(ppp_serial_stats_t *stats)
     stats->rx_errors = g_serial_ctx.rx_errors;
     stats->rx_buffer_usage = g_serial_ctx.rx_count;
     stats->rx_buffer_size = g_serial_ctx.rx_buffer_size;
-}
+} 
 
 /* 内部函数实现 */
 
@@ -274,7 +486,7 @@ static void ppp_serial_rx_callback(const void *buffer, uint16_t length, bool rem
 
     const uint8_t *data = (const uint8_t *)buffer;
 
-    osal_mutex_lock(g_serial_ctx.rx_mutex);
+    osal_mutex_lock(&g_serial_ctx.rx_mutex);
 
     /* 检查缓冲区空间 */
     uint32_t available_space = ppp_serial_buffer_available_space();
@@ -293,10 +505,10 @@ static void ppp_serial_rx_callback(const void *buffer, uint16_t length, bool rem
 
     g_serial_ctx.rx_bytes += length;
 
-    osal_mutex_unlock(g_serial_ctx.rx_mutex);
+    osal_mutex_unlock(&g_serial_ctx.rx_mutex);
 
     /* 通知有数据到达 */
-    osal_sem_signal(g_serial_ctx.rx_semaphore);
+    osal_sem_signal(&g_serial_ctx.rx_semaphore);
 
     /* 调用用户回调函数 */
     if (g_serial_ctx.rx_callback) {
@@ -320,13 +532,4 @@ static uint32_t ppp_serial_buffer_available_space(void)
 static uint32_t ppp_serial_buffer_data_count(void)
 {
     return g_serial_ctx.rx_count;
-}
-
-/**
- * @brief 获取PPP模块SIO句柄
- * @return SIO句柄,如果未初始化则返回NULL
- */
-sio_fd_t ppp_get_sio_fd(void)
-{
-    return g_serial_ctx.sio_fd;
 } 
\ No newline at end of file