代码起步是从ArduCopter.cpp里的展开
AP_HAL_MAIN_CALLBACKS(&copter);
传入的参数是Copter.h
extern Copter copter;
用extern 指向Copter.cpp里
Copter copter;
注意Copter继承自Callbacks
class Copter : public AP_HAL::HAL::Callbacks {
ArduCopter 文件夹下 ArduCopter.cpp
#ifndef AP_MAIN
#define AP_MAIN main
#endif
#define AP_HAL_MAIN_CALLBACKS(CALLBACKS) extern "C" { \
int AP_MAIN(void); \
int AP_MAIN(void) { \
hal.run(0, NULL, CALLBACKS); \
return 0; \
} \
}
AP_HAL_MAIN_CALLBACKS(&copter);
这里的hal是Copter.h用external声明,但是在Copter.cpp里获得,
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
AP_HAL_LINUX 文件夹下 HAL_Linux_Class.cpp
void HAL_Linux::run(int argc, char* const argv[], Callbacks* callbacks) const
{
...
}
const AP_HAL::HAL& AP_HAL::get_HAL() {
static const HAL_Linux hal;
return hal;
}
所以函数最终是在HAL_Linux::run下执行各种初始化,最后进入callbacks->loop
实际上是进入了传入的Copter::loop(),从而进一步进入scheduler调度各种在ArduCopter里设置的TASK
// Execute the fast loop
// ---------------------
fast_loop();
// tell the scheduler one tick has passed
scheduler.tick();
// run all the tasks that are due to run. Note that we only
// have to call this once per loop, as the tasks are scheduled
// in multiples of the main loop tick. So if they don't run on
// the first call to the scheduler they won't run on a later
// call until scheduler.tick() is called again
uint32_t time_available = (timer + MAIN_LOOP_MICROS) - micros();
scheduler.run(time_available);
即以下任务
const AP_Scheduler::Task Copter::scheduler_tasks[] = {
SCHED_TASK(rc_loop, 4, 130),
SCHED_TASK(throttle_loop, 8, 75),
SCHED_TASK(update_GPS, 8, 200),
#if OPTFLOW == ENABLED
SCHED_TASK(update_optical_flow, 2, 160),
#endif
SCHED_TASK(update_batt_compass, 40, 120),
SCHED_TASK(read_aux_switches, 40, 50),
SCHED_TASK(arm_motors_check, 40, 50),
SCHED_TASK(auto_disarm_check, 40, 50),
SCHED_TASK(auto_trim, 40, 75),
SCHED_TASK(update_altitude, 40, 140),
SCHED_TASK(run_nav_updates, 8, 100),
SCHED_TASK(update_thr_average, 4, 90),
SCHED_TASK(three_hz_loop, 133, 75),
SCHED_TASK(compass_accumulate, 4, 100),
SCHED_TASK(barometer_accumulate, 8, 90),
#if PRECISION_LANDING == ENABLED
SCHED_TASK(update_precland, 8, 50),
#endif
#if FRAME_CONFIG == HELI_FRAME
SCHED_TASK(check_dynamic_flight, 8, 75),
#endif
SCHED_TASK(update_notify, 8, 90),
SCHED_TASK(one_hz_loop, 400, 100),
SCHED_TASK(ekf_check, 40, 75),
SCHED_TASK(landinggear_update, 40, 75),
SCHED_TASK(lost_vehicle_check, 40, 50),
SCHED_TASK(gcs_check_input, 1, 180),
SCHED_TASK(gcs_send_heartbeat, 400, 110),
SCHED_TASK(gcs_send_deferred, 8, 550),
SCHED_TASK(gcs_data_stream_send, 8, 550),
SCHED_TASK(update_mount, 8, 75),
SCHED_TASK(ten_hz_logging_loop, 40, 350),
SCHED_TASK(fifty_hz_logging_loop, 8, 110),
SCHED_TASK(full_rate_logging_loop, 1, 100),
SCHED_TASK(dataflash_periodic, 1, 300),
SCHED_TASK(perf_update, 4000, 75),
SCHED_TASK(read_receiver_rssi, 40, 75),
SCHED_TASK(rpm_update, 40, 200),
SCHED_TASK(compass_cal_update, 4, 100),
#if FRSKY_TELEM_ENABLED == ENABLED
SCHED_TASK(frsky_telemetry_send, 80, 75),
#endif
#if EPM_ENABLED == ENABLED
SCHED_TASK(epm_update, 40, 75),
#endif
#ifdef USERHOOK_FASTLOOP
SCHED_TASK(userhook_FastLoop, 4, 75),
#endif
#ifdef USERHOOK_50HZLOOP
SCHED_TASK(userhook_50Hz, 8, 75),
#endif
#ifdef USERHOOK_MEDIUMLOOP
SCHED_TASK(userhook_MediumLoop, 40, 75),
#endif
#ifdef USERHOOK_SLOWLOOP
SCHED_TASK(userhook_SlowLoop, 120, 75),
#endif
#ifdef USERHOOK_SUPERSLOWLOOP
SCHED_TASK(userhook_SuperSlowLoop, 400, 75),
#endif
};
scheduler->run() 是AP_Scheduler.cpp里的
void AP_Scheduler::run(uint16_t time_available)
{
最后它读取任务表(tasks),并调度执行:
_task_time_started = now;
task_fn_t func;
pgm_read_block(&_tasks[i].function, &func, sizeof(func));
current_task = i;
func();
current_task = -1;