中断优先级和任务优先级:
1、中断优先级和任务优先级没有任何关系,中断的优先级高于任何任务的优先级,即任务在执行的过程中,中断来了就开始执行中断服务程序。
2、中断优先级数值越小,优先级就越高。FreeRTOS的任务优先级是,任务优先级数值越小,优先级越低。
-
中断优先级:
1、NVIC的全称是Nested vectoredinterrupt controller,即嵌套向量中断控制器。
2、对于M3和M4内核的MCU,每个中断的优先级都是用寄存器中的8位来设置的。8位的话就可以设置2^8 =256级中断,实
际中用不了这么多,所以芯片厂商根据自己生产的芯片做出了调整。比如ST的STM32F1xx和F4xx只使用了这个8位中的高
四位[7:4],低四位取零,这样2^4=16,只能表示16级中断嵌套。
从上面的表格可以看出,STM32支持5种优先级分组,系统上电复位后,默认使用的是优先级分组0,也就是没有抢占式
优先级,只有子优先级。为了更方便管理中断优先级,ST官方建议并且默认使用第5分组:NVIC_PriorityGroup_4,即只有
抢占优先级,优先级为0-15级,数值越大优先级越低。
具有高抢占式优先级的中断可以在具有低抢占式优先级的中断服务程序执行过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以抢占低抢占式优先级的中断的执行。
在抢占式优先级相同的情况下,有几个子优先级不同的中断同时到来,那么高子优先级的中断优先被响应。
在抢占式优先级相同的情况下,如果有低子优先级中断正在执行,高子优先级的中断要等待已被响应的低子优先级中断执行结束后才能得到响应,即子优先级不支持中断嵌套。
Reset、NMI、Hard Fault 优先级为负数,高于普通中断优先级,且优先级不可配置。
对于初学者还有一个比较纠结的问题就是系统中断(比如:PendSV,SVC,SysTick)是不是一定比外部中断(比如SPI,USART)要高,答案:不是的,它们是在同一个NVIC下面设置的。
- configPRIO_BITS
此宏用来设置 MCU 使用几位优先级,STM32 使用的是 4 位,因此此宏为 4!
- configLIBRARY_LOWEST_INTERRUPT_PRIORITY
此宏是用来设置最低优先级,前面说了,STM32 优先级使用了 4 位,而且STM32 配置的 使用组4,也就是 4 位都是
抢占优先级。因此优先级数就是 16 个,最低优先级那就是 15。所以 此宏就是 15。
- configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
此宏用来设置 FreeRTOS 系统可管理的最大优先级。这里设置为 5,也就是高于 5 的优先级(优先级数小于 5)不归
FreeRTOS 管理!
- configKERNEL_INTERRUPT_PRIORITY
此宏用来设置内核中断优先级(用来设置 PendSV 和滴答定时器的中断优先级)。
左移 8-configPRIO_BITS 位,也就是左移 4 位。为什么要左移 4 位呢?因为STM32使用了4位作为优先级,而这4位
是高4位,因此要左移4位才是真正的优先级,也可以直接宏定义为0xF0,但是不直观。
- configMAX_SYSCALL_INTERRUPT_PRIORITY
左移 4 位的原因与之前一致。
此宏设置好以后,低于此优先级(优先级数大于 5)的中断可以安全的调用 FreeRTOS 的 API 函数,高于此优先级(优先
级数小于 5)的中断 FreeRTOS 是不能禁止的,中断服务函数也不能调用 FreeRTOS 的 API 函数!
任务优先级:
- configMAX_PRIORITIES
1、用户实际可以使用的优先级范围是0- configMAX_PRIORITIES -1。
2、建议用户配置configMAX_PRIORITIES 的最大值不要超过32,用户可以使用的范围0-31。数值越大优先级越高。
根据实际应用配置,配置越大,需要的内存空间越大。
3、FreeRTOS 调度器确保处于就绪态或运行态的高优先级的任务获取处理器使用权,换句话说就是处于就绪态的最高优先
级的任务才会运行。
- configUSE_TIME_SLICING
当宏 configUSE_TIME_SLICING 定义为 1 的时 候多个任务可以共用一个优先级,数量不限。默认情况下宏
configUSE_TIME_SLICING 在文件 FreeRTOS.h 中已经定义为 1。此时处于就绪态的优先级相同的任务就会使用时间片轮
转调度器 获取运行时间。
附: ISR 专用、常规API函数对应
| ISR专用函数名 | 常规API对应 | 其它特性 |
| xTaskGetTickCountFromISR | xTaskGetTickCount | |
| xTaskNotifyFromISR | xTaskNotify | 附加参数 |
| xTaskNotifyAndQueryFromISR | xTaskNotifyAndQuery | 附加参数 |
| vTaskNotifyGiveFromISR | xTaskNotifyGive | 附加参数 |
| xTaskResumeFromISR | vTaskResume | 返回值 |
| xQueueIsQueueEmptyFromISR | --- | |
| xQueueIsQueueFullFromISR | --- | |
| uxQueueMessagesWaitingFromISR | uxQueueMessagesWaiting | |
| xQueueOverwriteFromISR | xQueueOverwrite | 附加参数 |
| xQueuePeekFromISR | xQueuePeek | 取消等待 |
| xQueueReceiveFromISR | xQueueReceive | 附加参数,取消等待 |
| xQueueSelectFromSetFromISR | xQueueSelectFromSet | 取消等待 |
| xQueueSendFromISR | xQueueSend | 附加参数,取消等待 |
| xQueueSendToBackFromISR | xQueueSendToBack | 附加参数 |
| xQueueSendToFrontFromISR | xQueueSendToFront | 附加参数 |
| xSemaphoreGiveFromISR | xSemaphoreGive | 附加参数 |
| xSemaphoreTakeFromISR | xSemaphoreTake | 附加参数,取消等待 |
| xTimerChangePeriodFromISR | xTimerChangePeriod | 附加参数,取消等待 |
| xTimerPendFunctionCallFromISR | xTimerPendFunctionCall | 附加参数,取消等待 |
| xTimerResetFromISR | xTimerReset | 附加参数,取消等待 |
| xTimerStartFromISR | xTimerStart | 附加参数,取消等待 |
| xTimerStopFromISR | xTimerStop | 附加参数,取消等待 |
| xEventGroupClearBitsFromISR | xEventGroupClearBits | Daemon Task中执行 |
| xEventGroupGetBitsFromISR | xEventGroupGetBits | Daemon Task中执行 |
| xEventGroupSetBitsFromISR | xEventGroupSetBits | 附加参数,Daemon Task中执行 |