在串口中断中发送事件但线程无法接收,通常由以下几个原因导致。请对照您的代码检查:
rt_event_t GPS_event_set = NULL; // 全局变量初始化为NULL
void main() {
GPS_event_set = rt_event_create("GPS_events", RT_IPC_FLAG_PRIO);
// 未检查返回值!
}问题:如果创建失败(如内存不足),GPS_event_set 仍为 NULL,中断中调用 rt_event_send(NULL, ...) 会导致崩溃或静默失败。
解决:添加错误检查:
GPS_event_set = rt_event_create("GPS_events", RT_IPC_FLAG_PRIO);
if (GPS_event_set == RT_NULL) {
rt_kprintf("Event create failed!n");
return -1;
}问题:线程优先级过低,导致无法及时抢占当前运行的线程。串口中断发送事件后,系统不会强制切换到低优先级线程。
解决:
tid = rt_thread_create("GPS_task", ..., 10 /* 优先级数值越小越高 */, ...); void USART_IRQHandler() {
rt_event_send(GPS_event_set, FLAG);
rt_schedule(); // 强制线程切换(需在中断上下文中谨慎使用)
}线程代码可能存在的错误:
0x01)。 RT_WAITING_FOREVER)。void gps_thread_entry(void *param) {
rt_uint32_t recv_flag;
while (1) {
// 错误:未指定超时时间或标志位错误
if (rt_event_recv(GPS_event_set, 0x01, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, &recv_flag) == RT_EOK) {
rt_kprintf("Event received!n");
}
}
}问题:串口中断配置错误,导致中断未触发或未调用发送事件的代码。
排查:
void USART_IRQHandler() {
rt_kprintf("ISR entered!n"); // 确认中断触发
rt_event_send(GPS_event_set, FLAG);
}问题:在中断中执行了非法操作(如使用阻塞函数),导致系统异常。
注意:
rt_event_send() 可在中断中使用,但 rt_kprintf() 等非异步函数需避免。问题:线程处理速度慢,而中断发送事件过于频繁,导致事件标志被覆盖。
解决:
RT_EVENT_FLAG_CLEAR 清除标志。NULL。// 线程中正确等待事件
rt_event_recv(GPS_event_set,
0x01, // 与发送的标志一致
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, // 永久阻塞等待
RT_NULL);通过以上步骤排查,通常可解决中断发送事件线程无响应的问题。
举报
更多回帖