在FreeRTOS中,中断服务函数(ISR)内严禁使用阻塞型API,信号量与互斥锁的常规版本(如xSemaphoreTake)会因调度器挂起或任务切换导致死锁或崩溃。正确做法:1)信号量:使用带“FromISR”后缀的API,如xSemaphoreGiveFromISR,它仅做非阻塞操作,并通过pxHigherPriorityTaskWoken参数请求上下文切换(由中断退出时的portYIELD_FROM_ISR执行)。2)互斥锁:绝对禁止在ISR中使用,因为互斥锁涉及优先级继承和任务所有权,ISR无任务上下文,且无法阻塞。替代方案:用二值信号量或直接发送事件标志组(xEventGroupSetBitsFromISR)模拟互斥效果;若需保护共享资源,建议在ISR中仅做数据拷贝或置标志,实际互斥操作推迟到任务级。实操建议:确保ISR内代码极短,使用临界区(taskENTER_CRITICAL_FROM_ISR)保护简单变量,但注意临界区会关闭中断,影响实时性,需权衡。
mcuku 阿沐 · 2026-08-27