FreeRTOS的源代码个人分析(基于KEIL下STM32F103的Demo) 三

本文详细分析了FreeRTOS在CM3内核下的任务启动与切换原理,重点讲解了PendSV异常在任务切换中的作用,以及CM3内核在响应中断时的入栈、取向量和堆栈指针更新过程。通过理解这些机制,可以更好地掌握FreeRTOS在STM32上的任务调度机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

任务启动与任务切换

CM3内核任务切换原理

无论是FreeRTOS还是ucos,其任务切换的实现都是用汇编来写的,在STM32上都是用的PendSV这个系统异常来进行任务切换的,参考权威手册121页有关SVC与PendSV的介绍。通过置位NVIC的ICSR中断控制及状态寄存器(131页)地址0xE000_ED04来悬起SVC及PendSV异常,在异常中进行任务切换工作。
CM3内核一共有R0-R15共16个寄存器加上四个特殊功能寄存器
这里写图片描述

其中R0-R12是用来存储程序运行时的临时存储值,R13是栈地址指针寄存器,R14是执行BL程序跳转时用来存储跳转处下一行代码地址用的寄存器,R15总是指向当前执行代码的下一行地址的寄存器。BASEPRI寄存器是用来按优先级来屏蔽中断的,向里面写入数值后会屏蔽大于该值的优先级的中断,FreeRTOS就是在这里来屏蔽中断进入临界区的,写0的话就不屏蔽。(ucos ii是用PRIMASK来屏蔽的,这个寄存器置1后会屏蔽所有可编程优先级的中断,只有几个负优先级的中断可以响应,这个屏蔽非常彻底。)
任务切换就是要先恢复任务最后运行时R0-R12寄存器的值,然后恢复栈指针的地址,xPSR状态寄存器的值,恢复LR寄存器的值,最后用BX LR来跳转到任务上次运行处的位置,此时上次运行后R0-R12的值都恢复原状,栈指针也被恢复,这样任务就会按原来的状态继续运行下去。这是任务切换的原理,无论是什么CPU(x86或者ARM),进行任务切换时,要做的事都大同小异。

FreeRTOS进行任务切换的过程

CM3内核的PendSV异常是专为操作系统用来任务切换用的,无论是FreeRTOS还是ucos在CM3上进行任务切换的过程和代码都差不多的。
当CM3开始响应一个中断时,会在它看不见的体内奔涌起三股暗流:(见权威指南中文版135页)
- 入栈: 把8个寄存器的值压入栈
- 取向量:从向量表中找出对应的服务程序入口地址
- 选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC

FreeRTOS要进行任务切换时,是使用在portmacro.h里的portYIELD()宏来实现的

/* Scheduler utilities. */
#define portYIELD()                                                             \
{
   
                                                                                  \
    /* Set a PendSV to request a context switch. */                             \
    portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;                             \
                                                                                \
    /* Barriers are nor
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值