×
嵌入式 > 技术百科 > 详情

极小资源单片机调度器

发布时间:2020-06-15 发布时间:
|
版本一、
 
  1.  
  2. /****小小调度器开始**********************************************/
  3. #define MAXTASKS 2
  4. static unsigned char timers[MAXTASKS];
  5. unsigned char currdt;
  6. #define _SS static unsigned char _lc; switch(_lc){default: 
  7. #define _EE ;}; _lc=0; return 255;
  8. #define WaitX(tickets)  do {_lc=__LINE__+((__LINE__%256)==0); return tickets ;} while(0); case __LINE__+((__LINE__%256)==0): 
  9. #define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); }  while(0);
  10.  
  11. #define CallSub(SubTaskName) do { _lc=__LINE__+((__LINE__%256)==0); return 0; case __LINE__+((__LINE__%256)==0):  currdt=SubTaskName(); if(currdt!=255) return currdt;} while(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.  
  14. #define SEM unsigned int 
  15. //初始化信号量
  16. #define InitSem(sem) sem=0;
  17. //等待信号量
  18. #define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
  19. //等待信号量或定时器溢出, 定时器tickets 最大为0xFFFE
  20. #define WaitSemX(sem,tickets)  do { sem=tickets+1; WaitX(0); if(sem>1){ sem--;  return 1;} } while(0);
  21. //发送信号量
  22. #define SendSem(sem)  do {sem=0;} while(0);
  23.  
  24. /*****小小调度器结束*******************************************************/
  25.  
  26. sbit LED1 = P2^1;
  27. sbit LED2 = P2^2;
  28.  
  29. void InitT0()
  30. {
  31.         TMOD = 0x21;
  32.         IE |= 0x82;  // 12t
  33.         TL0=0Xff;
  34.         TH0=0XDB;//22M---b7;
  35.         TR0 = 1;
  36. }
  37.  
  38. void INTT0(void) interrupt 1 using 1
  39. {
  40.     UpdateTimers();
  41.  
  42.     TL0=0Xff;    //10ms 重装
  43.     TH0=0XDB;//b7;    
  44. }
  45.  
  46.  
  47. void  task1(){
  48. _SS
  49.   while(1){
  50.    WaitX(50);
  51.    LED1=!LED1;   
  52.   }
  53. _EE
  54. }
  55.  
  56. void  task2(){
  57. _SS
  58.   while(1){
  59.    WaitX(100);
  60.    LED2=!LED2;   
  61.   }
  62. _EE
  63. }
  64.  
  65.  
  66. void main()
  67. {
  68.         InitT0();
  69.         while(1){
  70.            RunTask(task1,0);
  71.            RunTask(task2,1);
  72.     }
  73. }
 
 
版本二、
 
在IAR6.7下编译通过。(选用:Misra C 2004)

/****小小调度器开始**********************************************/
#define MAXTASKS 3U
volatile static unsigned char timers[MAXTASKS];
#define _SS    static unsigned char _lc=0U; switch(_lc){case 0U:  
#define _EE     break; default:break;}  _lc=0U;  return 255U;
#define WaitX(tickets)   _lc=(unsigned char)(__LINE__)%255U+1U;  if(_lc){return (tickets);}  break; case ((unsigned char)(__LINE__)%255U)+1U: 

#define RunTask(TaskName,TaskID)  do {if (timers[(TaskID)]==0U){ timers[(TaskID)]=(TaskName)(); } } while(0)  
#define RunTaskA(TaskName,TaskID) { if (timers[(TaskID)]==0U) {timers[(TaskID)]=(TaskName)(); continue;} }    /*前面的任务优先保证执行*/

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

#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);

/*****小小调度器结束*******************************************************/


static unsigned char task0(void){
  static int i;  
_SS
  for(i=0;i<11;i++){    
    WaitX(10U);
  }  
_EE
}

static unsigned char task1(void){
    
_SS
  while(1){    
    WaitX(10U);
  }  
_EE
}

static unsigned char task2(void){
    
_SS
  while(1){    
    WaitX(10U);   
  }  
_EE
}

void InitT0()
{
        TMOD = 0x21;
        IE |= 0x82;  // 12t
        TL0=0Xff;
        TH0=0XDB;
        TR0 = 1;
}

void INTT0(void) interrupt 1 using 1
{
    TL0=0Xff;    //10ms 重装
    TH0=0XDB;//b7;    
    UpdateTimers();

    RunTask(task0,0);//任务0具有精确按时获得执行的权限,要求:task0每次执行消耗时间<0.5个 ticket
}

int main(void)
{
  InitT0();
  InitTasks(); 
  while(1){    
    RunTaskA(task1,1);  //任务一具有比任务二优先执行的权限
    RunTaskA(task2,2);  
  } 
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ADI 高精度低功耗精密放大器