正文时间到,学习了那么久实时操作系统,对于操作系统的结构认识也是很模糊的;而去阅读源码吧!是一个很痛苦且工作量很大的事情,本人也是折腾N久,终于有一次(也就是在折腾ARM9时的意外收获)发现一片优秀文章,完后才把实时操作系统基本的结构组织了起来。想想对新手是有很大的帮助,也就来写出来。在这里再次强调一句老掉牙的话:要会一点汇编、了解单片机运行原理和对C有较好的理解。
其次呢!单片机它只有一个CPU(排除那个什么双核的单片机,其实我也不太明白它),也就是说它一个时刻点只能做一个事情,就像让你同时照顾10个婴儿一样,你也只能是先哄哄这个,再去哄哄那个。单片机的多任务也是一样的原理。
首先说说一般的、最简单的单片机程序:
void main(void)
{
XXX_Init()
while(1)
{
xxx();
xxx();
......
}
}
好了,我刚开始学51的时候,也是这么写的,其实大家都是这么写的。当然这个还没有包括中断。如果加上中断呢?其实能琢磨RTOS的我想基本都会用中断了吧!但是能理解本质的不一定是全部。我还是画结构吧。
void main(void)
{
XXX_Init()
interrupt_init();
while(1)
{
xxx();
----------------------->假设中断发生在这里,那么单片机就要掉头了,去执行中断了-------->
xxx();
......
}
}
好了,大概就这么个样;其实当时我在想,估计多任务操作系统就是根据硬件中断原理写的吧!
记住硬件中断的准确步骤,有用的。我尽可能的写的通俗一点。
单片机在运行的时候,用到的几个核心的寄存器(写过汇编的人明白)就是PC、累加器和几个CPU的Rx寄存器、在C语言中还有SP(架构不同,细节不同,基本一样)。在正常运行时,用到了这几个寄存器,我叫它们公用寄存器;那么中断发生时,是要进中断函数的,在中断函数里面也是要进行各种运算的,也会用到那几个公用寄存器,怎么办呢?这个时候,用到了C语言里面的那个栈,把那些东西先暂时保存到栈里面(入栈)(结构不一样,栈的理解也不一样,不细说);在中断服务函数里面,就可以把那些公用寄存器值覆盖掉,而去填入新的值。在中断函数执行完毕后,再把那些数填回到那些公用寄存器(出栈),这样就可以实现while(1)主线程和中断辅助线程的双任务了,多个中断也可以排列成优先级不一样的多任务。
而实时操作系统呢,就是类似于用软件来产生单片机硬件那样的中断,而且那中断是可控制的。单片机的运行,实际就是PC指引着CPU去哪儿执行命令,CPU用RX和累加器来就运算中间缓冲。操作系统实际就是用软件控制了PC的值,而不是那种单纯的靠着PC指针自加去顺序的执行命令。