网站导航: 首页 > 设计参考 > 正文 文章搜索
一个抢占式、多个合作式任务调度器的C51源代码
 
文章编号:
091114225159
文章分类: 单片机 51系列
点 击:
...
关 键 词: 抢占式,多个合作式,任务调度器
文章来源:
网络
摘 要:

 
  1. /*==============================================================  
  2. 1ms时标 混合式调度器(一个抢占式任务,多个合作式任务)  
  3. 作者:shadow.hu  
  4. ===============================================================*/  
  5. #include<reg52.h>   
  6. #define uchar  unsigned char   
  7. #define ushort unsigned short   
  8. #define SCH_MAX_TASKS 9   
  9. #define ERROR_SCH_TOO_MANY_TASKS  9   
  10. #define ERROR_SCH_CANOT_DELETE_TASK 0   
  11. #define RETURN_ERROR 0   
  12. #define RETURN_NORMAL 1   
  13.   
  14. #define INTERRPT_Timer_2_Overflow 5   
  15.   
  16. #define SCH_REPORT_ERRORS   
  17. #ifdef  SCH_REPORT_ERRORS   
  18. #define Error_Port P1   
  19. #endif   
  20.   
  21. typedef data struct  
  22. {   
  23.     void (code *pTask)(void);   
  24.     ushort Delay;   
  25.     ushort Period;   
  26.     ushort RunMe;   
  27.     uchar  Co_op;//如果任务是合作式的,设置为1,如果任务是抢占式的,设置为0   
  28. }sTask;   
  29. sTask SCH_tasks_G[SCH_MAX_TASKS];   
  30.   
  31. void SCH_Init_T2(void);   
  32. uchar SCH_Add_Task(void (code * pFunction)(),const ushort Delay,   ushort PERIOD);   
  33. //                      函数名指针                 延时的时标数    执行任务的时间间隔   
  34. //                                                 为0则立即执行   如果为0,表示单次任务      
  35. void SCH_Dispatch_Tasks(void);   
  36. void SCH_Start(void);   
  37. bit SCH_Delete_Task(const ushort TASK_INDEX);   
  38. void SCH_Go_To_Sleep(void);   
  39. void SCH_Report_Status(void);//报告系统状况   
  40. void LED_Flash_Init(void);   
  41. void LED_Flash_Update_A(void);   
  42. void LED_Flash_Update_B(void);   
  43. void LED_Flash_Update_C(void);   
  44. void LED_Flash_Update_D(void);   
  45. void LED_Flash_Update_E(void);   
  46. void LED_Flash_Update_F(void);   
  47. void LED_Flash_Update_G(void);   
  48. void LED_Flash_Update_H(void);   
  49.   
  50. uchar Error_code_G = 0;//   
  51. static ushort Error_tick_count_G;//记住自从上一次纪录错误以来的时间   
  52. static uchar Last_error_code_G;//上次的错误代码(在1分钟之后复位)   
  53.   
  54. uchar  LED_State_G_A = 0;   
  55. uchar  LED_State_G_B = 0;   
  56. uchar  LED_State_G_C = 0;   
  57. uchar  LED_State_G_D = 0;   
  58. uchar  LED_State_G_E = 0;   
  59. uchar  LED_State_G_F = 0;   
  60. uchar  LED_State_G_G = 0;   
  61. uchar  LED_State_G_H = 0;   
  62.   
  63. sbit LED_pin_A = P1^0;   
  64. sbit LED_pin_B = P1^1;   
  65. sbit LED_pin_C = P1^2;   
  66. sbit LED_pin_D = P1^3;   
  67. sbit LED_pin_E = P1^4;   
  68. sbit LED_pin_F = P1^5;   
  69. sbit LED_pin_G = P1^6;   
  70. sbit LED_pin_H = P1^7;   
  71.   
  72. //Error_code_G = ERROR_SCH_TOO_MANY_TASKS;   
  73. //Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;   
  74. //Error_code_G = ERROR_SCH_WAITING_FOR_START_COMAND_FROM_MASTER;   
  75. //Error_code_G = ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START;   
  76. //Error_code_G = ERROR_SCH_LOST_SLAVE;   
  77. //Error_code_G = ERROR_SCH_CAN_BUS_ERROR;   
  78. //Error_code_G = ERROR_I2C_WRITE_BYTE_AT24C64;   
  79.   
  80. void main(void)   
  81. {   
  82.     SCH_Init_T2();   
  83.     LED_Flash_Init();   
  84.     SCH_Add_Task(LED_Flash_Update_A,0,1000);//添加一个任务   
  85.     SCH_Add_Task(LED_Flash_Update_B,0,2000);//添加一个任务   
  86.     SCH_Add_Task(LED_Flash_Update_C,0,3000);//添加一个任务   
  87.     SCH_Add_Task(LED_Flash_Update_D,0,4000);//添加一个任务   
  88.     SCH_Add_Task(LED_Flash_Update_E,0,5000);//添加一个任务   
  89.     SCH_Add_Task(LED_Flash_Update_F,0,6000);//添加一个任务   
  90.     SCH_Add_Task(LED_Flash_Update_G,0,7000);//添加一个任务   
  91.     SCH_Add_Task(LED_Flash_Update_H,0,8000);//添加一个任务   
  92.        
  93.     SCH_Start();//开全局中断   
  94.     while(1)   
  95.     {   
  96.         SCH_Dispatch_Tasks();   
  97.     }   
  98. }   
  99. /*------------------------------------------------------------  
  100. 这是调度器的中断服务程序,初始化函数中的定时器设置决定了它  
  101. 的调度频率,这个版本的调度器由定时器2触发中断,定时器自动重装。  
  102. -------------------------------------------------------------*/  
  103. void SCH_Update(void) interrupt INTERRPT_Timer_2_Overflow   
  104. {   
  105.     //刷新任务队列   
  106.     uchar Index;   
  107.     TF2 = 0;//必须手工清除   
  108.     //注意:计算单位为"时标"(不是毫秒)   
  109.     for(Index = 0;Index < SCH_MAX_TASKS;Index++)   
  110.     {   //检测这里是否有任务   
  111.         if(SCH_tasks_G[Index].pTask)   
  112.         {     
  113.             if(SCH_tasks_G[Index].Delay == 0)   
  114.             {   
  115.                 //任务需要运行,间隔的时间已经到了   
  116.                 if(SCH_tasks_G[Index].Co_op)   
  117.                 {   
  118.                     //如果是合作式任务,RunMe标志加1   
  119.                     SCH_tasks_G[Index].RunMe += 1;//要执行任务的标志加1   
  120.                 }   
  121.                 else//如果它是抢占式任务,立即运行它   
  122.                 {   
  123.                     (*SCH_tasks_G[Index].pTask)();//运行任务   
  124.                     SCH_tasks_G[Index].RunMe -= 1;   
  125.                     //周期性的任务将自动再次运行,单次任务就删除   
  126.                     if(SCH_tasks_G[Index].Period == 0)   
  127.                     {   
  128.                         SCH_tasks_G[Index].pTask = 0;   
  129.                     }   
  130.                 }       
  131.                 if(SCH_tasks_G[Index].Period)//时标间隔不等于0   
  132.                 {   
  133.                     //调度周期性的任务再次运行,每隔这个固定的时标长度执行一次任务   
  134.                     SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;   
  135.                 }   
  136.             }   
  137.             else //任务有延迟执行要求,还没到达延迟的时间   
  138.             {   
  139.                 //还没有准备好运行,延迟减1   
  140.                 SCH_tasks_G[Index].Delay -= 1;   
  141.             }   
  142.         }   
  143.     }   
  144. }   
  145.   
  146. void SCH_Init_T2(void)   
  147. {   
  148.     uchar i;   
  149.     for(i=0;i<SCH_MAX_TASKS;i++)   
  150.     {   
  151.         SCH_Delete_Task(i);   
  152.     }   
  153.     Error_code_G = 0;   
  154.     T2CON = 0x04;   
  155.     TMOD = 0x00;   
  156.     TH2   = 0xfc;   
  157.     RCAP2H = 0xfc;   
  158.     TL2   = 0x18;   
  159.     RCAP2L = 0x18;   
  160.     ET2   = 1;   
  161.     TR2   = 1;   
  162. }   
  163. /*----------------------------------------------------------------------------  
  164. 任务函数每隔一定时间间隔或在用户定义的延迟之后运行  
  165. pFunction -- 将被调用的函数名称。注意:被调函数必须是“void void”型  
  166. DELAY     -- 在任务第一次被执行之前的间隔  
  167. PERIOD    -- 如果它为0,则只调用该函数一次,由DELAY确定其调用的时间  
  168. 如果非0,那么它就是被重复调用的时间间隔  
  169. Co_op     -- 如果是合作式任务则设置为1,如果是抢占式任务则设置为0.  
  170.  
  171.   注意:如果以后要删除任务,将需要返回值  
  172.   例子:  
  173.   Task_ID = SCH_Add_Task(Do_X,1000,0,0);  
  174.   使函数Do_X()在1000个调度器时标之后运行一次(抢占式任务)   
  175.   Task_ID = SCH_Add_Task(Do_X,0,1000,1);  
  176.   使函数Do_X()每隔1000个调度器时标运行一次(合作式任务)  
  177.   Task_ID = SCH_Add_Task(Do_X,300,1000,0);  
  178.   使函数Do_X()每隔1000个调度器时标运行一次,任务首先在T=300个时标时被执行  
  179.   然后是1300个时标.........(抢占式任务)  
  180.     
  181. -----------------------------------------------------------------------------*/  
  182. uchar SCH_Add_Task(void (code * pFunction)(),const ushort DELAY, ushort PERIOD,bit Co_op)   
  183. {   
  184.     uchar Index = 0;   
  185.     //首先在队列中找到一个空隙(如果有的话,否则就不添加新任务)   
  186.     while((SCH_tasks_G[Index].pTask != 0)&&(Index < SCH_MAX_TASKS))   
  187.     {   
  188.         Index++;//当一个新任务被添加,且没有超过任务上限   
  189.     }   
  190.     //是否达到任务队列的结尾?   
  191.     if(Index == SCH_MAX_TASKS)//任务数量达到上限   
  192.     {   
  193.         Error_code_G = ERROR_SCH_TOO_MANY_TASKS;   
  194.         return SCH_MAX_TASKS;//直接返回,不添加这个新任务   
  195.     }   
  196.     //如果能运行到这里,说明任务队列中有空隙,添加任务。   
  197.     SCH_tasks_G[Index].pTask = pFunction;   
  198.     SCH_tasks_G[Index].Delay = DELAY;   
  199.     SCH_tasks_G[Index].Period = PERIOD;   
  200.     SCH_tasks_G[Index].Co_op = Co_op;   
  201.     SCH_tasks_G[Index].RunMe  = 0;   
  202.     return Index;//返回任务的位置(以便以后删除)   
  203. }   
  204.   
  205. void SCH_Dispatch_Tasks(void)   
  206. {   
  207.     uchar Index;   
  208.     //调度(运行)下一个任务(如果有任务就绪)   
  209.     for(Index = 0;Index < SCH_MAX_TASKS;Index++)   
  210.     {   
  211.         //只调度合作式任务   
  212.         if((SCH_tasks_G[Index].RunMe > 0)&&(SCH_tasks_G[Index].Co_op))   
  213.         {   
  214.             (*SCH_tasks_G[Index].pTask)();//执行任务   
  215.             SCH_tasks_G[Index].RunMe -= 1;//清除任务需要执行的标志   
  216.         }   
  217.         //如果这是个“单次”任务,将它从队列中删除   
  218.         if(SCH_tasks_G[Index].Period == 0)   
  219.         {   
  220.             SCH_tasks_G[Index].pTask = 0;// 比通过调用来删除任务更快SCH_Delete_Task(Index);   
  221.         }   
  222.     }   
  223.     SCH_Report_Status();//报告系统状况   
  224.     SCH_Go_To_Sleep();   
  225. }   
  226.   
  227. void SCH_Start(void)   
  228. {   
  229.     EA = 1;   
  230. }   
  231.   
  232. bit SCH_Delete_Task(const ushort TASK_INDEX)   
  233. {   
  234.     bit Return_code;   
  235.     if(SCH_tasks_G[TASK_INDEX].pTask == 0)   
  236.     {   
  237.         //这里没有任务。。。设置全局错误变量   
  238.         Error_code_G = ERROR_SCH_CANOT_DELETE_TASK;   
  239.         Return_code = RETURN_ERROR;//返回错误代码   
  240.     }   
  241.     else  
  242.     {   
  243.         Return_code = RETURN_NORMAL;   
  244.     }   
  245.     //删除任务   
  246.     SCH_tasks_G[TASK_INDEX].pTask = 0x0000;   
  247.     SCH_tasks_G[TASK_INDEX].Delay = 0;   
  248.     SCH_tasks_G[TASK_INDEX].Period = 0;   
  249.     SCH_tasks_G[TASK_INDEX].RunMe = 0;   
  250.     return Return_code;   
  251. }   
  252.   
  253. void SCH_Go_To_Sleep()   
  254. {   
  255.     PCON |= 0x01;//进入休眠模式   
  256. }   
  257.   
  258. void SCH_Report_Status(void)   
  259. {   
  260. /* #ifdef SCH_REPORT_ERRORS  
  261. if(Error_code_G != Last_error_code_G)  
  262. {  
  263. Error_Port = 255 - Error_code_G;  
  264. Last_error_code_G = Error_code_G;  
  265. if(Error_code_G != 0)  
  266. {  
  267. Error_tick_count_G = 60000;  
  268. }  
  269. else  
  270. {  
  271. Error_tick_count_G = 0;  
  272. }  
  273. }  
  274. else  
  275. {  
  276. if(Error_tick_count_G != 0)  
  277. {  
  278. if(--Error_count_G == 0)  
  279. {  
  280. Error_code_G = 0;  
  281. }  
  282. }  
  283. }  
  284. #endif    */  
  285. }   
  286.   
  287. void LED_Flash_Update_A(void)   
  288. {   
  289.     if(LED_State_G_A == 1)   
  290.     {   
  291.         LED_State_G_A = 0;   
  292.         LED_pin_A = 0;   
  293.     }   
  294.     else  
  295.     {   
  296.         LED_State_G_A = 1;   
  297.         LED_pin_A = 1;   
  298.     }   
  299. }   
  300.   
  301. void LED_Flash_Update_B(void)   
  302. {   
  303.     if(LED_State_G_B == 1)   
  304.     {   
  305.         LED_State_G_B = 0;   
  306.         LED_pin_B = 0;   
  307.     }   
  308.     else  
  309.     {   
  310.         LED_State_G_B = 1;   
  311.         LED_pin_B = 1;   
  312.     }   
  313. }   
  314.   
  315. void LED_Flash_Update_C(void)   
  316. {   
  317.     if(LED_State_G_C == 1)   
  318.     {   
  319.         LED_State_G_C = 0;   
  320.         LED_pin_C = 0;   
  321.     }   
  322.     else  
  323.     {   
  324.         LED_State_G_C = 1;   
  325.         LED_pin_C = 1;   
  326.     }   
  327. }   
  328. void LED_Flash_Update_D(void)   
  329. {   
  330.     if(LED_State_G_D == 1)   
  331.     {   
  332.         LED_State_G_D = 0;   
  333.         LED_pin_D = 0;   
  334.     }   
  335.     else  
  336.     {   
  337.         LED_State_G_D = 1;   
  338.         LED_pin_D = 1;   
  339.     }   
  340. }   
  341. void LED_Flash_Update_E(void)   
  342. {   
  343.     if(LED_State_G_E == 1)   
  344.     {   
  345.         LED_State_G_E = 0;   
  346.         LED_pin_E = 0;   
  347.     }   
  348.     else  
  349.     {   
  350.         LED_State_G_E = 1;   
  351.         LED_pin_E = 1;   
  352.     }   
  353. }   
  354. void LED_Flash_Update_F(void)   
  355. {   
  356.     if(LED_State_G_F == 1)   
  357.     {   
  358.         LED_State_G_F = 0;   
  359.         LED_pin_F = 0;   
  360.     }   
  361.     else  
  362.     {   
  363.         LED_State_G_F = 1;   
  364.         LED_pin_F = 1;   
  365.     }   
  366. }   
  367. void LED_Flash_Update_G(void)   
  368. {   
  369.     if(LED_State_G_G == 1)   
  370.     {   
  371.         LED_State_G_G = 0;   
  372.         LED_pin_G = 0;   
  373.     }   
  374.     else  
  375.     {   
  376.         LED_State_G_G = 1;   
  377.         LED_pin_G = 1;   
  378.     }   
  379. }   
  380. void LED_Flash_Update_H(void)   
  381. {   
  382.     if(LED_State_G_H == 1)   
  383.     {   
  384.         LED_State_G_H = 0;   
  385.         LED_pin_H = 0;   
  386.     }   
  387.     else  
  388.     {   
  389.         LED_State_G_H = 1;   
  390.         LED_pin_H = 1;   
  391.     }   
  392. }   
  393.   
  394. void LED_Flash_Init(void)   
  395. {   
  396.     LED_State_G_A= 0;//初始化LED状态   
  397.     LED_State_G_B= 0;//初始化LED状态   
  398.     LED_State_G_C= 0;//初始化LED状态   
  399. }   

 

 
相关文章:

 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4