. 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 }