FreeRTOS之开关中断
来源:互联网 发布:js有没有boolean 编辑:程序博客网 时间:2024/06/08 12:08
1.Cortex-M3和M4的中断介绍
Cortex-M3和M4的NVIC最多支持240个IRQ(中断请求)、一个不可屏蔽中断(NMI)、一个SysTick(滴答定时器)定时器中断和多个系统异常。
2.Cortex-M3和M4中断屏蔽寄存器介绍
这里介绍的寄存器有3个:PRIMASK、FAULTMASK、BASEPRI
(1)PRIMASK寄存器
PRIMASK寄存器可以禁止除NMI和HardFault两个中断外的所有的异常和中断。
CPSIE I; // 清除PRIMASK(使能中断)CPSID I; // 设置PRIMASK(禁止中断)
多说一句,在uC/OS中就是通过该方式实现中断的使能和禁止。
(2)FAULTMASK寄存器
FAULTMASK寄存器会把异常的优先级提升到-1,除复位外,其他的异常和中断都能屏蔽掉。
CPSIE F; // 清除FAULTMASKCPSID F; // 设置FAULTMASK
(3)BASEPRI寄存器
该寄存器可以屏蔽低于某一个阈值的中断。
注意:FreeRTOS的开关中断就是操作BASEPRI寄存器来实现的,它可以关闭低于某个阈值的中断,高于这个阈值的中断就不会被关闭。
3.FreeRTOS中断配置宏
(1)configPRIO_BITS
此宏用来设置MCU使用几位优先级。
(2)configLIBRARY_LOWEST_INTERRUPT_PRIORITY
此宏用来设置最低优先级。
(3)configKEYNEL_INTERRUPT_PRIORITY
此宏是configLIBRARY_LOWEST_INTERRUPT_PRIORITY左移得来的。
此宏用来配置系统调用(PendSV)和滴答定时器(Systick)的中断优先级。
(4)configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
此宏用来设置FreeRTOS系统可管理的最大优先级,也就是BASEPRI寄存器中存放的阈值。
(5)configMAX_SYSCALL_INTERRUPT_PRIORITY
此宏是configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY左移得来的。
4.FreeRTOS开关中断
FreeRTOS开关中断的函数为portENABLE_INTERRUPTS()和portDISABLE_INTERRUPTS(),它们都是宏定义。
函数的定义位于portmacro.h中:
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() // 关中断#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) // 开中断
由以上可以看出开关中断其实是由函数vPortSetBASEPRI(0)和vPortRaiseBASEPRI()来实现的,函数的原型定义如下:
// 开中断// 向basepri中写入0就表示开中断static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ){ __asm { msr basepri, ulBASEPRI }}// 关中断// 向basepri中写入configMAX_SYSCALL_INTERRUPT_PRIORITY,// 表明优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断都会被屏蔽static portFORCE_INLINE void vPortRaiseBASEPRI( void ){uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { msr basepri, ulNewBASEPRI dsb isb }}
5.临界段代码
临界段代码也叫临界区,是指那些必须完整运行、不能被打断的代码段。
FreeRTOS在进入临界段代码的时候需要关闭中断,处理完临界段代码以后再打开中断。
FreeRTOS与临界段代码保护有关的函数有4个:taskENTER_CRITICAL()、taskEXIT_CIRTICAL()、taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()。这些函数其实是宏定义,在task.h中定义。前两个是任务级的临界代码段保护,后两个是中断级的临界代码段保护。
(1)任务级临界代码段保护
taskENTER_CRITICAL()是进入临界段,taskEXIT_CRITICAL()是退出临界段,定义如下:
#define taskENTER_CRITICAL() portENTER_CRITICAL() #define taskEXIT_CRITICAL() portEXIT_CRITICAL()
portENTER_CRITICAL()和portEXIT_CRITICAL()也是宏定义,在文件portmacro.h中有定义,如下:
#define portENTER_CRITICAL() vPortEnterCritical()#define portEXIT_CRITICAL() vPortExitCritical()
函数vPortEnterCritical()和vPortExitCritical()在文件port.c中定义,如下:
// 进入临界段代码的时候调用void vPortEnterCritical( void ){ portDISABLE_INTERRUPTS(); // 关闭中断 uxCriticalNesting++; // uxCriticalNesting是一个全局变量,用来记录嵌套次数的。 if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); }}// 退出临界段代码的时候调用void vPortExitCritical( void ){ configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); // 打开中断 }}
(2)中断级临界段代码保护
函数taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()为中断级临界段代码保护函数,用在中断服务程序中,而且这个中断优先级一定要低于configMAX_SYSCALL_INTERRUPT_PRIORITY。这两个函数在文件task.h中定义。
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
函数portSET_INTERRUPT_MASK_FROM_ISR()和port_CLEAR_INTERRUPT_MASK_FROM_ISR()在portmacro.h中定义,如下:
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
函数ulPortRaiseBASEPRI()在portmacro.h中定义,如下:
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void ){uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm { mrs ulReturn, basepri // 读出basepri的值,放入ulReturn msr basepri, ulNewBASEPRI // 将configMAX_SYSCALL_INTERRUPT_PRIORITY的值写入 // basepri中 dsb isb } return ulReturn; // 返回ulReturn}
- FreeRTOS之开关中断
- FreeRTOS临界段和开关中断
- FreeRTOS临界段和开关中断
- FreeRTOS 中断
- FreeRTOS中断分析
- STM32F4使用FreeRTOS的中断
- STM32F4使用FreeRTOS的中断
- ucos-ii开关中断
- Linux的开关中断
- STM32开关总中断
- 【学习笔记】zedboard上freertos 按键中断
- 【学习笔记】zedboard上freertos 按键中断
- FreeRTOS学习笔记——SysTick中断
- FreeRTOS中断调用api卡死
- 学习FreeRTOS(3):两种中断
- FreeRTOS CortexM3 M4中断优先级设置总结
- FreeRTOS 中断配置和临界段
- FreeRTOS怎么定义systick中断处理?
- MBCS与Unicode码
- 1. 函数调用
- 3. 变量的存储布局
- 2. main函数和启动例程
- Unicode和UTF-8
- FreeRTOS之开关中断
- 什么是操作符重载
- Handler体系以及原理
- 二叉树中的那些常见的面试题
- Jupyter NoteBook
- 宏定义(一)
- 阿里巴巴盘中市值达4700亿美元;B站计划最快明年美国IPO ;NASA计划为前往火星宇航员修改DNA丨价值早报
- 图片的异步加载和适配器
- sizeof的深入理解