FreeRTOS-临界段

什么是临界段?临界段就是在执行时不能被打断(除非是系统调度(pend SV中断),或外部中断)的代码。

FreeRTOS对临界段的保护还是通过对中断的开和关来控制。

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

①:
在这里插入图片描述
这个寄存器是只有一位的寄存器。控制方式如下:
在这里插入图片描述
②:
在这里插入图片描述
同样也是一位的寄存器。
在这里插入图片描述
③:
在这里插入图片描述

关中断

freeRTOS关中断的函数定义在 portmacro.h 文件中。
关中断函数分为带返回值和不带返回值两种。
不带返回值的如下:
注意:不带返回值的是不能嵌套,且不能在中断中使用的。

#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
static portFORCE_INLINE void vPortRaiseBASEPRI(void)
{
    uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
	  
	  __asm
	  {
		    msr basepri, ulNewBASEPRI    // 大于11 是不能被响应的,小于11是能响应的
			  dsb
			  isb
		}
}

带返回值的如下:
注意:带返回值的是能够用于中断且能嵌套使用的。

#define portSET_INTERRUPT_MASK_FROM_ISR()     ulPortRaiseBASEPRI()     // 凡是看到FROM_ISR,都是在中断里面用到。
// 返回一个无符号整型变量。  可嵌套,可在中断中使用
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI(void)
{
    uint32_t ulReturn,ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
	  __asm
	 {
	     mrs ulReturn,basepri     // 把原先basepri的值保存在返回值中
		   msr basepri,ulNewBASEPRI  // 在设置basepri的值
		   dsb
		   isb
	 }
	 return ulReturn;
}

开中断

与关中断一样,开中断函数也是在 portmacro.h 函数中定义的。
开中断函数分为有中断保护的和不带中断保护的函数。
带中断保护的:
与带返回值的关中断函数portSET_INTERRUPT_MASK_FROM_ISR() 配对使用。

#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)  vPortSetBASEPRI(x)
static portFORCE_INLINE void vPortSetBASEPRI(uint32_t ulBASEPRI)  // 开中断函数
{
     __asm
		{
		    msr basepri,ulBASEPRI
		}
}

不带中断保护的:
与不带返回值的 portDISABLE_INTERRUPTS()配对使用。

#define portENABLE_INTERRUPTS()  vPortSetBASEPRI(0)

开中断函数将 ulBASEPRI保存到BASEPRI寄存器中(汇编语言:msr用于恢复状态寄存器的内容或改变寄存器的内容。),根据传进来的形参选择两者中的一个。

进入/退出临界段

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

进入临界段:

FreeRTOS-临界段_第1张图片
FreeRTOS-临界段_第2张图片

退出临界段:

FreeRTOS-临界段_第3张图片
FreeRTOS-临界段_第4张图片
FreeRTOS-临界段_第5张图片
有一部分是根据野火freeRTOS内核实现与应用开发实战指南截图的。
如果有需要PDF的请联系我。

如有错误,欢迎批评指正。
欢迎交流学习!

完。

你可能感兴趣的:(stm32解析)