STM32之HAL例程-FreeRTOS底层开关中断以及临界区汇总
创作时间:
作者:
@小白创作中心
STM32之HAL例程-FreeRTOS底层开关中断以及临界区汇总
引用
CSDN
1.
https://m.blog.csdn.net/youk110/article/details/123351030
在嵌入式系统开发中,中断管理是实时操作系统(RTOS)的核心功能之一。本文将深入探讨STM32微控制器中FreeRTOS的中断管理机制,包括数据类型定义、优先级设置、中断开关函数以及临界区管理等关键内容,并通过实验验证来加深理解。
1. 数据类型重定义和宏定义预览
FreeRTOS在移植到不同平台时,需要对一些基础数据类型进行重定义,以确保代码的可移植性和效率。以下是FreeRTOS中一些常用数据类型的定义:
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef void * TaskHandle_t;
typedef uint32_t TickType_t;
typedef void (*TaskFunction_t)( void * ); // 一种函数类型的申明,返回类型为void,形式参数为
void类型的指针
// 用于含MPU单元的宏定义
#define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA
#define portUSING_MPU_WRAPPERS 0
2. 优先级设置
STM32使用高4位作为其优先级设置位,FreeRTOS通过以下宏定义来配置中断优先级:
#define configPRIO_BITS 4 /* 15 priority levels for stm32 */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
为什么要左移呢?这是因为STM32使用高4位作为其优先级设置位。默认采用中断分组采用第4种类型,即抢占优先级占用4位,子优先级0位,故用户优先级编号为0~15。设置受RTOS管理最高的优先级编号为5,即优先级编号小于5的不收RTOS管理。
3. 任务的开关中断
FreeRTOS使用basepri寄存器来管理中断,向该寄存器写入某值后,优先级标号高于此值的中断将被屏蔽,向该寄存器写0时,打开所有的中断。
(1)关中断
#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
// 高于configMAX_SYSCALL_INTERRUPT_PRIORITY数值的中断被屏蔽,本列编号为5
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
dsb
isb
}
}
(2)开中断
#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
// 清零开中断
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
__asm
{
/* Barrier instructions are not used as this function is only used to
lower the BASEPRI value. */
msr basepri, ulBASEPRI
}
}
(3)进入临界区
#define taskENTER_CRITICAL() portENTER_CRITICAL()
#define portENTER_CRITICAL() vPortEnterCritical()
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( uxCriticalNesting == 1 )
{
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
}
}
(4)退出临界区
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
#define portEXIT_CRITICAL() vPortExitCritical()
void vPortExitCritical( void )
{
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
(5)中断内临界区的进入和退出
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
4. 实验体验
HAL_Delay(uint32_t Delay)
函数是HAL库用于进行延时的基础函数,未使用RTOS时主要使用SYSTICK的定时中断产生。在使用RTOS时,我们可配置HAL_Delay的时钟基准来自定时器,RTOS的时间基准来自于SYSTICK。
在FREERTOS下,默认情况下SYSTICK和HAL_Delay的定时器中断优先级均为15。为了验证vPortRaiseBASEPRI
功能,我们可设置TIMER优先级为4,并在任务中使用taskDISABLE_INTERRUPTS()
关闭中断,看TIMER的回调函数是否还能进入。
实测结果是关闭FREERTOS的中断,timer中断还是会进入的。
热门推荐
茶叶久泡的影响及适宜的冲泡时间探讨
你的债券究竟什么时候到期?
高密度互联基板如何选择焊锡膏
家庭主妇离婚中可以主张哪些补偿
夫妻共同财产与个人财产的认定标准
验房中的5大检查与操作,为你的房屋安全把关!
战锤世界观:奸奇——变化与阴谋之神的全面解析
育娲人口研究发布各国养育成本相对于人均GDP的倍数 各国养孩子成本排行
燃气抄表员透露5个省钱秘诀,每月轻松省下一半燃气费!
玩转示波器:探秘采样率与带宽的奥秘
高邮战役:抗日战争的最后一役,歼灭日军1200余人
碳正离子课件
绩效考核表如何避免主观评价偏差?2025年专家拆解六步法
哥哥姐姐有没有义务抚养弟弟妹妹?三个家庭抚养问题的法律解答
AI的崛起:它将如何改变IT行业的职业景象?
加班补贴和加班费有什么不同
周末因公事出差算不算加班
被人恶意举报可以打12345申诉吗
南京二手房市场新动向:200万内房源成新宠
赛乐赛:脸胖怎么减?
模电·场效应管放大电路静态工作点的设置方法及其分析估算
助力"新型电力系统"落地!国网山东电力打造可信AI负荷预测
跑步膝盖疼的恢复方法:冰敷还是热敷?
12个跑步前必做的拉伸:跑步前最佳拉伸动作。(内附动图)
也许是世界最强常规潜艇—日本海自新一代潜艇雷鲸号开始海上实验
股票"SZ"和"SH"代表什么?
一级物业标准及收费是怎样的
新手养宠指南:最受欢迎的5种宠物蛇
马尔克斯逝世十周年|唯有孤独恒常如新
太中银铁路22个车站CTC机柜电源升级稳步推进!