|
以前一直以为OSAL是一个分时抢占OS(在一帖子上面看到的,不知道是哪个家伙了,误导了我这么久,而我又比较懒,没有做实验就验证),所以就一直都在纠结,会不会被打断我的任务呢,比如我一次采集需要比较长的时间,一个时间片肯定不够的,如果此时激活了优先级较高的任务,那我的采集事件不就要被打断了吗?后来问了一个牛人,他说我误解了OSAL,其实OSAL很简单的,仅仅是简单的FIFO,也就是说只有当一个task完成后,才会开始下一个task。对于他说的,我十分的震撼,想想看,一直认为地是方的,现在有人说是圆的,你能淡定吗?
以下是我们的对话。
我:大家都知道Z-Stack采取时间片轮询任务调度算法,然而Z-Stack2.3.0的时间片长度为320us,也就是说每隔320us协议栈的 OSAL就开始切换Task。废话不刷了,直入正题吧,我的问题是,假如我有一个传感器,每次读取的时间远大于320us假设读取时间为5ms,我该怎么做才能保证读取过程不被打断呢?刚开始想到中断,后来有觉得不妥,因为5ms中有很多个320us了已经被打断很多次了,纠结啊....
牛人:osal并不具备时间片调度功能,任务都是执行完一个再执行下一个的,只是它的最小轮询时间可以达到320us而已。
我:能详细说说吗?
牛人:这个怎么才算详细?你说的那种叫抢先式实时操作系统,就是任务在执行时如果有更高级任务产生,则保存现在任务的现场转去执行高级任务,执行完后恢复现场回到被中断的任务继续执行。OSAL就是不停查询有没有任务需要执行,如果有就执行,执行完了再查询,就这么转着圈的查,一个循环的时间取决于每个任务执行的时间。这要求对每个任务编程时需要注意不要执行太耗时的工作,否则会影响其它任务的执行效果
听了他的话,我决定做一个实验来验证,揭开OSAL任务调度的神秘面纱。
老规矩,选用最简单的例子GenericApp。
对按键事件SW_2进行修改,修改很简单,代码如下
if ( keys & HAL_KEY_SW_2 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
while (1); // 死等
}
使用debug模式,全速运行,触发SW_2事件,中断一下,发现停在while(1);处,然后在系统for(;;)内部断点,再次全速运行,这次真的让我大跌眼镜了(心声:哇靠,真是瞎了我的狗眼),居然再也没有停在断点处了,单击中断看看,居然还停留在while(1);处,由此可见,OSAL要等待当前任务完成,才进行下一次任务的。
唉~~ 大家以后千万别像我这么懒啊,有觉得不妥的就立马做实验验证吧,我从学习Z-Stack开始到现在已经被误导2个多月了啊.... |
|