本文主要描述如何在中断中使用队列、信号量等操作。
中断相关函数与普通函数的区别
下面以写队列为例,分析区别:
xQueueSend | xQueueSendFromISR | |
参数不同 | 有超时参数 | 没有超时参数 |
循环不同 | 有while(1) | 没有while(1) |
唤醒操作不同 | 直接产生一次调度 | 只记录需要调度 不去实际调度 |
队列满操作不同 | 根据传入的超时时间, 进行相应操作 | 即刻返回 |
相关解释:
- 中断处理没有超时参数,是因为中断的处理必须要足够的快,不能阻塞在中断中。
- 当存在 等待读取队列的任务优先级 比 当然任务的优先级高 时,才会存在产生一次调度或记录调度。
中断相关函数的使用方法
步骤如下:
- 定义一个变量,用于存储是否需要进行调度。
- 调用FromISR的函数时,传入这个变量
- 使用portYIELD_FROM_ISR触发调度
注意:portYIELD_FROM_ISR是触发调度,而不是即刻产生调度。它实际是设置了一个优先级最低的中断,当现在运行的中断执行结束后,立刻去执行这个优先级最低的中断。在这个中断中才是实际的产生任务调度。
具体代码实现框架如下(伪代码):
void XXX_IRQHandler(){/* 定义变量,用于存储调度状态,初始值为pdFALSE */BaseType_t pxHigherPriorityTaskWoken = pdFALSE;/* 中断中写队列,前两个参数与xQueueSend一致 */xQueueSendFromISR(队列句柄,写入值,&pxHigherPriorityTaskWoken);/* 触发调度 */portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
}