#define AP_HAL_MAIN() \
AP_HAL::HAL::FunCallbacks callbacks(setup, loop); \
extern "C" { \
int AP_MAIN(int argc, char* const argv[]); \
int AP_MAIN(int argc, char* const argv[]) { \
hal.run(argc, argv, &callbacks); \
return 0; \
} \
}
#define AP_HAL_MAIN_CALLBACKS(CALLBACKS) extern "C" { \
hal.run(argc, argv, CALLBACKS); \
virtual void run(int argc, char * const argv[], Callbacks* callbacks) const = 0; HAL.h
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
class HAL_ChibiOS : public AP_HAL::HAL HAL_ChibiOS_class.cpp
{
}
class HAL
struct Callbacks
{
virtual void setup() = 0;
virtual void loop() = 0;
};
}
static AP_HAL::HAL::Callbacks* g_callbacks;
HAL_ChibiOS::run(int argc, char * const argv[], Callbacks* callbacks)
{
g_callbacks = callbacks;
//Takeover main
main_loop();
main_loop()
hal.scheduler->init(); //AP_HAL::Scheduler* scheduler; class AP_HAL::Scheduler {}
g_callbacks->setup();
while (true)
g_callbacks->loop();
}
class AP_Vehicle : public AP_HAL::HAL::Callbacks
void setup(void) override final;
// HAL::Callbacks implementation.
void loop() override final;
void AP_Vehicle::setup()
hal.console->printf("\n\nInit %s"
"\n\nFree RAM: %u\n",
AP::fwversion().fw_string,
(unsigned)hal.util->available_memory());
const AP_Scheduler::Task *tasks;
uint8_t task_count;
uint32_t log_bit;
get_scheduler_tasks(tasks, task_count, log_bit);
AP::scheduler().init(tasks, task_count, log_bit);
init_ardupilot();
void AP_Vehicle::loop()
scheduler.loop();
G_Dt = scheduler.get_loop_period_s();
virtual void get_scheduler_tasks(const AP_Scheduler::Task *&tasks, uint8_t &task_count, uint32_t &log_bit) = 0; AP_Verticle.h
void Copter::get_scheduler_tasks(const AP_Scheduler::Task *&tasks,
uint8_t &task_count,
uint32_t &log_bit)
tasks = &scheduler_tasks[0];
task_count = ARRAY_SIZE(scheduler_tasks);
log_bit = MASK_LOG_PM;
// \libraries\AP_HAL\utility/function.h
#define FUNCTOR_TYPEDEF(name, rettype, ...) \
typedef Functor<rettype, ## __VA_ARGS__> name
#define FUNCTOR_DECLARE(name, rettype, ...) \
Functor<rettype, ## __VA_ARGS__> name
#define FUNCTOR_BIND(obj, func, rettype, ...) \
Functor<rettype, ## __VA_ARGS__>::bind<std::remove_reference<decltype(*obj)>::type, func>(obj)
#define FUNCTOR_BIND_MEMBER(func, rettype, ...) \
Functor<rettype, ## __VA_ARGS__>::bind<std::remove_reference<decltype(*this)>::type, func>(this)
//constructor
AP_Scheduler::AP_Scheduler(scheduler_fastloop_fn_t fastloop_fn) :
_fastloop_fn(fastloop_fn)
AP_Scheduler scheduler{FUNCTOR_BIND_MEMBER(&AP_Vehicle::fast_loop, void)}; AP_Vehicle.h
Functor<void>::bind<&AP_Scheduler,&AP_Vehicle::fast_loop>
return {obj,(void)AP_Vehicle::fast_loop}
template <class RetType, class... Args>
class Functor
template<class T, RetType (T::*method)(Args...)>
static constexpr Functor bind(T *obj)
{
return { obj, method_wrapper<T, method> };
static RetType method_wrapper(void *obj, Args... args)
T *t = static_cast<T*>(obj);
return (t->*method)(args...);
virtual void fast_loop();
void Copter::fast_loop()
AP_Vehicle::fast_loop();
class Copter : public AP_Vehicle
Copter copter;
AP_HAL_MAIN_CALLBACKS(&copter);
展開是
int main(int argc, char* const argv[]);
int main(int argc, char* const argv[])
hal.run(argc, argv, &copter);
return 0;