|
|
|
@ -24,6 +24,15 @@
@@ -24,6 +24,15 @@
|
|
|
|
|
#include <AP_HAL/AP_HAL.h> |
|
|
|
|
#include <AP_Param/AP_Param.h> |
|
|
|
|
#include <AP_Progmem/AP_Progmem.h> |
|
|
|
|
#include <AP_Vehicle/AP_Vehicle.h> |
|
|
|
|
|
|
|
|
|
#if APM_BUILD_TYPE(APM_BUILD_ArduCopter) |
|
|
|
|
#define SCHEDULER_DEFAULT_LOOP_RATE 400 |
|
|
|
|
#define SCHEDULER_EXPOSE_LOOP_RATE_PARAMETER 0 |
|
|
|
|
#else |
|
|
|
|
#define SCHEDULER_DEFAULT_LOOP_RATE 50 |
|
|
|
|
#define SCHEDULER_EXPOSE_LOOP_RATE_PARAMETER 1 |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
extern const AP_HAL::HAL& hal; |
|
|
|
|
|
|
|
|
@ -36,9 +45,39 @@ const AP_Param::GroupInfo AP_Scheduler::var_info[] = {
@@ -36,9 +45,39 @@ const AP_Param::GroupInfo AP_Scheduler::var_info[] = {
|
|
|
|
|
// @Values: 0:Disabled,2:ShowSlips,3:ShowOverruns
|
|
|
|
|
// @User: Advanced
|
|
|
|
|
AP_GROUPINFO("DEBUG", 0, AP_Scheduler, _debug, 0), |
|
|
|
|
|
|
|
|
|
#if SCHEDULER_EXPOSE_LOOP_RATE_PARAMETER |
|
|
|
|
// @Param: LOOP_RATE
|
|
|
|
|
// @DisplayName: Scheduling main loop rate
|
|
|
|
|
// @Description: This controls the rate of the main control loop in Hz. This should only be changed by developers. This only takes effect on restart
|
|
|
|
|
// @Values: 50:50Hz,100:100Hz,200:200Hz,400:400Hz
|
|
|
|
|
// @RebootRequired: True
|
|
|
|
|
// @User: Advanced
|
|
|
|
|
AP_GROUPINFO("LOOP_RATE", 1, AP_Scheduler, _loop_rate_hz, SCHEDULER_DEFAULT_LOOP_RATE), |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
AP_GROUPEND |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// constructor
|
|
|
|
|
AP_Scheduler::AP_Scheduler(void) |
|
|
|
|
{ |
|
|
|
|
_loop_rate_hz.set_default(SCHEDULER_DEFAULT_LOOP_RATE); |
|
|
|
|
AP_Param::setup_object_defaults(this, var_info); |
|
|
|
|
|
|
|
|
|
// only allow specific values of main loop rate. This code is not
|
|
|
|
|
// setup for arbitrary rates yet
|
|
|
|
|
if (_loop_rate_hz <= 50) { |
|
|
|
|
_loop_rate_hz.set(50); |
|
|
|
|
} else if (_loop_rate_hz <= 100) { |
|
|
|
|
_loop_rate_hz.set(100); |
|
|
|
|
} else if (_loop_rate_hz <= 200) { |
|
|
|
|
_loop_rate_hz.set(200); |
|
|
|
|
} else { |
|
|
|
|
_loop_rate_hz.set(400); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// initialise the scheduler
|
|
|
|
|
void AP_Scheduler::init(const AP_Scheduler::Task *tasks, uint8_t num_tasks)
|
|
|
|
|
{ |
|
|
|
@ -66,7 +105,10 @@ void AP_Scheduler::run(uint16_t time_available)
@@ -66,7 +105,10 @@ void AP_Scheduler::run(uint16_t time_available)
|
|
|
|
|
|
|
|
|
|
for (uint8_t i=0; i<_num_tasks; i++) { |
|
|
|
|
uint16_t dt = _tick_counter - _last_run[i]; |
|
|
|
|
uint16_t interval_ticks = pgm_read_word(&_tasks[i].interval_ticks); |
|
|
|
|
uint16_t interval_ticks = _loop_rate_hz / _tasks[i].rate_hz; |
|
|
|
|
if (interval_ticks < 1) { |
|
|
|
|
interval_ticks = 1; |
|
|
|
|
} |
|
|
|
|
if (dt >= interval_ticks) { |
|
|
|
|
// this task is due to run. Do we have enough time to run it?
|
|
|
|
|
_task_time_allowed = pgm_read_word(&_tasks[i].max_time_micros); |
|
|
|
|