FreeRTOS专栏4: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 中断优先级的代码,如下所示:

#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS     __NVIC_PRIO_BITS    // 4
#else
    #define configPRIO_BITS     4
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15  //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5   //系统可管理的最高中断优先级
// 15 << (8 - 4) 将高4位的中断优先级设置成15,即最低优先级
#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)

/*
 * See header file for description.
 */
BaseType_t xPortStartScheduler(void)
{
    /* Make PendSV and SysTick the lowest priority interrupts. */
    // 通过绝对地址,将PendSV SysTick中断优先级设置成15
    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))
// 设置系统调用的中断优先级为5
#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;

    __asm
    {
        /* Set BASEPRI to the max syscall priority to effect a critical
		section. */
		msr basepri, ulNewBASEPRI   // 将设置的中断屏蔽优先级写入到 BASEPRI 寄存器中
		dsb
		isb
    }
}

portDISABLE_INTERRUPTS(); // 关闭中断

进入 / 退出中断的函数(其实就是写0 / 写入 BASEPRI寄存器):

portDISABLE_INTERRUPTS();   // 关闭中断
portENABLE_INTERRUPTS();    // 打开中断      

关于 FreeRTOS 与中断屏蔽的说明:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值