你好,这里是风筝的博客,
欢迎和我一起交流。
寒假那段时间开始接触UCOS实时操作系统,感觉真的很神奇,还借了任哲和邵贝贝的书的来看,原来代码还可以写得那么美妙。
后来,在知乎上看到一位答主的文章(https://www.zhihu.com/question/25628124/answer/133388181),顿时对操作 系统兴趣大增,想着自己也简单写一个轻量级的嵌入式操作系统。
现在好几个月过去了,这个操作系统我用着感觉还不错,非常的小(自己写的嘛,功能有限,呵呵呵)。当然,当初写这个也是为了好玩而已,并不保证严格的实际用途。
就想着开源出来,与大家一起分享。
这一章并不打算就这样裸讲程序,感觉先把概念说一下比较好:
什么是操作系统?
所谓操作系统就是能有效地管理计算机系统中的各种硬件\软件资源、合理的组织计算机的工作流程,从而为程序员\操作员和各类用户创造良好的工作环境的系统软件.
由于我学习的操作系统为UCOS,所以也将参照他的风格来写。而且由于实时操作系统与通用操作系统的基本设计原则差别很大,因此在很多资源调度策略的选择上以及操作系统实现的方法上两者都具有较大的差异。
我们需要完成以下部分:
a.任务调度策略
b.内存管理
c.中断处理
d.共享资源的访问
恩.....大概就这些吧,反正我只实现了这些,,,,,,
我的实验平台为ST公司的STM32F1系列的板子,Cortex-M3的内核,属于ARMv7家族。
好了,写代码之前,我们得先确定下a点,任务调度策略:
采用基于优先级的抢先式调度策略。
但是我们怎么实现任务抢占(即任务切换)呢?
当一个运行中的任务A因为某种原因要切换到其他任务去运行时,A必须保存自己的"上下文"(进程的状态以及堆栈中的内容被称为该进程的上下文),以保证以后再次切换回A运行时,能从已保存的"上下文"中恢复回来。这样当A再次运行时,对A而言"上下文"根本没有变化过,好像从来没有进行过任务切换一样。
如果用汇编写程序就知道,很多东西都是存在寄存器里的。查看下《Cortex-M3权威指南》可以知道:
Cortex-M3有两个堆栈指针,但是同一时刻只能用一个,我们可以用一个来作为任务切换时保存"上下文"。如图
抽象图,嘿嘿。。。。。。。
此时在cpu在跑任务B,任务切换时,把运行任务B时的寄存器参数入栈保存到任务B栈中,再把任务A栈里的内容出栈处理,这样就可以实现任务切换了,从任务B切换到任务A。
其实在权威指南里也说有:
使用双堆栈指针。注意哦,M3的堆栈是"向下"的哦。
这图明显没我灵魂画师画得好,嘿嘿。不过看到一个有用的信息:SysTick作为系统"心跳"。
好了,知道是怎么切换任务的了,那问题又来了,谁来做这些操作呢?
当然是从权威指南里找答案了:
还有一张图,带你理解PendSV,真贴心:
到这里。任务切换部分算是知道是怎么回事了。。。
b.内存管理,这个以后再说。
c.中断处理,从之前的图可以看出,系统应当采用SysTick(滴答定时器)作为系统"心跳"。
因为是基于基于优先级的调度策略,所以每次"心跳",都要去检测有没有比当前任务更高优先级的任务产生,如果有,通过PendSV进行任务切换。当然,任务切换不仅限于此,可能还是任务自身让出CPU使用权。
d.共享资源的访问,因为是单核的CPU,打个比方,厕所(资源)只有一个,小A(任务A)和小B(任务B)都想去上厕所(资源),那不就出问题了吗?所以之后我们要注意这个问题,之后再深入讨论这个。
恩,,,,,,码了那么多,感觉就那么多了,就先这样了。下一章再分析具体程序。
先放个交流群:136045527
下一章:自编STM32轻量级操作系统(二)------任务调度