Skip to content

临界段

在执行的时候不被中断的函数

一般是在系统调度以及外部中断的时候会被打断

  • PRIMASK: 设置为1以后关闭所有可屏蔽中断, 只剩下NMI和硬FSULT可以响应

  • FAULTMASK, 设置为1, 只有NMI可以响应

  • BASEPRI: 最多有九位, 设置为一个数, 优先级比他大的都屏蔽

实现

c
//关闭中断
#define portDISABLE_INTERRUPTS()				vPortRaiseBASEPRI()
//在中断中使用,中断保护版本
#define portSET_INTERRUPT_MASK_FROM_ISR()		ulPortRaiseBASEPRI()


#define portINLINE __inline

#ifndef portFORCE_INLINE
	#define portFORCE_INLINE __forceinline
#endif

//定义函数为内联函数
static portFORCE_INLINE void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;//这个值高四位有效为11, 中断优先级高于11可以响应

	__asm
	{
		/* Set BASEPRI to the max syscall priority to effect a critical
		section. */
		msr basepri, ulNewBASEPRI
		dsb
		isb
	}
}
//把原来的数字保存在返回值中, 之后设置为11, 为可以嵌套的
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
{
uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;

	__asm
	{
		/* Set BASEPRI to the max syscall priority to effect a critical
		section. */
		mrs ulReturn, basepri
		msr basepri, ulNewBASEPRI
		dsb
		isb
	}

	return ulReturn;
}

实现关闭中断, 前一个值由于不关心中断现在的状态所以不能在中断中使用

c
//打开最有中断
#define portENABLE_INTERRUPTS()					vPortSetBASEPRI( 0 )
//设置打开的范围
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)	vPortSetBASEPRI(x)


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
	}
}

打开中断