欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FreeRTOS中断嵌套问题

程序员文章站 2022-06-09 16:49:24
...

    任务优先级和中断优先级之间经常会出现混淆。中断优先级,即中断服务程序(ISR)相对于彼此执行的优先级。分配给任务的优先级与分配给中断的优先级没有任何关系。硬件决定ISR何时执行,而软件决定任务何时执行。响应硬件中断而执行的ISR将中断任务,但是任务无法抢占ISR。

      支持中断嵌套的端口需要在FreeRTOSConfig.h中定义下表中详细说明的一个或两个常量,configMAX_SYSCALL_INTERRUPT_PRIORITY和configMAX_API_CALL_INTERRUPT_PRIORITY都定义相同的属性。较旧的FreeRTOS端口使用configMAX_SYSCALL_INTERRUPT_PRIORITY,较新的FreeRTOS端口使用configMAX_API_CALL_INTERRUPT_PRIORITY。

常量

描述

configMAX_SYSCALL_INTERRUPT_PRIORITY或configMAX_API_CALL_INTERRUPT_PRIORITY

设置最高的中断优先级,从中可以调用中断安全的FreeRTOS API函数。

 

configKERNEL_INTERRUPT_PRIORITY

设置滴答中断使用的中断优先级,并且必须始终将其设置为最低的中断优先级。

 

如果正在使用的FreeRTOS端口也未使用configMAX_SYSCALL_INTERRUPT_PRIORITY

常量,那么使用中断安全的FreeRTOS API函数的任何中断也必须以由定义的优先级执行

configKERNEL_INTERRUPT_PRIORITY。

每个中断源都有一个数字优先级和一个逻辑优先级:
    1. 数值优先级
    数字优先级只是分配给中断优先级的数字。例如,如果将中断的优先级分配为7,则其数字优先级为7。同样,如果将中断的优先级分配为200,则其数字优先级为200。
    2. 逻辑优先级
    中断的逻辑优先级描述了该中断相对于其他中断的优先级。

    如果两个优先级不同的中断同时发生,则处理器将为两个中断中优先级较高的中断执行ISR,然后再为两个中断中较低优先级的中断执行ISR。
    中断可以中断(嵌套)具有较低逻辑优先级的任何中断,但是中断不能中断(嵌套)具有相同或更高逻辑优先级的任何中断。
中断的数字优先级和逻辑优先级之间的关系取决于处理器体系结构。在某些处理器上,分配给中断的数字优先级越高,则中断的逻辑优先级越高;而在其他处理器体系结构上,分配给中断的数字优先级越高,则中断的逻辑优先级就越低。
通过将configMAX_SYSCALL_INTERRUPT_PRIORITY设置为比configKERNEL_INTERRUPT_PRIORITY更高的逻辑中断优先级,可以创建完整的中断嵌套模型,下图显示该模型。

  • 处理器具有七个独特的中断优先级

  • 数值越大,其逻辑优先级越高

  • configKERNEL_INTERRUPT_PRIORITY设置为1

  • configMAX_SYSCALL_INTERRUPT_PRIORITY设置为3

FreeRTOS中断嵌套问题

     1. 当内核或应用程序位于关键部分内时,将阻止执行使用优先级1至3(包括1和3)的中断。以这些优先级运行的ISR可以使用中断安全的FreeRTOS API函数。。

     2.使用优先级4或更高优先级的中断不受关键部分的影响,因此调度程序所做的任何事情都不会阻止这些中断立即执行-在硬件本身的限制内。以这些优先级执行的ISR不能使用任何FreeRTOS API函数。

     3.通常,要求非常严格的定时精度的功能(例如,电动机控制)将使用高于configMAX_SYSCALL_INTERRUPT_PRIORITY的优先级,以确保调度程序不会在中断响应时间中引入抖动。


对于ARM Cortex-M  和ARM GIC 

      Cortex-M处理器上的中断配置令人困惑,并且容易出错。在开发过程中,可以通过FreeRTOS Cortex-M端口会自动检查中断配置,但前提是已定义configASSERT()。

       ARM Cortex内核和ARM通用中断控制器(GIC)使用低优先级数字表示逻辑上高优先级的中断。这似乎违反直觉,并且很容易忘记。如果希望将中断分配为逻辑低优先级,则必须为其分配较高的数值。如果希望将中断分配为逻辑高优先级,则必须为其分配较低的数值。
Cortex-M中断控制器最多允许使用八位来指定每个中断优先级,使255为最低可能的优先级。零是最高优先级。但是,Cortex-M微控制器通常仅实现八个可能位的子集。实际实现的位数取决于微控制器系列。

#define __NVIC_PRIO_BITS          2    /*!< Number of Bits used for Priority Levels   

当仅实现了八个可能位的子集时,仅可以使用字节的最高有效位,而使最低有效位未实现。未实现的位可以取任何值,但是将它们设置为1是正常的。下图显示了二进制文件101的优先级如何存储在实现四个优先级位的Cortex-M微控制器中。

FreeRTOS中断嵌套问题

在上图中,因为未实现最低有效的四位,所以二进制值101已移入最高有效的四位。未实现的位已设置为1。

1.有的库函数是在将优先级值上移至已实现(最高有效)位后指定优先级值。当使用这种功能时,可以将上图所示的优先级指定为十进制95。十进制95是二进制101向上移四以形成二进制101nnnn(其中“ n”是未实现的位),并且未实现的位设置为1制作二进制1011111。

2.有些库函数是在将优先级值上移到已实现(最高有效)位之前指定优先级值。当使用这种功能时,必须将上图所示的优先级指定为十进制5。十进制5是二进制101,无任何移位。

configMAX_SYSCALL_INTERRUPT_PRIORITY和configKERNEL_INTERRUPT_PRIORITY必须以允许将它们直接写入Cortex-M寄存器的方式指定,以便在将优先级值上移至实现的位之后。configKERNEL_INTERRUPT_PRIORITY必须始终设置为最低的中断优先级。可以将未实现的优先级位设置为1,因此无论实际实现了多少个优先级位,常量都可以始终设置为255。

NOTE:Cortex-M中断的默认优先级为零,即最高优先级。Cortex-M硬件的实现不允许将configMAX_SYSCALL_INTERRUPT_PRIORITY设置为0,因此使用FreeRTOS API的中断的优先级绝不能保持其默认值。