基于STM32C8T6的freertos的任务切换课堂笔记

本文详细解释了FreeRTOS中任务切换过程,涉及CPU寄存器值的保存和恢复,以及PSP和PendSV中断服务函数在任务切换中的关键作用。特别强调了自动压栈和出栈操作,以及如何通过中断管理和时间片调度实现任务切换。
摘要由CSDN通过智能技术生成

​​​​​


  • 任务切换的本质是CPU寄存器中值的切换,现在要由任务A切换至B,就要将目前CPU中寄存器的值(A任务的值)压栈入A的任务中去,堆栈再将任务B的值(在B的任务堆栈中)出栈到CPU的寄存器中。
  • 只有在异常或特殊中断时才使用MSP,FreeRTOS中任务A的自动压栈和任务B的自动出栈都在中断之外进行,也就是使用PSP指针。
  • 任务切换的过程在PendSV中断服务函数中进行。
  • 触发PendSV中断服务函数的本质上是通过向中断控制和状态寄存器(ICSR)的第28位写入1来挂起PendSV。
  • 当使能时间片调度时,当有同等优先级的多个任务时,每一个滴答定时器中断周期就调用一次PendSV中断服务函数,还可以通过API函数来触发PendSV中断服务函数,用在很多函数里。

  • 压栈时,前一部分寄存器的值硬件会自动保存,后一部分需要我们手动压栈。
    出栈时,需要先手动出栈,在自动出栈。
  •      mrs r0, psp
    自动压栈后PSP指针会指向R0这个寄存器的地址,( mrs r0, psp)将PSP任务栈指针赋值给r0,也就是说现在r0->PSP->R0
  •     ldr r3, =pxCurrentTCB
        ldr r2, [ r3 ]
    r3获取当前运行的任务的TCB的地址。
    r2获取r3这个地址下的值 ,也就是这个地址下第一个元素的地址,也就是栈顶指针的地址
  • stmdb r0 !, { r4 - r11 }
    str r0, [ r2 ] 
    从r0这个地址开始压栈, r4 - r11这些寄存器,最后r0指向任务堆栈最低的一个地址,也就是栈顶地址
    str r0, [ r2 ] ,之前r2获取了栈顶指针,把r0这个地址写入r2的内存里边,现在栈顶指针里边的值指向任务栈最低地址。
    也就是说当需要回复现场时,只要有任务控制块,就能找到栈顶指针,而栈顶指针里边的值就是任务栈最低地址。
  •     stmdb sp !, { r3, r14 }
    将 r3, r14压栈,保存到MSP里边,r3保存的是A的TCB
  •     mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
        msr basepri, r0
    关中断
  •     bl vTaskSwitchContext
        mov r0, #0
        msr basepri, r0
    找到下一个要运行的任务,开中断
  •     ldmia sp !, { r3, r14 }
    出 r3, r14的栈
  •     ldr r1, [ r3 ]
        ldr r0, [ r1 ] /* The first item in pxCurrentTCB is the task top of stack. */
    r1获取 r3这个地址下的值,获取TCB的地址
    r0获取 r1这个地址下的值,The first item in pxCurrentTCB,也就是栈顶指针,得到栈顶指针就能得到栈顶指针里边的值(栈底的地址),r0现在指向栈底地址
  •     ldmia r0 !, { r4 - r11 } /* Pop the registers and the critical nesting count. */
        msr psp, r0
    从这个r0地址回复寄存器的值
    将 r0赋值给psp
  •     bx r14
    执行任务B
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值