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条评论)
登录后参与讨论