FreeRTOS原理剖析:任务切换过程

1. 任务切换相关API函数

函数 描述
xPortPendSVHandler() PendSV中断服务函数,其实函数原型为PendSV_Handler()
vTaskSwitchContext() 检查任务堆栈使用是否溢出,和查找下一个优先级高的任务,如果使能运行时间统计功能,会计算任务运行时间

2. 任务切换的基本知识

在FreeRTOS任务管理中,最主要的目的就是找到就绪态优先级最高的任务,然后执行任务切换,从而能保持优先级最高的任务一直占用CPU资源。为了达到最优性能,任务切换部分程序使用汇编代码编写。

FreeRTOS有两种方法触发任务切换:

  • 系统节拍时钟中断(SysTick定时器)。切换过程参考《FreeRTOS原理剖析:系统节拍时钟分析》
  • 执行系统调用代码。普通任务使用taskYIELD()强制任务切换;中断服务程序使用portYIELD_FROM_ISR()强制任务切换;在应用程序里也可以通过设置xYieldPending的值来通知调度器进行任务切换。

其中:

// 对于普通任务时
#define taskYIELD()				portYIELD()
#define portYIELD_WITHIN_API 	portYIELD
// 对于中断服务程序时
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )

可以看出,最终执行的代码段为:

#define portYIELD()											\
{															\
	/* 														\
	 * 通过向中断控制及状态寄存器ICSR的第28位写入1,触发PendSV中断	\
	 * 地址为0xE000 ED04 									\
	 */														\
	portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;			\
															\
	/* dsb和isb 完成数据同步隔离和指令同步隔离					\
	 * 保证之前存储器访问操作和指令都执行完						\
	 */														\
	__dsb( portSY_FULL_READ_WRITE );						\
	__isb( portSY_FULL_READ_WRITE );						\
}

通过向中断控制及状态寄存器ICSR(地址:0xE000 ED04)的第28位写入1,触发PendSV中断,从而执行任务切换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值