搜索
bottom↓
回复: 5

关于小小调度器没看懂,有不少疑问,请大家不吝赐教

[复制链接]

出0入0汤圆

发表于 2014-9-2 09:45:00 | 显示全部楼层 |阅读模式
最近打算使用个小的调度器在8为单片机上,看论坛“小小调度器”不错,打算使用,只是有些没看明白,请大家不吝赐教,如果回答解决了问题,送出40莫元聊表谢意

小小调度器的源码如下:
  1. #include <stc89c51.h>
  2. /****小小调度器开始**********************************************/
  3. #define MAXTASKS 3
  4. volatile unsigned char timers[MAXTASKS];
  5. #define _SS static unsigned char _lc=0; switch(_lc){default:
  6. #define _EE ;}; _lc=0; return 255;
  7. #define WaitX(tickets)  do {_lc=(__LINE__%255)+1; return tickets ;} while(0); case (__LINE__%255)+1:
  8. #define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); }  while(0);
  9. #define RunTaskA(TaskName,TaskID) { if (timers[TaskID]==0) {timers[TaskID]=TaskName(); continue;} }   //前面的任务优先保证执行

  10. #define CallSub(SubTaskName) do {unsigned char currdt; _lc=(__LINE__%255)+1; return 0; case (__LINE__%255)+1:  currdt=SubTaskName(); if(currdt!=255) return currdt;} while(0);
  11. #define InitTasks() {unsigned char i; for(i=MAXTASKS;i>0 ;i--) timers[i-1]=0; }
  12. #define UpdateTimers() {unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}}

  13. #define SEM unsigned int
  14. //初始化信号量
  15. #define InitSem(sem) sem=0;
  16. //等待信号量
  17. #define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
  18. //等待信号量或定时器溢出, 定时器tickets 最大为0xFFFE
  19. #define WaitSemX(sem,tickets)  do { sem=tickets+1; WaitX(0); if(sem>1){ sem--;  return 1;} } while(0);
  20. //发送信号量
  21. #define SendSem(sem)  do {sem=0;} while(0);
  22. /*****小小调度器结束*******************************************************/

  23. sbit LED1 = P2^1;
  24. sbit LED2 = P2^2;

  25. sbit LED0 = P2^5;

  26. unsigned char task0(){
  27. _SS
  28.   while(1){
  29.    WaitX(50);
  30.    LED0=!LED0;
  31.   }
  32. _EE
  33. }

  34. unsigned char  task1(){
  35. _SS6
  36.   while(1){
  37.    WaitX(100);
  38.    LED1=!LED1;   
  39.   }
  40. _EE
  41. }

  42. unsigned char  task2(){
  43. _SS
  44.   while(1){
  45.    WaitX(100);
  46.    LED2=!LED2;
  47.   }
  48. _EE
  49. }

  50. void InitT0()
  51. {
  52.         TMOD = 0x21;
  53.         IE |= 0x82;
  54.         TL0=0Xff;
  55.         TH0=0XDB;
  56.         TR0 = 1;
  57. }

  58. void INTT0(void) interrupt 1 using 1
  59. {
  60.     TL0=0Xff;    //10ms 重装
  61.     TH0=0XDB;
  62.     UpdateTimers();
  63.     RunTask(task0,0);//任务0具有精确按时获得执行的权限,要求:task0每次执行消耗时间<0.5个 ticket
  64. }

  65. void main()
  66. {
  67.         InitT0();
  68.         InitTasks(); //初始化任务,实际上是给timers清零
  69.         while(1){
  70. //      RunTask(task0,0);
  71.         RunTaskA(task1,1);//任务1具有比任务2高的运行权限                 
  72.         RunTaskA(task2,2);//任务2具有低的运行权限
  73.       }
  74. }
复制代码


1. 调度器 _EE ;}; _lc=0; return 255; 这里应该是任务执行完了后返回255,这个255会写到任务的Timers[TaskID]数组中,定时器中断调用UpdateTimers时,检查到这个255不会减1,那么下一次任务就得不到运行啊?(任务运行的条件是Timers[TaskID]=0),我的理解应该是Return 0啊,我的理解到底错在哪里?

2. 任务宏如下:
  1. unsigned char task0(){
  2. _SS
  3.   while(1){
  4.    WaitX(50);
  5.    LED0=!LED0;
  6.   }
  7. _EE
  8. }
复制代码

任务宏定义展开如下:
  1. unsigned char task0()
  2. {
  3.   static unsigned char _lc=0;
  4.   switch(_lc)
  5.    {
  6.     default:
  7.      while(1)
  8.          {
  9.               do {
  10.                       _lc=(__LINE__%255)+1;
  11.                 return 50 ;
  12.            } while(0);
  13.      case (__LINE__%255)+1:
  14.                 LED0=!LED0;
  15.       }
  16.     ;
  17.    }
  18.    ;
  19.    _lc=0;
  20.   return 255;
  21. }
复制代码

我觉得任务中不需要while(1){};因为任务不需要死循环,主要还是通过main函数中的死循环去不断的循环调用各任务,况且任务执行是有返回的,我的理解错在哪里?还有什么更深沉的意义?
宏定义中 do{
            }while(0);的作用是啥,可以删掉吗?
3.RunTask跟RunTaskA的区别应该是每次执行完RunTaskA都重新去扫描放在前面的任务,只有前面的任务都在延时或者等待,才执行后面的任务,
譬如:
   while(1)
      {
         RunTask(Task0,0);
         RunTaskA(Task1,0);
         RunTaskA(Task2,0);
      }
尽管Task0是用RunTask调用的,但实际上有最高的优先级,对于Task2而言,放在最末尾,用RunTask和RunTaskA调用没啥区别,我的理解对吗?

出140入158汤圆

发表于 2014-9-2 09:57:48 | 显示全部楼层
这玩意是形式主义,用来做个跑马灯还凑合,实际应用没什么意义。

出0入0汤圆

 楼主| 发表于 2014-9-2 10:04:33 | 显示全部楼层
amigenius 发表于 2014-9-2 09:57
这玩意是形式主义,用来做个跑马灯还凑合,实际应用没什么意义。

为啥这么说呢?你有好的解决方案吗?

出0入0汤圆

发表于 2014-9-2 11:05:27 | 显示全部楼层
这个得任务优先级 主要是看定时的时间,每次返回255  表示本次任务已经结束,当任务都执行完的以后再大的main函数中又会再次赋值,重新开始。

出0入0汤圆

发表于 2014-9-2 11:19:03 | 显示全部楼层
返回255任务停止了,任务死循环就不会运行到这里停止任务。宏定义这样展开也不对,两个(__LINE__%255)+1;要在同一行

出0入0汤圆

发表于 2014-11-15 17:38:01 | 显示全部楼层
amigenius 发表于 2014-9-2 09:57
这玩意是形式主义,用来做个跑马灯还凑合,实际应用没什么意义。

确实是 我费劲移植到430上 跑了个 灯挺好,但是发现实际用起来局限性太大了,没啥意义
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 07:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表