FreeRTOS中断管理
文章目录
前言
在RTOS
中,需要应对各类事件。这些事件很多时候是通过硬件中断产生。
假设当前系统正在运行Task1
任务,用户按下了按键,触发了按键中断。触发中断后:
硬件负责:
CPU跳到固定地址去执行代码,这个固定地址通常被称为中断向量。
软件负责:
- 保存现场:
Task1
被打断,需要先保存Task1
的运行环境,比如各类寄存器的值; - 调用处理函数(这个函数就被称为ISR,interrupt service
routine) - 恢复现场:继续运行
Task1
,或者运行其他优先级更高的任务。
本章主要涉及
- FreeRTOS的哪些API函数能在ISR中使用
- 怎么把中断的处理分为两部分:ISR、任务
提示:以下是本篇文章正文内容,下面案例可供参考
一、ISR的API函数
FreeRTOS中很多API函数都有两套:一套在任务中使用,另一套在ISR中使用。因为很多API函数会导致任务计入阻塞状态,但是ISR不能进入阻塞状态,所以需要另一套函数。
类型 | 在任务中 | 在ISR中 |
---|---|---|
队列(queue) | xQueueSendToBack | xQueueSendToBackFromISR |
xQueueSendToFront | xQueueSendToFrontFromISR | |
xQueueReceive | xQueueReceiveFromISR | |
xQueueOverwrite | xQueueOverwriteFromISR | |
xQueuePeek | xQueuePeekFromISR | |
信号量(semaphore) | xSemaphoreGive | xSemaphoreGiveFromISR |
xSemaphoreTake | xSemaphoreTakeFromISR | |
事件组(event group) | xEventGroupSetBits | xEventGroupSetBitsFromISR |
以写队列为例,来看一下这两个API有什么区别
xQueueSendToBack | xQueueSendToBackFromISR | |
---|---|---|
参数不同 | xTicksToWait: 队列满阻塞时间 | 没有xTicksToWait |
唤醒等待的任务 | 写队列后,会唤醒等待数据的任务,如果唤醒任务优先级高会发起调度 | 写队列后,会唤醒等待数据的任务但不调度,只会记录是否需要发起调度 |
阻塞 | 如果队列满,可以阻塞 也可以即刻返回 | 如果队列满,即刻返回 |
二、切换任务
我们希望中断处理要快,那当我们处理比较耗时的中断就需要中断的延迟处理:
- ISR:尽快做些清理、记录工作,然后触发某个任务
- 任务:更复杂的事情放在任务中处理
FreeRTOS的ISR函数中,使用宏进行任务切换:
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
void XXX_ISR()
{
int i;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
for (i = 0; i < N; i++)
{
xQueueSendToBackFromISR(..., &xHigherPriorityTaskWoken); /* 被多次调用 */
}
/* 最后再决定是否进行任务切换
* xHigherPriorityTaskWoken为pdTRUE时才切换
*/
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
原文地址:https://blog.csdn.net/qq_43340911/article/details/138909001
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!