如何在NXP MIMXRT1040-EVK上实现ThreadX的ppp_byte_send函数
ThreadX PPPoS UART单字节发送无响应问题
问题背景
在NXP MIMXRT1040-EVK开发板上基于ThreadX实现PPPoS功能时,遇到UART发送PPP数据的障碍:ThreadX的nx_ppp_create函数要求传入ppp_byte_send回调函数,用于向Quectel EG800Q调制解调器通过串口发送单字节数据。
当前实现与现象
- 用NXP SDK的
LPUART_WriteBlocking实现单字节发送时,调制解调器无响应:
void ppp_byte_send(UCHAR byte) { LPUART_WriteBlocking(MODEM_REG_BASE, byte, 1); }
- 若在
ppp_byte_send中单次调用LPUART_WriteBlocking发送完整的首条PPP消息序列,调制解调器可以正常响应:
void ppp_byte_send(UCHAR byte) { uint8_t cmd[] = { 0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x21, 0xC3, 0x7D, 0x20, 0x7D, 0x28, 0x7D, 0x21, 0x7D, 0x24, 0x7D, 0x25, 0xDC, 0xF1, 0xB7, 0x7E }; LPUART_WriteBlocking(MODEM_REG_BASE, cmd, sizeof(cmd)); }
- 尝试循环逐个发送上述字节序列,同样无效。怀疑单字节发送速度过慢,想了解
ppp_byte_send是否有其他实现方式。
参考信息
- UART波特率:115200bps
- 该MCU+调制解调器组合已在Zephyr和FreeRTOS+LwIP环境中正常运行
解决思路与实现方案
1. 缓存批量发送优化
单字节调用LPUART_WriteBlocking会引入频繁的硬件等待和函数开销,导致字节间隔超出调制解调器接收阈值。可以在回调中缓存字节,积累到一定数量或检测到PPP帧结束符时批量发送:
#define PPP_SEND_BUF_SIZE 64 static uint8_t ppp_send_buf[PPP_SEND_BUF_SIZE]; static uint16_t ppp_send_buf_idx = 0; static TX_MUTEX ppp_send_mutex; // 初始化互斥锁,建议在系统启动阶段调用 void ppp_send_init(void) { tx_mutex_create(&ppp_send_mutex, "PPP Send Mutex", TX_NO_INHERIT); } void ppp_byte_send(UCHAR byte) { tx_mutex_get(&ppp_send_mutex, TX_WAIT_FOREVER); ppp_send_buf[ppp_send_buf_idx++] = byte; // 缓存满或遇到PPP帧结束符时立即发送 if (ppp_send_buf_idx >= PPP_SEND_BUF_SIZE || byte == 0x7E) { LPUART_WriteBlocking(MODEM_REG_BASE, ppp_send_buf, ppp_send_buf_idx); ppp_send_buf_idx = 0; } tx_mutex_put(&ppp_send_mutex); }
2. 直接操作UART寄存器减少开销
跳过SDK封装的阻塞函数,直接操作UART寄存器发送,降低单字节发送的延迟:
void ppp_byte_send(UCHAR byte) { // 等待发送寄存器为空 while (!(LPUART_GetStatusFlags(MODEM_REG_BASE) & LPUART_STATUS_REG_TDRE_MASK)); LPUART_WriteByte(MODEM_REG_BASE, byte); }
3. 对齐UART硬件配置
对比Zephyr/FreeRTOS+LwIP环境的UART配置,确保以下参数一致:
- 波特率、数据位、停止位、奇偶校验
- UART FIFO阈值(是否启用FIFO、触发级别)
- 硬件流控(RTS/CTS是否开启,之前环境若启用流控则当前也需配置)
4. 调整ThreadX PPP栈时序
查看nx_ppp.h中的宏定义,调整PPP发送相关的超时或延迟参数,确保字节发送间隔符合调制解调器要求。
内容的提问来源于stack exchange,提问作者MulattoKid
相关产品推荐
相关产品推荐

