APM principle task scheduler analysis

  . 1  the APM Scheduler analysis
   2  
  . 3  void AP_Scheduler :: RUN (uint32_t time_available)
   . 4  {
   . 5      uint32_t run_started_usec = AP_HAL :: Micros ();
   . 6      uint32_t now = run_started_usec;
   . 7  
  . 8      for (uint8_t I = 0 ; I <_num_tasks; I ++ ) {
   9          // dt represents the current task has scheduled a number of cycle 
10          uint16_t dt = _tick_counter - _last_run [i];
 11  
12          // interval_ticks on behalf of this task requires the number of cycles to run scheduled
 13          // If the task scheduling period (_loop_rate_hz) provided 50hz, a schedule that is 20ms, _tick_counter + 1
14          // If a task is arranged to run 10hz, i.e. 100ms run time, the need for 50hz / 10hz = 5 times scheduled, this task can be run once 
15          uint16_t interval_ticks = _loop_rate_hz / _tasks [I] .rate_hz;
 16  
. 17          // If the scheduling times is less than 1, that is to say the frequency scheduling faster than _loop_rate_hz, scheduling only one
 18          // herein by limiting the fastest frequency _loop_rate_hz task scheduling 
. 19          IF (interval_ticks < 1 ) { 
 20 is              interval_ticks = 1 ;
 21          }
 22 is  
23 is          // If dt> = interval_ticks, representing the current has reached the desired task scheduling period, can be scheduled 
24          IF (dt> = interval_ticks) {
 25              //_task_time_allowed represents the current maximum allowed time task to be run
 26              // this time there is no egg is used in this scheduling strategy, purely tasteless! ! !
27              // Sorry, it is not totally tasteless, his role is reflected in the remaining time when the scheduler is enough task the maximum time required for the current
 28              
29              // the this IS Task Due to RUN. Time enough to have have the Do WE RUN IT? 
30              _task_time_allowed = _tasks [I] .max_time_micros;
 31 is  
32              // required for the current scheduling period more than twice the time required, the representative of the present task should be executed, but is delayed by
 33              @ here without doing any treatment, but it did debugging output
 34              // so even if you have specified for each task scheduling his frequency, but a desired value, he affected the whole system scheduling, real-time he is uncertain 
35              IF (dt> = * interval_ticks 2 ) {
 36                  // we've slipped a whole run of this task!
 37                 if (_debug > 4) {
 38                     ::printf("Scheduler slip task[%u-%s] (%u/%u/%u)\n",
 39                              (unsigned)i,
 40                              _tasks[i].name,
 41                              (unsigned)dt,
 42                              (unsigned)interval_ticks,
 43                              (unsigned)_task_time_allowed);
 44                 }
 45             }
 46 
 47             //time_available representing the current remaining time how much the scheduler is further to schedule task
 48       // time_available = 1000000 / 20ms _loop_rate_hz =
 49              // if the current task is the maximum allowable time for a single run is smaller than the remaining time, there is sufficient proof system his time to run, then you can run this task
 50              // otherwise jump out and continue in rotation the next time the task list, a chance to see who was executed 
51              IF (_task_time_allowed <= time_available) {
 52                  // rUN IT
 53                  / / note of the currently running task starting time 
54 is                  _task_time_started = now;
 55                  current_task = I;
 56 is                  _tasks [I] .function ();
 57 is                  current_task = - . 1 ;
 58 
59                  // Update the current tick after the completion of the task runs, is calculated for the next time dt preparation
 60                  // Record The tick counter When WE RAN This Drives.
 61 is                  // When WE RUN The Next Event 
62 is                  _last_run [I] = _tick_counter;
 63 is  
64-                  // Work oUT How Long at the Event Actually Took 
65                  now = AP_HAL :: Micros ();
 66                  // calculate the current task running time of 
67                  uint32_t TIME_TAKEN = now - _task_time_started;
 68  
69                  // If the current task is running longer than the maximum time allowed, representing the current task has been overrun
 70                  // here just to do a printout, and no egg with 
71                 if (time_taken > _task_time_allowed) {
 72                     // the event overran!
 73                     if (_debug > 4) {
 74                         ::printf("Scheduler overrun task[%u-%s] (%u/%u)\n",
 75                                  (unsigned)i,
 76                                  _tasks[i].name,
 77                                  (unsigned)time_taken,
 78                                  (unsigned)_task_time_allowed);
 79                     }
 80                 }
 81                 //If the currently running task scheduler time has exceeded the time remaining, then the task list scheduling exit
 82   // but behind the front is not the task is scheduled tasks 
83                  IF (TIME_TAKEN> = time_available) {
 84                      GOTO update_spare_ticks;
 85                  }
 86                  // the scheduler updates the remaining time available, if the current task overrun, then the next task may not perform a 
87                  time_available - = TIME_TAKEN;
 88              }
 89          }
 90      }
 91 is  
92      // update Number of Spare microseconds 
93      _spare_micros + = time_available;
 94  
95  update_spare_ticks:
 96     _spare_ticks++;
 97     if (_spare_ticks == 32) {
 98         _spare_ticks /= 2;
 99         _spare_micros /= 2;
100     }
101 }

 

Guess you like

Origin www.cnblogs.com/jingjin666/p/11131255.html