




根据您的描述,信号量值为-2且回调函数未执行,这表明串口中断服务程序未能正确触发信号量释放。以下是可能的原因和解决方法:
串口回调函数未正确注册:
rt_device_set_rx_indicate() 可能未成功绑定回调函数rt_err_t err = rt_device_set_rx_indicate(device, uart_rx_ind);中断服务程序未调用框架接口:
rt_hw_serial_isr()stm32f1xx_it.c 中的中断函数如下:void USART1_IRQHandler(void)
{
rt_interrupt_enter();
rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
rt_interrupt_leave();
}串口打开模式错误:
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);信号量初始化问题:
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);硬件自动方向切换冲突:
在 USART1_IRQHandler 中添加调试信息:
void USART1_IRQHandler(void)
{
rt_kprintf("[IRQ] Enter USART1 interruptn"); // 添加调试输出
rt_interrupt_enter();
rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
rt_interrupt_leave();
}如果看到输出但回调未执行,问题在RT-Thread框架层。
在设置回调后添加验证:
rt_err_t res = rt_device_set_rx_indicate(device, uart_rx_ind);
if (res != RT_EOK) {
rt_kprintf("Bind callback failed! Error:%dn", res);
}在接收线程中监控信号量:
static void serial_thread_entry(void *param)
{
while(1) {
rt_int32_t sem_val;
rt_sem_control(&rx_sem, RT_IPC_CMD_GET_STATE, &sem_val);
rt_kprintf("Semaphore value: %dn", sem_val); // 打印信号量值
if (rt_sem_take(&rx_sem, RT_WAITING_FOREVER) == RT_EOK) {
// ... 处理数据
}
}
}在回调函数中添加延迟:
static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
{
rt_thread_delay(1); // 延时1个tick(约1ms)
rt_sem_release(&rx_sem);
return RT_EOK;
}/* 查找串口设备 */
serial = rt_device_find("uart1");
/* 以中断模式打开 */
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
/* 绑定回调函数 */
rt_device_set_rx_indicate(serial, uart_rx_ind);
/* 创建信号量 */
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/* 创建接收线程 */
rt_thread_t thread = rt_thread_create("serial",
serial_thread_entry,
serial,
1024, 10);
rt_thread_startup(thread);static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
{
rt_sem_release(&rx_sem); // 关键步骤!
return RT_EOK;
}485自动切换电路:
串口引脚映射:
__HAL_AFIO_REMAP_USART1_ENABLE(); // 必须调用!终端电阻匹配:
通过以上步骤逐步排查,重点检查 中断服务程序是否调用rt_hw_serial_isr() 和 回调函数是否成功注册。信号量值为负表明有线程在等待但未被唤醒,确认中断到信号量释放的链路是否畅通。
举报
更多回帖