美文网首页
Arduino时间片轮转

Arduino时间片轮转

作者: ww4u | 来源:发表于2020-12-30 18:24 被阅读0次
    • 同等地位的N个任务
    • 每个任务有固定的执行间隔
    • 典型的Arduino模式


      setup-loop
    • 将loop进行中的任务进行拆分,设定调用时间周期


      时间片
      • 适用于运行周期不同的任务,周期相对比较准确
      • 任务不能阻塞
      • 每次调用都是同一个入口,也就是说一次调用是全部完成返回的
      • 执行任务从时间上分散后可以增加“实时任务”的及时性
    分散任务
    #ifndef TASK_H
    #define TASK_H
    
    typedef void (*P_VOID_void)();
    
    class Task{
      
    private:
      int mPeri;
      volatile int mTick;
      P_VOID_void mProc;
      
    public:
      Task( P_VOID_void proc, int peri=10 )
      { 
        mPeri = peri;
        mTick = peri; 
        mProc = proc;
      }
    
      void run()
      {
        if ( mTick <= 0 )
        {
          mTick = mPeri;
          mProc();
        }
      }
    
      void tick()
      {
        if ( mTick > 0 )
        { mTick--; }
      }
    };
    
    #define MAX_TASK_CNT 8
    
    class Schedule
    {
    private:
      Task * mTasks[MAX_TASK_CNT];
      int mTaskCnt;
      
    public:
      Schedule()
      {
        mTaskCnt = 0;
      }  
      
      void start()
      {
          TCCR1A = 0;          // normal operation
          TCCR1B = bit(WGM12) | bit(CS10) | bit(CS12);   // CTC, 1024
          OCR1A =  999;       // compare A register value (1000 * clock speed)
          TIMSK1 = bit (OCIE1A);             // interrupt on Compare A Match
      }
    
      void run()
      {
          int i;
    
          for ( i = 0; i < mTaskCnt; i++ )
          {
            mTasks[i]->run();
          }
      }
    
      void tick()
      {
          int i;
    
          for ( i = 0; i < mTaskCnt; i++ )
          {
            mTasks[i]->tick();
          }
      }
    
    public:
      void attachTask( Task *pTask )
      {
        mTasks[ mTaskCnt ] = pTask;
        mTaskCnt++;
      } 
    };
    
    Schedule _schedule;
    
    ISR(TIMER1_COMPA_vect)
    {
      _schedule.tick();
    }
    
    #endif 
    
    • 使用方法
    #include <Task.h>
    void task1()
    {
      Serial.println("task1 "+String( millis() ));
    }
    
    void task2()
    {
      Serial.println("task2 "+String( millis() ));
    }
    
    Task _task1( task1, 60 );
    Task _task2( task2, 120 );
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
    
      _schedule.attachTask( &_task1 );
      _schedule.attachTask( &_task2 );
    
      _schedule.start();
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      _schedule.run();
    }
    

    模块的添加方法

    • /libraries/模块名称
    • /libraries/模块名称/src中放置源码
    • /libraries/模块名称/library.properties进行模块描述

    相关文章

      网友评论

          本文标题:Arduino时间片轮转

          本文链接:https://www.haomeiwen.com/subject/yaghoktx.html