临界段的保护

临界段的保护

1、什么是临界段

临界段用一句话概括就是一段在执行的时候不能被中断的代码段。

在 FreeRTOS 里面,这个临界段最常出现的就是对全局变量的操作。

临界段会被打的情况:一个是系统调度,还有一个就是外部中断。

在FreeRTOS,系统调度,最终也是产生 PendSV 中断,在 PendSV Handler 里面实现任务的切换,所以还是可以归结为中断。既然这样,FreeRTOS 对临界段的保护最终还是回到对中断的开和关的控制。

2、Cortex-M 内核快速关中断指令

为了快速地开关中断, Cortex-M 内核专门设置了一条 CPS 指令,有 4 种用法:

CPSID I ;PRIMASK=1 ;关中断
CPSIE I ;PRIMASK=0 ;开中断
CPSID F ;FAULTMASK=1 ;关异常
CPSIE F ;FAULTMASK=0 ;开异常

PRIMASK 和 FAULTMAST 是 Cortex-M内核 里面三个中断屏蔽寄存器中的两个,还有一个是 BASEPRI。

在这里插入图片描述

3、关中断

FreeRTOS 关中断的函数在 portmacro.h 中定义,分不带返回值和带返回值两种。

/* 不带返回值的关中断函数,不能嵌套,不能在中断里面使用 */
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()

void vPortRaiseBASEPRI( void )
{
	uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; 
	{
	msr basepri, ulNewBASEPRI
	dsb
	isb
	}
}

/* 带返回值的关中断函数,可以嵌套,可以在中断里面使用 */ 
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
ulPortRaiseBASEPRI( void )
{
	uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; 
	{
	mrs ulReturn, basepri 
	msr basepri, ulNewBASEPRI 
	isb
	}
return ulReturn;
}

4、 开中断

/* 不带中断保护的开中断函数 */
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) 

/* 带中断保护的开中断函数 */
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) 

void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
	__asm
	{
	msr basepri, ulBASEPRI
	}
}

5、进入/退出临界段的宏

进入和退出临界段的宏在 task.h 中定义

#define taskENTER_CRITICAL() portENTER_CRITICAL()
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )

进入和退出临界段的宏分中断保护版本和非中断版本,但最终都是通过开/关中断来实现。

6、临界段代码的应用

在 FreeRTOS 中,对临界段的保护出现在两种场合,一种是在中断场合,一种是在非中断场合。

/* 在中断场合,临界段可以嵌套 */
{
	uint32_t ulReturn;
	/* 进入临界段,临界段可以嵌套 */
	ulReturn = taskENTER_CRITICAL_FROM_ISR();
	
	/* 临界段代码 */
	
	/* 退出临界段 */
	taskEXIT_CRITICAL_FROM_ISR( ulReturn );
}

/* 在非中断场合,临界段不能嵌套 */
{
	/* 进入临界段 */
	taskENTER_CRITICAL();
	
	/* 临界段代码 */
	
	/* 退出临界段*/
	taskEXIT_CRITICAL();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值