zhwm3064 发表于 2014-4-8 23:12:28

《时间触发》这本书提供的调度器最大的缺点

《时间触发》这本书提供的调度器,最大的缺点是程序之间缺少信息沟通

比如如下程序,是一个调度函数
/********************************************************
      ×××××××××××××××调度函数×××××××××××××××××
********************************************************/

void OS_Dispatch_Tasks(void)

   {uchar Index;
      for (Index=0;Index<OS_MAX_TASKS;Index++) //在任务队列中循环找
         {if(OS_tasks_G.RunMe>0)      //如果某个任务需要运行
            { (*OS_tasks_G.pTask)();//就运行这个任务
                OS_tasks_G.RunMe-=1;    //运行当量减一

                if(OS_tasks_G.Period==0)//如果周期等于0
                  {OS_Delete_Task(Index);      //删除此任务
                  }
            }
         }                           
      OS_Report_Status();//报告系统状态
   // OS_Go_To_Sleep();    //进入空闲模式   
   }

其中有一条是删除函数程序:OS_Delete_Task(Index);      //删除此任务
这个程序只是单纯的删除函数,函数退出时,并没有清理函数内部的变量,这样当再次运行函数时,由于前一次变量没有清理干净,会发生运行错误的。

zhwm3064 发表于 2014-4-8 23:18:57

这就好比手机上的安卓软件,如果你从运行程序当中直接按,强行停止程序,虽然程序停止了,但是会发生错误,比如,金山电池医生,强行停止,通知栏上的电池电量图标会永久停在通知栏上,而且电量也不再下降了,因为程序停止了。
而,如果在 全部程序界面,点清除金山电池医生内存,这时金山电池医生就停止运行,同时所有内存也清除,不会发生错误了。

zhwm3064 发表于 2014-4-8 23:25:30

我看如下 方法可能会好
(*OS_tasks_G.pTask)();//就运行这个任务
这条程序会面加一个参数,变成:(*OS_tasks_G.pTask)(OS_tasks_G.stop);//就运行这个任务
这样在程序中判断,如果是stop==1,就清除内存,并且删除本函数。

study_hardware 发表于 2014-4-8 23:25:52

期待激烈讨论

zhwm3064 发表于 2014-4-8 23:35:08

写这本书的作者号称这是非常安全的 程序框架,
经过我的使用发现,如果避开上面提到的缺点,的确是不错,但是,很多时候我们没有办法避开这种应用,那么程序会发生 未知的 不确定的 偶然性的错误。关于这些 作者没有过多的说明,我自己也没有发现有什么更好的方法来解决。
可能,使用RTOS系统可以改变这一缺点吧,因为,这个系统任务间据说有信息传递机制。
而《时间触发》是使用了一种叫做任务队列的方法,这种方法从外部很难动用程序内部的数据。程序指针。

zhwm3064 发表于 2014-4-8 23:40:20

另外还有一种方法可以
就是添加一个程序,这个程序只运行一次,然后在这个添加程序里面再次添加两个程序,第一个只运行一次,作用是初始化,设置好内存数值,第二个才是实际程序

error_dan 发表于 2014-4-9 00:08:38

可重入。。。

zhwm3064 发表于 2014-4-9 05:48:00

本帖最后由 zhwm3064 于 2014-4-9 05:51 编辑

error_dan 发表于 2014-4-9 00:08
可重入。。。

就是尽量使用局部变量,使用局部变量一定是可重入的(可中断的)
如果使用全局变量 或者静态变量,就要想出种种的方法,目的是重入时,不能出错。

实际上我在6楼提供的方法就是只使用局部变量,分两个程序,头一个程序只调用一次,比如设置IO等操作,第二个程序才是主程序,这样两个程序都不包含静态变量。如果合为一个程序,必然得使用静态变量

mcu_lover 发表于 2014-4-9 08:02:49

需要自己动手修改一下,增加任务之间的通信,可以采用队列或者事件的方式。

金牛AKI 发表于 2014-4-9 08:08:37

说的有些道理

coleyao 发表于 2014-4-9 08:12:21

本帖最后由 coleyao 于 2014-4-9 16:25 编辑

如果任务一直运行不删除呢,如果需要任务停止一段时间可以挂起,等需要时再唤醒就好了!

Excellence 发表于 2014-4-9 08:23:57

{:victory:}{:victory:}{:victory:}

zhwm3064 发表于 2014-4-9 09:03:09

一般来说,主要程序之间具有互斥性,所以,可以设置一个全局互斥变量,这样程序相互切换,根据互斥变量的值来确定该停哪个程序该开那个程序,这样就会好了。

harold 发表于 2014-4-10 16:36:45

这是非常老的一本书吧。好像很多年前看过。书写的非常简单。

coleyao 发表于 2014-4-10 18:10:22

书上的内容是不复杂,讲的东西却很实用,而且提供实例和源代码,实时os入门首选啊!

1170390 发表于 2014-4-11 22:57:54

好贴》》》》》》》》》》》》》》》

liuchuanxhu 发表于 2014-6-5 09:03:45

这本书从传统的while(1)到理解任务调度入门的好书

trey21ic 发表于 2014-6-5 09:22:41

别人讲的就是调度器,提供的是一种思路,一种方法,怎么用?还是要自已把握

zhuyi 发表于 2014-6-5 09:32:19

批处理系统而已

BG4RFF 发表于 2014-6-7 11:29:23

我就只创建不删除

zhwm3064 发表于 2014-6-7 16:25:45

我看书上提供的例程全部是只添加程序,而且是一次性添加完,不删除。而我是随时添加随时删除,任务数量是动态的。现在所遇到的问题是——有些任务是不可以任意删除的,必须处理任务中的变量。这个可以实现,但是估计比较复杂,由于任务自身不可以结束自身,所以,涉及到任务与调度器之间的多次通信。1调度器发信息,指示需清除变量,2任务中清变量,并返回信息。3调度器收到信息,结束任务4调度器确认任务已结束,再添加另一任务   或者使用公用变量区,结束任务时同时清变量

冷雨夜 发表于 2014-6-12 12:39:37

函数内部的局部变量不存在这种问题吧,你退出函数变量就不存在了。如果是静态变量或者全局变量,那你用别的OS同样存在可重入问题,都是要留意的。

mangocity 发表于 2014-6-12 12:50:09

为毛你的任务不会自己初始化自己的运行环境?
难道你打算拿个变量不初始化就用?

LOVEDZKF 发表于 2014-9-16 15:37:42

mangocity 发表于 2014-6-12 12:50
为毛你的任务不会自己初始化自己的运行环境?
难道你打算拿个变量不初始化就用? ...

LS正解。。。

damy2008 发表于 2014-9-20 23:55:59

期待讨论

jack_yu 发表于 2014-9-25 13:36:38

长知识了。谢谢

yuzr 发表于 2014-9-25 13:49:26

学习了,这样的讨论交流最实用

ijlc1314 发表于 2014-10-14 17:33:49

看了一点里面的程序,如下:

tByte SCH_Add_Task(void (code * pFunction)(),
                   const tWord DELAY,
                   const tWord PERIOD)   
   {
   tByte Index = 0;
   
   // First find a gap in the array (if there is one)
   while ((SCH_tasks_G.pTask != 0) && (Index < SCH_MAX_TASKS))
      {
      Index++;
      }
   
   // Have we reached the end of the list?   
   if (Index == SCH_MAX_TASKS)
      {
      // Task list is full
      //
      // Set the global error variable
      Error_code_G = ERROR_SCH_TOO_MANY_TASKS;

      // Also return an error code
      return SCH_MAX_TASKS;
      }
      
   // If we're here, there is a space in the task array
   SCH_tasks_G.pTask= pFunction;
   
   SCH_tasks_G.Delay= DELAY;
   SCH_tasks_G.Period = PERIOD;

   SCH_tasks_G.RunMe= 0;

   return Index; // return position of task (to allow later deletion)
   }

我认为,在创建任务的时候,有必要加入原子保护操作

shinemotou 发表于 2014-11-2 21:51:21

这本书挺好的   

canopen 发表于 2014-11-2 21:54:42

LOVEDZKF 发表于 2014-9-16 15:37
LS正解。。。

正解


。。。
页: [1]
查看完整版本: 《时间触发》这本书提供的调度器最大的缺点