HotBIOS之零耗时任务切换的研究论证及大略实现方法
OS的任务一般可划分为4个阶段或状态:
1.任务终止.
一般常用于所有任务的初始化任务,它的初始化级别最高,但只运行一次即
自杀或他杀而进入任务终止状态.
有些OS是有任务钩子函数来完成初始化工作的.方法不同效果是一样的.
而钩子函数效率应该高些.
而在C++程序中,由于全局类的构造函数是可以抢在main()前运行的,它也可
用于初始化任务.
虽然这些都可实现,但也是有些区别的,这里不想讨论,只是列举些实现的方法.
2.任务挂起.
由于任务主动执行sleep(),sempend(),mbxpend()等函数,则该任务主动放弃即挂起对程序的控制权利,形成任务阻塞.主动出让控制权是协作式OS的要点.它和裸奔的性质
基本类同,这种编程思路在强实时的OS也是很重要也是一种良好的习惯.
3.任务就绪.
由于节拍中断的到来,可能同时有几个任务挂起的时间到,由于任务级别
的不同(即使级别相同也只能有一个任务按时间片算法按顺序执行)
导致低级别任务在本次切换活动中得不到照顾,虽然处于就绪也不能执行.
4.任务运行
在任务就绪后,本次任务级别最高或下次高级别任务挂起(发送sleep(),sempend(),mbxpend())
则该任务得以完成切换,即在退出节拍中断时OS修改中断返回PC值时原本该返回
被中断任务处的断点改成了该任务上次被中断或阻塞后的地方.
注意这里留了一个疑问,且听下面分解,切记!!!!!!!!!!
概念讲完了,现在讲述如何实现零耗时任务切换,即不需折腾SP.
一.线程池.
由于每个任务需要的RAM的大小不同,SP的大小也就不相同.
由于OS是随机切换的.不能俺顺序编程的思路来顺序的放置即依次调用程序.
函数的调用导致SP大小的伸缩变化,顺序编程是不会出现问题的.
但在OS中就不行了!!!
假使不为每个任务设置SP的指针即大小,俺常规编程手法是不需也很难控制SP的.
那么一个任务执行过程中,由于节拍中断导致该任务被切换到其他任务.此时
由于节拍中断退出时恢复现场的SP是被中断的SP值,故新的任务访问的是旧任务
的变量即RAM区域,所以必须为任务即线程分配独立间隔的区域.
前面留的疑问就是不能此时执行恢复中断现场,因为这是被中断任务的现场,应该把本次被切换任务上次被中断现场的恢复块的SP恢复后再执行中断恢复程序.
当遇到retf后,返回的PC是就是新任务上次被中断或被阻塞后的地方!!!
所以,我们完成最终切换只用了恢复上次的SP值(未一定SP内的任何数据),从而一举实现"零耗时任务切换".
二.任务切换来源及处理方法.
1.硬件节拍中断.
它的工作其一主要是对所有任务的节拍计数,这里有+/-两种方法,主要为后面
任务就绪及运行提供切换依据.
2.软件节拍中断(菜农非典之法)
由于任务阻塞即调用sleep(),sempend(),mbxpend()等函数后,若用软件中断
(51无,但可用无int0时拉低int0来实现"软件中断")调用节拍中断函数.
那么只要区分软硬件方式即可.注意只有硬件节拍中断才节拍任务计数!!!
因为他们调用和返回的路径和方法一样(只是节拍计数不同),所以任务切换的
算法和函数可以一样,这样就大大简化了切换算法的处理.
在有多软件系统中,如DSP/ARM中,软硬件中断分开也可.
用此法都好处是中断使切换只要还原SP寄存器即可~~~
3.外部或其他硬件中断(非硬件节拍中断)
由于HWI的级别比任务高,故也可中断任务.HWI的体系和结构和节拍中断一样
的架构是一样的,联想到上面的任务阻塞用户发送软件中断的方法.
所以它的算法也归类到前2中任务切换,所以这样代码和方法都不用动脑了~~~
4.软件中断.
看起来有人会发问:这可能吗???软件中断可是由任务"手动"发送的,上面任务阻塞不是谈到过了吗???
非也~~~因为在硬件中断HWI中,由于"理论"上说也在HWI不要干重活,故一般采用在HWI中发送SWI_Post()把中断级别即特权自己降低.有时可以再降到任务级.
所以它也归为前面的切换算法之中了~~~
5.硬件中断退出时激活切换
"好的实时OS是硬件中断捣乱的结果"---菜农的歪论~~~
因为正常的OS是搞节拍实现任务切换的,如果运行任务阻塞,高级别任务此时未就绪.
OS切换到空闲任务,高级别由于定时未到也只能等下次节拍中断来获取对CPU的控制权.
所以其OS如果不靠其他中断源在退出前产生的额外任务切换,就只能每节拍中断
及切换一次.
|