举报
根据您提供的代码和描述,问题可能由以下几个原因引起。以下是详细分析和解决方案:
在RT-Thread中,信号量需要正确初始化才能工作。请确认信号量 modbus_uart_sem 是否在创建接收线程之前正确初始化:
rt_sem_init(&modbus_uart_sem, "uart_sem", 0, RT_IPC_FLAG_FIFO);
// 或动态创建:rt_sem_create("uart_sem", 0, RT_IPC_FLAG_FIFO);0,确保接收线程在启动后立刻等待信号量。1,线程可能在无数据时提前运行,导致后续信号量无法正确同步。回调函数 modbus_uart_input 需在串口设备中正确注册才能触发:
// 在初始化代码中设置回调函数
rt_device_set_rx_indicate(comm_uart_dev, modbus_uart_input);rt_device_open() 时启用了中断接收模式?rt_device_open(comm_uart_dev, RT_DEVICE_FLAG_INT_RX);"uart3")是否正确绑定到 comm_uart_dev。STM32中断优先级需高于线程优先级,否则中断无法抢占线程:
// 在HAL库中设置中断优先级
HAL_NVIC_SetPriority(USARTx_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USARTx_IRQn);rt_thread_init(..., RT_THREAD_PRIORITY_MAX / 2, ...);接收线程 thread_comm_uart_receive_entry 的堆栈过小可能导致运行异常:
#define THREAD_STACK_SIZE 1024
rt_thread_t thread = rt_thread_create("uart_rcv", thread_comm_uart_receive_entry, RT_NULL, THREAD_STACK_SIZE, ...);rt_thread_mdelay(10) 替代原地循环等待数据,避免堆栈溢出。在STM32中,需手动清除串口中断标志(如 USART_SR_RXNE)。RT-Thread设备驱动通常已处理,但需确认:
drv_usart.c)是否清除了中断标志。 static rt_err_t modbus_uart_input(rt_device_t dev, rt_size_t size) {
rt_kprintf("IRQ!\n"); // 中断中打印需简短
rt_sem_release(&modbus_uart_sem);
return RT_EOK;
}接收线程需正确处理 rt_device_read() 返回值:
void thread_comm_uart_receive_entry(void* parameter) {
char ch;
while (1) {
rt_sem_take(&modbus_uart_sem, RT_WAITING_FOREVER); // 阻塞等待
if (rt_device_read(comm_uart_dev, -1, &ch, 1) != 1) {
continue; // 读取失败处理
}
// 处理数据 ch
}
}size 参数应为 1(读一个字节),而非 sizeof(ch)。确认以下API在V4.0.3中未被弃用:
rt_sem_release():中断中释放信号量是安全的。rt_device_set_rx_indicate():串口驱动的标准注册方式。0。// 示例初始化代码
comm_uart_dev = rt_device_find("uart3");
rt_device_set_rx_indicate(comm_uart_dev, modbus_uart_input);
rt_device_open(comm_uart_dev, RT_DEVICE_FLAG_INT_RX);通过逐步排除以上问题,可定位根源。重点优先级:信号量初始化 > 中断配置 > 串口驱动。
举报
更多回帖