1271_FreeRTOS中xPortPendSVHandler的实现

全部学习汇总: GreyZhang/g_FreeRTOS: learning notes about FreeRTOS. (github.com)

前面分析了几个FreeRTOS的接口实现,多次在调度的时候止步。而调度止步的点都是PendSV的请求,可以看得出来PendSV的处理在OS的实现中是比较重要的。接下来,就看一下这部分的处理实现。

首先再次回顾一下M3内核中的寄存器信息,这里有13个通用寄存器还有几个特殊寄存器。其中,通用寄存器又分为两组。其中的一组支持所有的指令操作,而另一组16bit的指令支持有限制。而上下文切换的过程中,几个特殊寄存器可能需要特别关注一下。

这是上下文切换的执行处理软件设计,虽然是汇编但是看上去内容不多,这样可以稍微舒缓一口气。接下来,逐条解读一下。

为了能够更方便解析,我创建了一个新的文件。这样行号确认起来更方便。

第6、7、7行,把psp(线程堆栈指针寄存器)的信息存储到R0寄存器。之后,同步了指令的状态。

第9、10行得结合31行一起看,这个31行的地方其实是对汇编信息进行了一个定义。这样,第9行实现的功能就是把当前任务控制块的指针信息存储地址加载到R3。之后,通过R3寻址查找得出任务控制块的指针信息,存储到R2。

第12、13行,R4~R11存入堆栈。这个操作之后,R0的信息其实是没有发生改变的。之后,把R0的信息,也就是原来的PSP的信息存储到任务控制块的栈顶指针上。关于这个信息的分析,可以看下面代码的数据结构。

关于R0的数值为什么没有发生变化,在这个文档之中是有说明的。

第15行:R3(保存了当前任务控制块的指针)、R14,这个是LR寄存器。如果发生调用返回的时候会自动修改。第18行有调用处理,因此这里做一个压栈保护。

第16、17行,给basepri赋值为configMAX_SYSCALL_INTERRUPT_PRIORITY。之前类似的操作分析过,目的其实是防止OS托管的中断影响到调度环境中的信息。这样的处理,可以屏蔽相关的中断。

第18行:跳转到了一个上下文切换的函数,之前做过这个函数的实现分析,它最终实现的是选择一个最高优先级的任务进行切换准备。

第19、20行,通过修改寄存器实现开中断。

第21行,跟15行正好是相反的操作。恢复了2个寄存器的信息。

第23-25行,先从R3根据指针找到一个TCB指针信息,进一步根据这个指针信息找到任务的栈顶。然后,恢复堆栈信息中R4~R11寄存器的数值。

剩下的部分:更新了堆栈指针之后,切换到新的任务。

整个实现过程其实可以做一个总结,那就是:先保存、再更新、再读取新任务状态到寄存器、切换新任务。多少有点绕脑,尤其是面对不熟悉的汇编指令的时候。但是,多少还是看出了一点点眉目。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值