1267_FreeRTOS启动第一个任务接口prvPortStartFirstTask实现分析

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

         前面分析了启动调度器的接口实现,在接口实现的最后部分有几个封装的接口当时只做了定时器设置的分析。今天,看一下启动第一个Task的接口prvPortStartFirstTask()的分析。

         首先,确认了一下上面涉及到的这个地址信息其实是向量表的偏移寄存器。

         接下来,去理解ldr的用法。这个我参考了ARM的汇编手册。

         具体的解释可能比较枯燥繁琐,文档中有一段例子其实有很好的参考价值。

         上面是文档中的参考代码。前面两个例子为什么会有不同的转换结果我没理解,因为从手册看的话,两个数值都在0-65535的范围内,似乎是可以一步到位的。第三个例子中,r2获取的其实是place的地址。

         这样,结合上面的MSR的命令介绍。画出来的4条命令的意思逐步解释为:

  1. Vector Table Offset寄存器地址加载到R0
  2. 根据R0中的地址信息,读取Vector Table Offset寄存器的数值,存储到R0。而从Vector Table Offset寄存器中的确出来的内容是一个地址。
  3. 由于上面读取出来的是一个地址,因此,加载命令再执行一次解析出来的是地址上的内容。
  4. 把读出来的内容存储到msp寄存器。

         通过这一段描述,基本可以理解前面的两条操作。首先能够知道,这个寄存器存储的信息其实是一个地址偏移信息。这个地址,可以跟寄存器本身的地址拆离,更确切说是MCU拥有的存储地址。地址可以是RAM也可以是flash。这里的描述可能有点绕,其实是有俩of,也就是说,这个偏移量看的时候还是得看寄存器整体,而修改能够改动的只有提到的21bit,其他的bit应该都是按0算。

         关于这部分的数值,做一个调试查看。这里涉及到两部分的代码,第一个是程序初始化的时候,另一个是在这个部分。两部分的数值全都查看一下,看看相应的数值状态。

         上面这部分代码的信息,应该也是处理这个寄存器。

         而最后赋值的MSP寄存器,是main stack pointer寄存器。这样,应该梳理出来了一个信息链: 地址0xE000ED08(向量表偏移寄存器)存储了一个数值ADDR1,ADDR1地址上存储了另一个信息,这个信息应该是main stack pointer的数值。

         为了查看这部分的信息,修改了一下代码:

         编译后的运行结果:

         结合map的信息其实很容易理解,这个就是RAM的最后地址,然后堆栈是负向增长,使用的其实是RAM最后的一部分空间。

         上面涉及到的几个指令是修改处理器状态的指令,主要是做中断的处理操作。先开启了IRQ,接着开启了FIQ。关于这两种中断的介绍,我从ARM网站的文档中搜到了一点说明后面增补。在开启了中断功能之后,同步数据以及指令后增加了一个PendSV的操作以触发一次上下文的切换。

         结合其他的信息,其实FIQ是fast interrupt request,响应速度要比IRQ速度快一些。两个在硬件设计上有着不同的路由路径。而且,在新的架构上两者没有优先级的差异了。

         这样,第一个任务的启动的分析基本就结束了。看起来PendSV是一个很重要的概念,这是OS启动的一个很巧妙的地方。之前,对于各种切换的认识一直停留在必须由定时器等中断来进行触发的概念看起来需要改一下了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值