|
最近打算使用个小的调度器在8为单片机上,看论坛“小小调度器”不错,打算使用,只是有些没看明白,请大家不吝赐教,如果回答解决了问题,送出40莫元聊表谢意
小小调度器的源码如下:
- #include <stc89c51.h>
- /****小小调度器开始**********************************************/
- #define MAXTASKS 3
- volatile unsigned char timers[MAXTASKS];
- #define _SS static unsigned char _lc=0; switch(_lc){default:
- #define _EE ;}; _lc=0; return 255;
- #define WaitX(tickets) do {_lc=(__LINE__%255)+1; return tickets ;} while(0); case (__LINE__%255)+1:
- #define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); } while(0);
- #define RunTaskA(TaskName,TaskID) { if (timers[TaskID]==0) {timers[TaskID]=TaskName(); continue;} } //前面的任务优先保证执行
- #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);
- #define InitTasks() {unsigned char i; for(i=MAXTASKS;i>0 ;i--) timers[i-1]=0; }
- #define UpdateTimers() {unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}}
- #define SEM unsigned int
- //初始化信号量
- #define InitSem(sem) sem=0;
- //等待信号量
- #define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
- //等待信号量或定时器溢出, 定时器tickets 最大为0xFFFE
- #define WaitSemX(sem,tickets) do { sem=tickets+1; WaitX(0); if(sem>1){ sem--; return 1;} } while(0);
- //发送信号量
- #define SendSem(sem) do {sem=0;} while(0);
- /*****小小调度器结束*******************************************************/
- sbit LED1 = P2^1;
- sbit LED2 = P2^2;
- sbit LED0 = P2^5;
- unsigned char task0(){
- _SS
- while(1){
- WaitX(50);
- LED0=!LED0;
- }
- _EE
- }
- unsigned char task1(){
- _SS6
- while(1){
- WaitX(100);
- LED1=!LED1;
- }
- _EE
- }
- unsigned char task2(){
- _SS
- while(1){
- WaitX(100);
- LED2=!LED2;
- }
- _EE
- }
- void InitT0()
- {
- TMOD = 0x21;
- IE |= 0x82;
- TL0=0Xff;
- TH0=0XDB;
- TR0 = 1;
- }
- void INTT0(void) interrupt 1 using 1
- {
- TL0=0Xff; //10ms 重装
- TH0=0XDB;
- UpdateTimers();
- RunTask(task0,0);//任务0具有精确按时获得执行的权限,要求:task0每次执行消耗时间<0.5个 ticket
- }
- void main()
- {
- InitT0();
- InitTasks(); //初始化任务,实际上是给timers清零
- while(1){
- // RunTask(task0,0);
- RunTaskA(task1,1);//任务1具有比任务2高的运行权限
- RunTaskA(task2,2);//任务2具有低的运行权限
- }
- }
复制代码
1. 调度器 _EE ;}; _lc=0; return 255; 这里应该是任务执行完了后返回255,这个255会写到任务的Timers[TaskID]数组中,定时器中断调用UpdateTimers时,检查到这个255不会减1,那么下一次任务就得不到运行啊?(任务运行的条件是Timers[TaskID]=0),我的理解应该是Return 0啊,我的理解到底错在哪里?
2. 任务宏如下:
- unsigned char task0(){
- _SS
- while(1){
- WaitX(50);
- LED0=!LED0;
- }
- _EE
- }
复制代码
任务宏定义展开如下:
- unsigned char task0()
- {
- static unsigned char _lc=0;
- switch(_lc)
- {
- default:
- while(1)
- {
- do {
- _lc=(__LINE__%255)+1;
- return 50 ;
- } while(0);
- case (__LINE__%255)+1:
- LED0=!LED0;
- }
- ;
- }
- ;
- _lc=0;
- return 255;
- }
复制代码
我觉得任务中不需要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调用没啥区别,我的理解对吗? |
|