原创
四、freeRTOS与Cortex - M中断
Cortex - M中断
1 中断简介
中断与异常
可以看到,中断源的个数和优先级的位数,都是由芯片厂商决定的(stm32的中断优先级为高4位)。
系统异常清单:
2 NVIC 寄存器设计
手册中关于NVIC的描述:
NVIC寄存器详细说明:
1 中断的使能与除能
对应的寄存器描述:
对应的stm32标准库中的结构体:
中断悬起/解悬寄存器:
中断优先级设置寄存器:
以上是外部中断的优先级,系统异常的优先级设置如下:
中断激活位寄存器:
中断优先级的定义:
抢占优先级与子优先级设置:
应用程序中断及复位控制寄存器描述:
在 HAL 库中,有中断优先级分组的设置:
这个寄存器设置在SCB(系统控制寄存器)中,如下所示:
CM3内核与stm32中断向量的对应关系(中断向量表):
这与下面的ARM-Cortex内核是相对应的:
系统异常是由 ARM 设计的,不能修改。
外部中断是由ST设计的,通过设置IP(中断优先级)寄存器来设置,如下所示:
这个和stm32f10x.h中的设置是一致的;
实际上,stm32也是通过IP寄存器来设置中断优先级的,如下所示:
对于 FreeRTOS 中比较重要的是,PendSV 和 SysTick 这两个中断。
注意这个地址,0XE000_ED20,实际上这里包含 4 个 8位优先级设置寄存器。
在调度器函数源码中,有设置 PendSV 和 SysTick 中断优先级的代码,如下所示:
#define configPRIO_BITS __NVIC_PRIO_BITS
#define configPRIO_BITS 4
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
#define portNVIC_SYSPRI2_REG (*((volatile uint32_t *)0xe000ed20))
#define portNVIC_PENDSV_PRI (((uint32_t)configKERNEL_INTERRUPT_PRIORITY) << 16UL)
#define portNVIC_SYSTICK_PRI (((uint32_t)configKERNEL_INTERRUPT_PRIORITY) << 24UL)
BaseType_t xPortStartScheduler(void)
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
中断屏蔽
PRIMASK 与 FAULTMASK
在 UCOS 操作系统中,进入临界段使用的就是 PRIMASK 寄存器,会屏蔽掉几乎所有的寄存器。
而在 FreeRTOS 中,使用的是 BASEPRI 寄存器,实现更加精细的控制,如下所示:
如果设置写入的优先级为5,则 0 ~ 4的优先级无法被屏蔽,5及以上的中断都会被屏蔽。
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
static portFORCE_INLINE void vPortRaiseBASEPRI(void)
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
msr basepri, ulNewBASEPRI
portDISABLE_INTERRUPTS();
进入 / 退出中断的函数(其实就是写0 / 写入 BASEPRI寄存器):
portDISABLE_INTERRUPTS();
关于 FreeRTOS 与中断屏蔽的说明:
转载于:https://blog.csdn.net/dingyc_ee/article/details/104054941
文章评论(0条评论)
登录后参与讨论