FreeRTOS学习笔记<中断>

中断概念

Cortex-M的NVIC最多支持240个IRQ(中断请求)、1个不可屏蔽中断(NMI)、1个Systick(滴答定时器)定时器中断和多个系统异常

Cortex-M处理器有多个用于管中断和异常的可编程寄存器, 这些寄存器大多数都在 NVIC和系统控制块 (SCB)中, CMSIS将这些寄存器定义为结构体。以 STM32F103为例,打开core_cm3.h,有两个结构体, NVIC_Type和 SCB_Type。NVIC和SCB都位于系统控制空间(SCS)内,SCS的地址从0XE000E000开始。

对于FreeRTOS比较关注的是三个中断屏蔽寄存器:PRIMASK、FAULTMASK和BASEPRI

优先级

Cortex-M处理器有三个固定优先级和256个可编程优先级,最多128个抢占优先级(因为抢占式最多只能占7bit,留一个给子优先级),但实际的优先级数量是由芯片决定的,大多数为8、16、32级等,比如STM32只有16级(这里用了4bit,所以2的4次是16),在设计芯片时会裁掉表达优先级低几位,下面是STM32使用Cortex-M的高四位表示优先级:

使用4位表达优先级
Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0
用于表达优先级没有实现,读回0
STM32支持的5组优先级
优先级分组抢占优先级子优先级描述
NVIC_PriorityGroup_000-15主-0bit,子-4bit
NVIC_PriorityGroup_10-10-7主-1bit,子-3bit
NVIC_PriorityGroup_20-30-3主-2bit,子-2bit
NVIC_PriorityGroup_30-70-1主-3bit,子-1bit
NVIC_PriorityGroup_40-150主-4bit,子-0bit

移植FreeRTOS只能配置组4(只有抢占优先级),因为FreeRTOS中断处理没有子优先级这种情况

优先级设置

每个外部中断都有一个对应的优先级寄存器,每个寄存器占8bit,最大宽度8bit,最小3bit。4个相邻的寄存器可以拼成一个32bit寄存器。在FreeRTOS设置PendSV和Systick的中断优先级的时候都是直接操作地址0xE000ED20

 FreeRTOS中断的屏蔽和开启

(1)FreeRTOS在STM32中中断关闭调用 BASEPRI寄存器。

①只屏蔽优先级低于某一个阈值的中断
1)MOV R0, #0X60
2)MSR BASEPRI, R0

②开启中断
1)FreeRTOS中开启中断是通过对BASEPRI寄存器写0进行的
2)MOV R0, #R0
3)MSR BASEPRI, R0

portENABLE_INTERRUPTS ()//开中断

portDISABLE_INTERRUPTS()//关中断

FreeRTOS中断配置宏

configPRIO_BITS

设置MCU使用几位优先级,STM32使用4位

configLIBRARY_LOWEST_INTERRUPT_PRIORITY

设置最低优先级,因为STM32使用了4bit,这里也配置了组4,所以只有抢占优先级0-15,这里15就是最低优先级。

configKERNEL_INTERRUPT_PRIORITY

用来设置内核中断优先级,主要是PendSV和Systick中断优先级,这里设置为0xF0(最低优先级是configLIBRARY_LOWEST_INTERRUPT_PRIORITY==15,即0x0F,这里要左移4位,得到0xF0),最低的中断优先级。这里写0xFF也行

configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

设置FreeRTOS系统可管理的最大优先级,就是BASEPRI寄存器的阈值。现在的范围是0~15,如果设置为5,也就是高于5的优先级(0~5)不归FreeRTOS管理。

configMAX_SYSCALL_INTERRUPT_PRIORITY

是configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY左移4bit来的,低于configKERNEL_INTERRUPT_PRIORITY设置好的阈值,可以安全调用FreeRTOS的API函数,但未被FreeRTOS管理的中断是不能禁止的(就是调用FreeRTOS开关中断时,对这些中断不受影响),其中断函数不能调用FreeRTOS的API函数

临界段代码

指必须完整运行,不能被打断的代码(代码要保证精简),比如有的初始化过程不能被打算。一般都是采用开关中断的方式。FreeRTOS在进入临界段代码时需要关闭中断,处理完临界段代码再打开中断。分以下两种:

任务级临界段代码保护

taskENTER_CRITICAL()和 taskEXIT_CRITICAL()是任务级的临界代码保护,一个进入是任务级的临界段,一个是退出临界段,成对使用。可能会发生临界段嵌套,所以看源码需要一个全局变量uxCriticalNesting++;来保证成对使用。

中断级临界段代码保护

 taskENTER_CRITICAL_FROM_ISR()和 taskEXIT_CRITICAL_FROM_ISR()

在中断服务程序使用的

这个中断服务程序的优先级一定要低于configMAX_SYSCALL_INTERRUPT_PRIORITY,因为高于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断不能调用FreeRTOS的API,避免造成系统紊乱。

以 “FromISR” 结尾的 FreeRTOS 函数是具有中断调用保护的(执行这些函数会进入临界区),但是就算是这些函数,也不可以被逻辑优先级高于                 configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断服务函数调用

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值