// 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);
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);
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);
// 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;
#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;
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)
{
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;
}
/**
}
/* 检查是否已有数据 */
- 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;
}
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;
}
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;
}
/**
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;
-}
+}
/* 内部函数实现 */
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();
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) {
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