1266_FreeRTOS调度器启动代码实现分析

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

这一次看一下FreeRTOS的启动都执行了什么操作。

这个是CubeIDE生成的代码中内核启动的接口,这个并不是FreeRTOS最原始的接口而是进行了一定封装的结果。看一下这个接口的实现。

这种封装的意义看起来不是很大,因为没有实质的变化,只是增加了一个无效的返回值。然而,增加的这个无效返回值在调用的时候又被丢弃了。因此,这个其实可以直接调用FreeRTOS的接口即可。

在我用的工程中,可以按照上面的形式修改,运行没有什么本质上的区别。

只要是FreeRTOS配置了支持静态存储分配功能,支持静态的任务创建模式,那么就会在任务调度器启动前以静态的方式创建一个idle task。Idle task进行静态创建的时候,首先获取指定的存储的信息、TCB的对象位置以及堆栈大小,而后利用这些信息以静态的方式创建一个task。最后,判断了一下创建idle task是否成功。

关于存储以及定义对象的信息获取接口,实现比较简单。但是这里涉及到了一个新的复杂的数据结构。结合上面的两部分代码,采用静态的方式创建idle task的时候其实是不占用FreeRTOS的heap空间的。

这个数据结构从注释看就看得出来,其实只是一个存储分配以及对齐的处理。但是,这个可读性并不好,更不推荐访问其中的成员。我猜测这个跟标准的TCB_t有对应关系,测试了一下两者的大小,发现所占的存储空间其实是一致的。

看得出来,两个所占的存储空间一致。可能,在后面的OS的处理中两者会有一定的转换映射关系。

如果不支持静态的方式,那么就会在启动调度器的时候以动态的方式创建一个idle task。

上面这部分代码,有效的部分其实只有一点,那就是:如果前面的idle task创建成功了,接下来禁用中断。关于中断禁用的接口,之前已经做了一次分析,这里不再累述。

接下来,更新一部分OS的基础信息之后,进入到调度器的启动。关于调度器的启动,后面再进一步分析。如果idle task创建失败的话,那么会直接在断言的位置停住。

启动调度器,首先判断了configMAX_SYSCALL_INTERRUPT_PRIORITY设置的合理性。这个不可以为0,之前也测试过,现在的工程中这个数值为80。之后,读取了第一个中断优先级寄存器的内容做了保存备份。之后,给这个寄存器写入了0xFF然后回读,因此判断这个内核实现的中断优先级的支持。最后,根据最大优先级的支持信息把前面配置的最大系统调用中断优先级的可能错误置1的bit清零。

这里,再次打印一下确认一下。

注释里对这部分功能做了说明,其实这里应该得出一个3的结果。我加了一个中间量来看看这个真实的结果。

这是打印出来的结果,看得出来跟前面的分析一致。

这里其实是对计算出来的结果而配置中的结果做了一个校验。那么,计算的依据是哪里来的,配置信息又是从哪里来的呢?

这是上面计算的依据,来自于内核手册。

这是上面配置的依据,来自于芯片手册。

针对前面计算出来的组优先级数值为3,具体是什么意思呢?结合注释提示,可以找到上面的文档。最终,这个组优先级是用来填充上面这个SCB_AIRCR寄存器的组优先级位的。而填充的效果是,所有的优先级都是组优先级,没有子优先级。

结合这一部分文档,这里把优先级设置为最低是可以理解的。但是没弄明白为什么3个寄存器必须用第三个,我这里尝试切换成前面两个,结果发现使用第一个的时候整个系统的行为与以前一致。使用第二个的时候,系统出现了异常。

接下来的处理,是对上面第一个接口vPortSetupTimerInterrupt的调用。看到这里的代码,发现systick还是生效了的。这个让我觉得有一点费解,之前其实是有一个定时器用作了tick的处理,还做过测试。也就是上面的第二段代码。这次我又做了对比测试,屏蔽掉了这个Tick增加接口,发现这个回调函数还是在不断执行,OS也可以正常运行。因此,这里实现的功能,可能还仅仅是一个计数器或者计时器,但是FreeRTOS的功能还是依赖于SysTick来实现。

这里,实现了SysTick的中断处理。这里我不禁好奇一把,如果把这部分处理直接放到前面的回调函数中OS是否可以运行起来呢?尝试做了一下修改,禁用了调度器启动时候的定时器的处理,相关的处理放进了定时器的回调函数,测试先前的任务运行正常。这样,vPortSetupTimerInterrupt其实是可以禁用掉的。更优雅的方法应该是重新定义,覆盖掉这部分的功能。但是,现在的CubeIDE生成的代码这方面并没有处理好。

接下来,启动了第一个任务、进行了上下文切换并进行了一个错误检查。

这样,大概的调度器启动的框架就分析完了。中间的内容看上去并不复杂,但是零碎的信息比较多。而且,还有最后的几个OS相关的接口没有做实质的分析。后面,还得拿时间出来看一下具体的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值