FreeRTOS 任务切换实例

FreeRTOS任务切换概述

FreeRTOS通过任务切换实现多任务并发执行,从而提高系统的响应速度和资源利用率。任务切换的本质是CPU寄存器的切换,它包含两个主要步骤:保存现场和恢复现场。当系统决定从一个任务切换到另一个任务时,它会先保存当前任务的寄存器状态(即保存现场),然后加载另一个任务的寄存器状态(即恢复现场)。这样,新任务就能从上一次停止的地方继续执行。

任务切换的具体流程

在FreeRTOS中,任务切换通常是在PendSV(Pended Service Call,可挂起服务调用)异常中完成的。PendSV的中断优先级可以设置为最低,以确保在所有其他中断处理完成后才执行任务切换。下面是一个任务切换的具体流程实例:
任务A触发SVC中断:假设任务A正在执行,但系统决定切换到任务B。此时,任务A可以通过SVC指令触发SVC中断,以请求进行任务切换。
系统内核准备任务切换:系统内核接收到任务切换请求后,开始准备任务切换。它会挂起PendSV异常,以便在后续的中断处理中执行任务切换。
进入PendSV异常处理:当SVC中断处理完成后,系统立即进入PendSV异常处理。在PendSV的中断服务函数xPortPendSVHandler中,系统会保存当前任务A的上下文(即寄存器状态)到任务A的任务堆栈中。
调用任务切换函数:在xPortPendSVHandler函数中,系统会调用vTaskSwitchContext函数来选择下一个要运行的任务。vTaskSwitchContext函数会更新当前任务控制块(TCB)指针,使其指向最高优先级的就绪态任务。
恢复新任务的上下文:一旦确定了下一个要运行的任务(假设为任务B),系统就会从任务B的任务堆栈中恢复其上下文(即寄存器状态)到CPU寄存器中。
返回线程模式:最后,系统返回线程模式,开始执行任务B。此时,任务B从上一次被切换时停止的地方继续执行。

实例代码分析

以下是化的PendSV中断服务函数xPortPendSVHandler的汇编代码,用于说明任务切换的具体实现:
__asm void xPortPendSVHandler( void )
{
extern uxCriticalNesting;
extern pxCurrentTCB;
extern vTaskSwitchContext;
PRESERVE8
mrs r0, psp // 从进程堆栈指针 (PSP) 中读取当前任务的堆栈指针
isb // 执行同步屏障指令,确保所有之前的指令都已完成
ldr r3, =pxCurrentTCB // 获取当前任务控制块 (TCB) 的地址
ldr r2, [r3] // 从 pxCurrentTCB 中加载当前 TCB 的地址
stmdb r0!, {r4-r11} // 将 r4 到 r11 寄存器的内容保存到堆栈中
str r0, [r2] // 将新的堆栈顶部地址保存到 TCB 的第一个成员中
stmdb sp!, {r3, r14} // 将 r3 和 r14 (LR) 保存到主堆栈 (MSP) 中
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY // 设置基础优先级寄存器 (BASEPRI) 为最大系统调用中断优先级
msr basepri, r0 // 将 r0 的值写入 BASEPRI 寄存器
dsb // 数据同步屏障
isb // 指令同步屏障
bl vTaskSwitchContext // 调用任务切换函数 vTaskSwitchContext
mov r0, #0 // 将 BASEPRI 寄存器重置为0
msr basepri, r0 // 将 r0 的值写入 BASEPRI 寄存器
ldmia sp!, {r3, r14} // 从主堆栈 (MSP) 中恢复 r3 和 r14 (LR)
ldr r1, [r3] // 从 r3 中加载当前 TCB 的地址
ldr r0, [r1] // 从 TCB 的第一个成员中加载任务堆栈顶部的地址
ldmia r0!, {r4-r11} // 从堆栈中恢复 r4 到 r11 寄存器的内容
msr psp, r0 // 将 r0 的值写入 PSP 寄存器
isb // 指令同步屏障
bx r14 // 返回到中断前的地址
nop // 无操作指令
}

在这段代码中,系统首先保存当前任务的上下文,然后调用vTaskSwitchContext函数来选择下一个要运行的任务,并恢复其上下文。最后,系统返回线程模式,开始执行新任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值