mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-03-27 09:33:51 +08:00
module_base: remove CRTP template pattern to reduce flash bloat (#26476)
* module_base: claude rewrite to remove CRTP bloat * module_base: apply to all drivers/modules * format * fix build errors * fix missing syntax * remove reference to module.h in files that need module_base.h * remove old ModuleBase<T> * add module_base.cpp to px4_protected_layers.cmake * fix IridiumSBD can_stop() * fix IridiumSBD.cpp * clang-tidy: downcast static cast * get_instance() template accessor, revert clang-tidy global * rename module_base.h to module.h * revert changes in zenoh/Kconfig.topics
This commit is contained in:
@@ -43,6 +43,8 @@
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <drivers/drv_io_heater.h>
|
||||
|
||||
ModuleBase::Descriptor Core_Heater::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
# ifndef GPIO_CORE_HEATER_OUTPUT
|
||||
# error "To use the heater driver, the board_config.h must define and initialize GPIO_CORE_HEATER_OUTPUT"
|
||||
# endif
|
||||
@@ -62,7 +64,7 @@ Core_Heater::~Core_Heater()
|
||||
int Core_Heater::custom_command(int argc, char *argv[])
|
||||
{
|
||||
// Check if the driver is running.
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
PX4_INFO("not running");
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -117,7 +119,7 @@ bool Core_Heater::initialize_topics()
|
||||
void Core_Heater::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -216,8 +218,8 @@ int Core_Heater::task_spawn(int argc, char *argv[])
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
_object.store(core_heater);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(core_heater);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
core_heater->start();
|
||||
return 0;
|
||||
@@ -257,5 +259,5 @@ Background process running periodically on the LP work queue to regulate IMU tem
|
||||
|
||||
extern "C" __EXPORT int core_heater_main(int argc, char *argv[])
|
||||
{
|
||||
return Core_Heater::main(argc, argv);
|
||||
return ModuleBase::main(Core_Heater::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -56,9 +56,11 @@ using namespace time_literals;
|
||||
#define CONTROLLER_PERIOD_DEFAULT 10000
|
||||
#define TEMPERATURE_TARGET_THRESHOLD 2.5f
|
||||
|
||||
class Core_Heater : public ModuleBase<Core_Heater>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
class Core_Heater : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
Core_Heater();
|
||||
|
||||
virtual ~Core_Heater();
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
#include "NavioRGBLed.hpp"
|
||||
|
||||
ModuleBase::Descriptor NavioRGBLed::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
NavioRGBLed::NavioRGBLed() :
|
||||
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::lp_default)
|
||||
{
|
||||
@@ -130,8 +132,8 @@ int NavioRGBLed::task_spawn(int argc, char *argv[])
|
||||
NavioRGBLed *instance = new NavioRGBLed();
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init() == PX4_OK) {
|
||||
return PX4_OK;
|
||||
@@ -142,8 +144,8 @@ int NavioRGBLed::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -170,5 +172,5 @@ Emlid Navio2 RGB LED driver.
|
||||
|
||||
extern "C" __EXPORT int navio_rgbled_main(int argc, char *argv[])
|
||||
{
|
||||
return NavioRGBLed::main(argc, argv);
|
||||
return ModuleBase::main(NavioRGBLed::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -40,9 +40,11 @@
|
||||
|
||||
#include <lib/led/led.h>
|
||||
|
||||
class NavioRGBLed : public ModuleBase<NavioRGBLed>, public px4::ScheduledWorkItem
|
||||
class NavioRGBLed : public ModuleBase, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
NavioRGBLed();
|
||||
~NavioRGBLed() override;
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
ModuleBase::Descriptor GhstRc::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
uint32_t GhstRc::baudrate = GHST_BAUDRATE;
|
||||
|
||||
GhstRc::GhstRc(const char *device) :
|
||||
@@ -114,8 +116,8 @@ int GhstRc::task_spawn(int argc, char *argv[])
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
instance->ScheduleNow();
|
||||
|
||||
@@ -174,7 +176,7 @@ void GhstRc::Run()
|
||||
if (should_exit()) {
|
||||
ScheduleClear();
|
||||
_rc_fd = -1;
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,5 +310,5 @@ This module parses the GHST RC uplink protocol and can generate GHST downlink te
|
||||
|
||||
extern "C" __EXPORT int ghst_rc_main(int argc, char *argv[])
|
||||
{
|
||||
return GhstRc::main(argc, argv);
|
||||
return ModuleBase::main(GhstRc::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -54,9 +54,11 @@
|
||||
|
||||
#define GHST_MAX_NUM_CHANNELS (16)
|
||||
|
||||
class GhstRc : public ModuleBase<GhstRc>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
class GhstRc : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
GhstRc(const char *device);
|
||||
~GhstRc() override;
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
|
||||
#include "rc_controller.hpp"
|
||||
|
||||
ModuleBase::Descriptor RC_ControllerModule::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
int RC_ControllerModule::print_status()
|
||||
{
|
||||
PX4_INFO("Running");
|
||||
@@ -69,35 +71,35 @@ int RC_ControllerModule::print_status()
|
||||
|
||||
int RC_ControllerModule::custom_command(int argc, char *argv[])
|
||||
{
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
print_usage("not running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "throttle")) {
|
||||
uint16_t val = atoi(argv[1]);
|
||||
get_instance()->set_throttle(val);
|
||||
get_instance<RC_ControllerModule>(desc)->set_throttle(val);
|
||||
PX4_INFO("Setting throttle to %u", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "yaw")) {
|
||||
uint16_t val = atoi(argv[1]);
|
||||
get_instance()->set_yaw(val);
|
||||
get_instance<RC_ControllerModule>(desc)->set_yaw(val);
|
||||
PX4_INFO("Setting yaw to %u", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "pitch")) {
|
||||
uint16_t val = atoi(argv[1]);
|
||||
get_instance()->set_pitch(val);
|
||||
get_instance<RC_ControllerModule>(desc)->set_pitch(val);
|
||||
PX4_INFO("Setting pitch to %u", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "roll")) {
|
||||
uint16_t val = atoi(argv[1]);
|
||||
get_instance()->set_roll(val);
|
||||
get_instance<RC_ControllerModule>(desc)->set_roll(val);
|
||||
PX4_INFO("Setting roll to %u", val);
|
||||
return 0;
|
||||
}
|
||||
@@ -106,17 +108,24 @@ int RC_ControllerModule::custom_command(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
int RC_ControllerModule::run_trampoline(int argc, char *argv[])
|
||||
{
|
||||
return ModuleBase::run_trampoline_impl(desc, [](int ac, char *av[]) -> ModuleBase * {
|
||||
return RC_ControllerModule::instantiate(ac, av);
|
||||
}, argc, argv);
|
||||
}
|
||||
|
||||
int RC_ControllerModule::task_spawn(int argc, char *argv[])
|
||||
{
|
||||
_task_id = px4_task_spawn_cmd("RC_ControllerModule",
|
||||
SCHED_DEFAULT,
|
||||
SCHED_PRIORITY_MAX,
|
||||
1024,
|
||||
(px4_main_t)&run_trampoline,
|
||||
(char *const *)argv);
|
||||
desc.task_id = px4_task_spawn_cmd("RC_ControllerModule",
|
||||
SCHED_DEFAULT,
|
||||
SCHED_PRIORITY_MAX,
|
||||
1024,
|
||||
(px4_main_t)&run_trampoline,
|
||||
(char *const *)argv);
|
||||
|
||||
if (_task_id < 0) {
|
||||
_task_id = -1;
|
||||
if (desc.task_id < 0) {
|
||||
desc.task_id = -1;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -252,5 +261,5 @@ int RC_ControllerModule::print_usage(const char *reason)
|
||||
|
||||
int rc_controller_main(int argc, char *argv[])
|
||||
{
|
||||
return RC_ControllerModule::main(argc, argv);
|
||||
return ModuleBase::main(RC_ControllerModule::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -41,9 +41,11 @@
|
||||
|
||||
extern "C" __EXPORT int rc_controller_main(int argc, char *argv[]);
|
||||
|
||||
class RC_ControllerModule : public ModuleBase<RC_ControllerModule>, public ModuleParams
|
||||
class RC_ControllerModule : public ModuleBase, public ModuleParams
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
RC_ControllerModule();
|
||||
|
||||
virtual ~RC_ControllerModule() = default;
|
||||
@@ -51,6 +53,9 @@ public:
|
||||
/** @see ModuleBase */
|
||||
static int task_spawn(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int run_trampoline(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static RC_ControllerModule *instantiate(int argc, char *argv[]);
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
ModuleBase::Descriptor VoxlSaveCalParams::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
VoxlSaveCalParams::VoxlSaveCalParams() :
|
||||
@@ -145,7 +147,7 @@ VoxlSaveCalParams::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
_parameter_primary_set_value_request_sub.unregisterCallback();
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -186,8 +188,8 @@ int VoxlSaveCalParams::task_spawn(int argc, char *argv[])
|
||||
VoxlSaveCalParams *instance = new VoxlSaveCalParams();
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init()) {
|
||||
return PX4_OK;
|
||||
@@ -198,8 +200,8 @@ int VoxlSaveCalParams::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -230,5 +232,5 @@ This implements autosaving of calibration parameters on VOXL2 platform.
|
||||
|
||||
extern "C" __EXPORT int voxl_save_cal_params_main(int argc, char *argv[])
|
||||
{
|
||||
return VoxlSaveCalParams::main(argc, argv);
|
||||
return ModuleBase::main(VoxlSaveCalParams::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -46,10 +46,12 @@
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
class VoxlSaveCalParams : public ModuleBase<VoxlSaveCalParams>, public ModuleParams,
|
||||
class VoxlSaveCalParams : public ModuleBase, public ModuleParams,
|
||||
public px4::WorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
VoxlSaveCalParams();
|
||||
~VoxlSaveCalParams() = default;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
229
platforms/common/module_base.cpp
Normal file
229
platforms/common/module_base.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2025 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file module_base.cpp
|
||||
*
|
||||
* Shared implementations of ModuleBase static methods. One copy linked
|
||||
* for all modules, replacing per-module CRTP template instantiations.
|
||||
*/
|
||||
|
||||
#ifndef MODULE_NAME
|
||||
#define MODULE_NAME "module"
|
||||
#endif
|
||||
|
||||
#include <px4_platform_common/module.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <cstring>
|
||||
|
||||
extern pthread_mutex_t px4_modules_mutex;
|
||||
|
||||
int ModuleBase::print_status()
|
||||
{
|
||||
printf("running\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ModuleBase::main(Descriptor &desc, int argc, char *argv[])
|
||||
{
|
||||
if (argc <= 1 ||
|
||||
strcmp(argv[1], "-h") == 0 ||
|
||||
strcmp(argv[1], "help") == 0 ||
|
||||
strcmp(argv[1], "info") == 0 ||
|
||||
strcmp(argv[1], "usage") == 0) {
|
||||
return desc.print_usage(nullptr);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "start") == 0) {
|
||||
// Pass the 'start' argument too, because later on px4_getopt() will ignore the first argument.
|
||||
return start_command(desc, argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "status") == 0) {
|
||||
return status_command(desc);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "stop") == 0) {
|
||||
return stop_command(desc);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&px4_modules_mutex);
|
||||
int ret = desc.custom_command(argc - 1, argv + 1);
|
||||
pthread_mutex_unlock(&px4_modules_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ModuleBase::start_command(Descriptor &desc, int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
pthread_mutex_lock(&px4_modules_mutex);
|
||||
|
||||
if (is_running(desc)) {
|
||||
ret = -1;
|
||||
PX4_ERR("Task already running");
|
||||
|
||||
} else {
|
||||
ret = desc.task_spawn(argc, argv);
|
||||
|
||||
if (ret < 0) {
|
||||
PX4_ERR("Task start failed (%i)", ret);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&px4_modules_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ModuleBase::stop_command(Descriptor &desc)
|
||||
{
|
||||
int ret = 0;
|
||||
pthread_mutex_lock(&px4_modules_mutex);
|
||||
|
||||
if (is_running(desc)) {
|
||||
ModuleBase *object = desc.object.load();
|
||||
|
||||
if (object) {
|
||||
object->request_stop();
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
do {
|
||||
pthread_mutex_unlock(&px4_modules_mutex);
|
||||
px4_usleep(10000); // 10 ms
|
||||
pthread_mutex_lock(&px4_modules_mutex);
|
||||
|
||||
if (++i > 500 && desc.task_id != -1) { // wait at most 5 sec
|
||||
PX4_ERR("timeout, forcing stop");
|
||||
|
||||
if (desc.task_id != task_id_is_work_queue) {
|
||||
px4_task_delete(desc.task_id);
|
||||
}
|
||||
|
||||
desc.task_id = -1;
|
||||
|
||||
delete desc.object.load();
|
||||
desc.object.store(nullptr);
|
||||
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
} while (desc.task_id != -1);
|
||||
|
||||
} else {
|
||||
// In the very unlikely event that can only happen on work queues,
|
||||
// if the starting thread does not wait for the work queue to initialize,
|
||||
// and inside the work queue, the allocation of _object fails
|
||||
// and exit_and_cleanup() is not called, set the task_id as invalid.
|
||||
desc.task_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&px4_modules_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ModuleBase::status_command(Descriptor &desc)
|
||||
{
|
||||
int ret = -1;
|
||||
pthread_mutex_lock(&px4_modules_mutex);
|
||||
|
||||
if (is_running(desc) && desc.object.load()) {
|
||||
ModuleBase *object = desc.object.load();
|
||||
ret = object->print_status();
|
||||
|
||||
} else {
|
||||
PX4_INFO("not running");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&px4_modules_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ModuleBase::exit_and_cleanup(Descriptor &desc)
|
||||
{
|
||||
// Take the lock here:
|
||||
// - if startup fails and we're faster than the parent thread, it will set
|
||||
// task_id and subsequently it will look like the task is running.
|
||||
// - deleting the object must take place inside the lock.
|
||||
pthread_mutex_lock(&px4_modules_mutex);
|
||||
|
||||
delete desc.object.load();
|
||||
desc.object.store(nullptr);
|
||||
|
||||
desc.task_id = -1; // Signal a potentially waiting thread for the module to exit that it can continue.
|
||||
pthread_mutex_unlock(&px4_modules_mutex);
|
||||
}
|
||||
|
||||
int ModuleBase::wait_until_running(Descriptor &desc, int timeout_ms)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
px4_usleep(2000);
|
||||
|
||||
} while (!desc.object.load() && ++i < timeout_ms / 2);
|
||||
|
||||
if (i >= timeout_ms / 2) {
|
||||
PX4_ERR("Timed out while waiting for thread to start");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ModuleBase::run_trampoline_impl(Descriptor &desc, instantiate_fn instantiate,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// We don't need the task name at this point.
|
||||
argc -= 1;
|
||||
argv += 1;
|
||||
|
||||
ModuleBase *object = instantiate(argc, argv);
|
||||
desc.object.store(object);
|
||||
|
||||
if (object) {
|
||||
object->run();
|
||||
|
||||
} else {
|
||||
PX4_ERR("failed to instantiate object");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
exit_and_cleanup(desc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
add_library(px4_layer
|
||||
${KERNEL_SRCS}
|
||||
${PX4_SOURCE_DIR}/platforms/common/Serial.cpp
|
||||
${PX4_SOURCE_DIR}/platforms/common/module_base.cpp
|
||||
SerialImpl.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ add_library(px4_layer
|
||||
board_dma_alloc.c
|
||||
board_fat_dma_alloc.c
|
||||
tasks.cpp
|
||||
${PX4_SOURCE_DIR}/platforms/common/module_base.cpp
|
||||
console_buffer_usr.cpp
|
||||
${PX4_SOURCE_DIR}/platforms/posix/src/px4/common/print_load.cpp
|
||||
${PX4_SOURCE_DIR}/platforms/posix/src/px4/common/cpuload.cpp
|
||||
@@ -45,6 +46,7 @@ target_link_libraries(px4_layer
|
||||
|
||||
add_library(px4_kernel_layer
|
||||
${KERNEL_SRCS}
|
||||
${PX4_SOURCE_DIR}/platforms/common/module_base.cpp
|
||||
SerialImpl.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ set(EXTRA_DEPENDS)
|
||||
add_library(px4_layer
|
||||
px4_posix_impl.cpp
|
||||
tasks.cpp
|
||||
${PX4_SOURCE_DIR}/platforms/common/module_base.cpp
|
||||
px4_sem.cpp
|
||||
px4_init.cpp
|
||||
lib_crc32.c
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
set(QURT_LAYER_SRCS
|
||||
drv_hrt.cpp
|
||||
tasks.cpp
|
||||
${PX4_SOURCE_DIR}/platforms/common/module_base.cpp
|
||||
px4_qurt_impl.cpp
|
||||
main.cpp
|
||||
qurt_log.cpp
|
||||
|
||||
@@ -43,220 +43,6 @@
|
||||
|
||||
#include "rclcpp/rclcpp.hpp"
|
||||
|
||||
/**
|
||||
* @class ModuleBase
|
||||
* Base class for modules, implementing common functionality,
|
||||
* such as 'start', 'stop' and 'status' commands.
|
||||
* Currently does not support modules which allow multiple instances,
|
||||
* such as mavlink.
|
||||
*
|
||||
* The class is implemented as curiously recurring template pattern (CRTP).
|
||||
* It allows to have a static object in the base class that is different for
|
||||
* each module type, and call static methods from the base class.
|
||||
*
|
||||
* @note Required methods for a derived class:
|
||||
* When running in its own thread:
|
||||
* static int task_spawn(int argc, char *argv[])
|
||||
* {
|
||||
* // call px4_task_spawn_cmd() with &run_trampoline as startup method
|
||||
* // optional: wait until _object is not null, which means the task got initialized (use a timeout)
|
||||
* // set _task_id and return 0
|
||||
* // on error return != 0 (and _task_id must be -1)
|
||||
* }
|
||||
*
|
||||
* static T *instantiate(int argc, char *argv[])
|
||||
* {
|
||||
* // this is called from within the new thread, from run_trampoline()
|
||||
* // parse the arguments
|
||||
* // create a new object T & return it
|
||||
* // or return nullptr on error
|
||||
* }
|
||||
*
|
||||
* static int custom_command(int argc, char *argv[])
|
||||
* {
|
||||
* // support for custom commands
|
||||
* // if none are supported, just do:
|
||||
* return print_usage("unrecognized command");
|
||||
* }
|
||||
*
|
||||
* static int print_usage(const char *reason = nullptr)
|
||||
* {
|
||||
* // use the PRINT_MODULE_* methods...
|
||||
* }
|
||||
*
|
||||
* When running on the work queue:
|
||||
* - custom_command & print_usage as above
|
||||
* static int task_spawn(int argc, char *argv[]) {
|
||||
* // parse the arguments
|
||||
* // set _object (here or from the work_queue() callback)
|
||||
* // call work_queue() (with a custom cycle trampoline)
|
||||
* // optional: wait until _object is not null, which means the task got initialized (use a timeout)
|
||||
* // set _task_id to task_id_is_work_queue and return 0
|
||||
* // on error return != 0 (and _task_id must be -1)
|
||||
* }
|
||||
*/
|
||||
template<class T>
|
||||
class ModuleBase : public rclcpp::Node
|
||||
{
|
||||
public:
|
||||
ModuleBase() : Node(MODULE_NAME)
|
||||
{
|
||||
|
||||
RCLCPP_INFO(get_logger(), "constructing %lu", hrt_absolute_time());
|
||||
}
|
||||
|
||||
virtual ~ModuleBase() {}
|
||||
|
||||
/**
|
||||
* @brief main Main entry point to the module that should be
|
||||
* called directly from the module's main method.
|
||||
* @param argc The task argument count.
|
||||
* @param argc Pointer to the task argument variable array.
|
||||
* @return Returns 0 iff successful, -1 otherwise.
|
||||
*/
|
||||
static int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Print the status if the module is running. This can be overridden by the module to provide
|
||||
* more specific information.
|
||||
* @return Returns 0 iff successful, -1 otherwise.
|
||||
*/
|
||||
virtual int print_status()
|
||||
{
|
||||
PX4_INFO("running");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main loop method for modules running in their own thread. Called from run_trampoline().
|
||||
* This method must return when should_exit() returns true.
|
||||
*/
|
||||
virtual void run()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the status of the module.
|
||||
* @return Returns true if the module is running, false otherwise.
|
||||
*/
|
||||
static bool is_running()
|
||||
{
|
||||
return _task_id != -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief Tells the module to stop (used from outside or inside the module thread).
|
||||
*/
|
||||
virtual void request_stop()
|
||||
{
|
||||
_task_should_exit.store(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the module should stop (used within the module thread).
|
||||
* @return Returns True iff successful, false otherwise.
|
||||
*/
|
||||
bool should_exit() const
|
||||
{
|
||||
return _task_should_exit.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exits the module and delete the object. Called from within the module's thread.
|
||||
* For work queue modules, this needs to be called from the derived class in the
|
||||
* cycle method, when should_exit() returns true.
|
||||
*/
|
||||
static void exit_and_cleanup()
|
||||
{
|
||||
// Take the lock here:
|
||||
// - if startup fails and we're faster than the parent thread, it will set
|
||||
// _task_id and subsequently it will look like the task is running.
|
||||
// - deleting the object must take place inside the lock.
|
||||
lock_module();
|
||||
|
||||
delete _object.load();
|
||||
_object.store(nullptr);
|
||||
|
||||
_task_id = -1; // Signal a potentially waiting thread for the module to exit that it can continue.
|
||||
unlock_module();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits until _object is initialized, (from the new thread). This can be called from task_spawn().
|
||||
* @return Returns 0 iff successful, -1 on timeout or otherwise.
|
||||
*/
|
||||
static int wait_until_running(int timeout_ms = 1000)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
px4_usleep(2000);
|
||||
|
||||
} while (!_object.load() && ++i < timeout_ms / 2);
|
||||
|
||||
if (i >= timeout_ms / 2) {
|
||||
PX4_ERR("Timed out while waiting for thread to start");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the module's object instance, (this is null if it's not running).
|
||||
*/
|
||||
static T *get_instance()
|
||||
{
|
||||
return (T *)_object.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var _object Instance if the module is running.
|
||||
* @note There will be one instance for each template type.
|
||||
*/
|
||||
static px4::atomic<T *> _object;
|
||||
|
||||
/** @var _task_id The task handle: -1 = invalid, otherwise task is assumed to be running. */
|
||||
static int _task_id;
|
||||
|
||||
/** @var task_id_is_work_queue Value to indicate if the task runs on the work queue. */
|
||||
static constexpr const int task_id_is_work_queue = -2;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief lock_module Mutex to lock the module thread.
|
||||
*/
|
||||
static void lock_module()
|
||||
{
|
||||
pthread_mutex_lock(&px4_modules_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unlock_module Mutex to unlock the module thread.
|
||||
*/
|
||||
static void unlock_module()
|
||||
{
|
||||
pthread_mutex_unlock(&px4_modules_mutex);
|
||||
}
|
||||
|
||||
/** @var _task_should_exit Boolean flag to indicate if the task should exit. */
|
||||
px4::atomic_bool _task_should_exit{false};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
px4::atomic<T *> ModuleBase<T>::_object{nullptr};
|
||||
|
||||
template<class T>
|
||||
int ModuleBase<T>::_task_id = -1;
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
add_library(px4_layer STATIC
|
||||
drv_hrt.cpp
|
||||
px4_sem.cpp
|
||||
${PX4_SOURCE_DIR}/platforms/common/module_base.cpp
|
||||
)
|
||||
target_compile_definitions(px4_layer PRIVATE MODULE_NAME="px4")
|
||||
target_compile_options(px4_layer PRIVATE -Wno-cast-align) # TODO: fix and enable
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
#include "voxl_esc.hpp"
|
||||
|
||||
ModuleBase::Descriptor VoxlEsc::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
// future use:
|
||||
#define MODALAI_PUBLISH_ESC_STATUS 0
|
||||
|
||||
@@ -425,8 +427,8 @@ int VoxlEsc::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init() == PX4_OK) {
|
||||
return PX4_OK;
|
||||
@@ -439,8 +441,8 @@ int VoxlEsc::task_spawn(int argc, char *argv[])
|
||||
// This will cause a crash on SLPI DSP
|
||||
// delete instance;
|
||||
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -693,12 +695,12 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
|
||||
/* start the driver if not running */
|
||||
if (!strcmp(verb, "start")) {
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
return VoxlEsc::task_spawn(argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
PX4_INFO("Not running");
|
||||
return -1;
|
||||
|
||||
@@ -761,7 +763,7 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
PX4_ERR("Reset ESC: %i", esc_id);
|
||||
cmd.len = qc_esc_create_reset_packet(esc_id, cmd.buf, sizeof(cmd.buf));
|
||||
cmd.response = false;
|
||||
return get_instance()->send_cmd_thread_safe(&cmd);
|
||||
return get_instance<VoxlEsc>(desc)->send_cmd_thread_safe(&cmd);
|
||||
|
||||
} else {
|
||||
print_usage("Invalid ESC ID, use 0-3");
|
||||
@@ -774,7 +776,7 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
cmd.len = qc_esc_create_version_request_packet(esc_id, cmd.buf, sizeof(cmd.buf));
|
||||
cmd.response = true;
|
||||
cmd.resp_delay_us = 2000;
|
||||
return get_instance()->send_cmd_thread_safe(&cmd);
|
||||
return get_instance<VoxlEsc>(desc)->send_cmd_thread_safe(&cmd);
|
||||
|
||||
} else {
|
||||
print_usage("Invalid ESC ID, use 0-3");
|
||||
@@ -787,7 +789,7 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
cmd.len = qc_esc_create_extended_version_request_packet(esc_id, cmd.buf, sizeof(cmd.buf));
|
||||
cmd.response = true;
|
||||
cmd.resp_delay_us = 5000;
|
||||
return get_instance()->send_cmd_thread_safe(&cmd);
|
||||
return get_instance<VoxlEsc>(desc)->send_cmd_thread_safe(&cmd);
|
||||
|
||||
} else {
|
||||
print_usage("Invalid ESC ID, use 0-3");
|
||||
@@ -799,7 +801,7 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
PX4_ERR("Request tone for ESC mask: %i", esc_id);
|
||||
cmd.len = qc_esc_create_sound_packet(period, duration, power, esc_id, cmd.buf, sizeof(cmd.buf));
|
||||
cmd.response = false;
|
||||
return get_instance()->send_cmd_thread_safe(&cmd);
|
||||
return get_instance<VoxlEsc>(desc)->send_cmd_thread_safe(&cmd);
|
||||
|
||||
} else {
|
||||
print_usage("Invalid ESC ID, use 0-3");
|
||||
@@ -808,14 +810,14 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
|
||||
} else if (!strcmp(verb, "led")) {
|
||||
if (led_mask <= 0x0FFF) {
|
||||
get_instance()->_led_rsc.test = true;
|
||||
get_instance()->_led_rsc.breath_en = false;
|
||||
get_instance<VoxlEsc>(desc)->_led_rsc.test = true;
|
||||
get_instance<VoxlEsc>(desc)->_led_rsc.breath_en = false;
|
||||
PX4_ERR("Request LED control for ESCs with mask: %i", led_mask);
|
||||
|
||||
get_instance()->_esc_chans[0].led = (led_mask & 0x0007);
|
||||
get_instance()->_esc_chans[1].led = (led_mask & 0x0038) >> 3;
|
||||
get_instance()->_esc_chans[2].led = (led_mask & 0x01C0) >> 6;
|
||||
get_instance()->_esc_chans[3].led = (led_mask & 0x0E00) >> 9;
|
||||
get_instance<VoxlEsc>(desc)->_esc_chans[0].led = (led_mask & 0x0007);
|
||||
get_instance<VoxlEsc>(desc)->_esc_chans[1].led = (led_mask & 0x0038) >> 3;
|
||||
get_instance<VoxlEsc>(desc)->_esc_chans[2].led = (led_mask & 0x01C0) >> 6;
|
||||
get_instance<VoxlEsc>(desc)->_esc_chans[3].led = (led_mask & 0x0E00) >> 9;
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
@@ -851,7 +853,7 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
id_fb,
|
||||
cmd.buf,
|
||||
sizeof(cmd.buf),
|
||||
get_instance()->_extended_rpm);
|
||||
get_instance<VoxlEsc>(desc)->_extended_rpm);
|
||||
|
||||
cmd.response = true;
|
||||
cmd.repeats = repeat_count;
|
||||
@@ -862,7 +864,7 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
PX4_ERR("Feedback id debug: %i", id_fb);
|
||||
PX4_ERR("Sending UART ESC RPM command %i", rate);
|
||||
|
||||
return get_instance()->send_cmd_thread_safe(&cmd);
|
||||
return get_instance<VoxlEsc>(desc)->send_cmd_thread_safe(&cmd);
|
||||
|
||||
} else {
|
||||
print_usage("Invalid ESC ID, use 0-3");
|
||||
@@ -907,7 +909,7 @@ int VoxlEsc::custom_command(int argc, char *argv[])
|
||||
PX4_ERR("Feedback id debug: %i", id_fb);
|
||||
PX4_ERR("Sending UART ESC power command %i", rate);
|
||||
|
||||
return get_instance()->send_cmd_thread_safe(&cmd);
|
||||
return get_instance<VoxlEsc>(desc)->send_cmd_thread_safe(&cmd);
|
||||
|
||||
} else {
|
||||
print_usage("Invalid ESC ID, use 0-3");
|
||||
@@ -1422,7 +1424,7 @@ void VoxlEsc::Run()
|
||||
ScheduleClear();
|
||||
_mixing_output.unregister();
|
||||
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1446,7 +1448,7 @@ void VoxlEsc::Run()
|
||||
PX4_ERR("Failed to initialize device, exiting the module");
|
||||
ScheduleClear();
|
||||
_mixing_output.unregister();
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1767,5 +1769,5 @@ extern "C" __EXPORT int voxl_esc_main(int argc, char *argv[]);
|
||||
|
||||
int voxl_esc_main(int argc, char *argv[])
|
||||
{
|
||||
return VoxlEsc::main(argc, argv);
|
||||
return ModuleBase::main(VoxlEsc::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -58,9 +58,11 @@
|
||||
|
||||
using namespace device;
|
||||
|
||||
class VoxlEsc : public ModuleBase<VoxlEsc>, public OutputModuleInterface
|
||||
class VoxlEsc : public ModuleBase, public OutputModuleInterface
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
VoxlEsc();
|
||||
virtual ~VoxlEsc();
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
#endif
|
||||
|
||||
ModuleBase::Descriptor ADC::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
ADC::ADC(uint32_t base_address, uint32_t channels, bool publish_adc_report) :
|
||||
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default),
|
||||
_publish_adc_report(publish_adc_report),
|
||||
@@ -362,8 +364,8 @@ int ADC::custom_command(int argc, char *argv[])
|
||||
const char *verb = argv[0];
|
||||
|
||||
if (!strcmp(verb, "test")) {
|
||||
if (is_running()) {
|
||||
return _object.load()->test();
|
||||
if (is_running(desc)) {
|
||||
return get_instance<ADC>(desc)->test();
|
||||
}
|
||||
|
||||
return PX4_ERROR;
|
||||
@@ -378,8 +380,8 @@ int ADC::task_spawn(int argc, char *argv[])
|
||||
ADC *instance = new ADC(SYSTEM_ADC_BASE, ADC_CHANNELS, publish_adc_report);
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init() == PX4_OK) {
|
||||
return PX4_OK;
|
||||
@@ -390,8 +392,8 @@ int ADC::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -421,5 +423,5 @@ ADC driver.
|
||||
|
||||
extern "C" __EXPORT int board_adc_main(int argc, char *argv[])
|
||||
{
|
||||
return ADC::main(argc, argv);
|
||||
return ModuleBase::main(ADC::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -62,9 +62,11 @@ using namespace time_literals;
|
||||
|
||||
#define ADC_TOTAL_CHANNELS 32
|
||||
|
||||
class ADC : public ModuleBase<ADC>, public px4::ScheduledWorkItem
|
||||
class ADC : public ModuleBase, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
ADC(uint32_t base_address = SYSTEM_ADC_BASE, uint32_t channels = ADC_CHANNELS, bool publish_adc_report = true);
|
||||
|
||||
~ADC() override;
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <builtin/builtin.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
ModuleBase::Descriptor AuterionAutostarter::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
AuterionAutostarter::AuterionAutostarter() :
|
||||
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default)
|
||||
{
|
||||
@@ -57,7 +59,7 @@ bool AuterionAutostarter::init()
|
||||
void AuterionAutostarter::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,7 +67,7 @@ void AuterionAutostarter::Run()
|
||||
_actuator_armed_sub.copy(&actuator_armed);
|
||||
|
||||
if (actuator_armed.armed) {
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -510,8 +512,8 @@ int AuterionAutostarter::task_spawn(int argc, char *argv[])
|
||||
AuterionAutostarter *instance = new AuterionAutostarter();
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init()) {
|
||||
return PX4_OK;
|
||||
@@ -522,8 +524,8 @@ int AuterionAutostarter::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -555,5 +557,5 @@ Driver for starting and auto-detecting different power monitors.
|
||||
|
||||
extern "C" __EXPORT int auterion_autostarter_main(int argc, char *argv[])
|
||||
{
|
||||
return AuterionAutostarter::main(argc, argv);
|
||||
return ModuleBase::main(AuterionAutostarter::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -71,10 +71,12 @@ private:
|
||||
struct i2c_master_s *_i2c {nullptr};
|
||||
};
|
||||
|
||||
class AuterionAutostarter : public ModuleBase<AuterionAutostarter>, public px4::ScheduledWorkItem
|
||||
class AuterionAutostarter : public ModuleBase, public px4::ScheduledWorkItem
|
||||
{
|
||||
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
AuterionAutostarter();
|
||||
virtual ~AuterionAutostarter();
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ __END_DECLS
|
||||
|
||||
#include <px4_platform_common/shutdown.h>
|
||||
|
||||
ModuleBase::Descriptor CdcAcmAutostart::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
#define USB_DEVICE_PATH "/dev/ttyACM0"
|
||||
|
||||
#if defined(CONFIG_SERIAL_PASSTHRU_UBLOX)
|
||||
@@ -95,7 +97,7 @@ int CdcAcmAutostart::Start()
|
||||
void CdcAcmAutostart::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -566,8 +568,8 @@ int CdcAcmAutostart::task_spawn(int argc, char *argv[])
|
||||
return ret;
|
||||
}
|
||||
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -660,7 +662,7 @@ and continue to check for VBUS and start mavlink once it is detected.
|
||||
extern "C" __EXPORT int cdcacm_autostart_main(int argc, char *argv[])
|
||||
{
|
||||
#if defined(CONFIG_SYSTEM_CDCACM)
|
||||
return CdcAcmAutostart::main(argc, argv);
|
||||
return ModuleBase::main(CdcAcmAutostart::desc, argc, argv);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,11 @@
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
class CdcAcmAutostart : public ModuleBase<CdcAcmAutostart>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
class CdcAcmAutostart : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
CdcAcmAutostart();
|
||||
~CdcAcmAutostart() override;
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
#include "pga460.h"
|
||||
|
||||
ModuleBase::Descriptor PGA460::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
|
||||
PGA460::PGA460(const char *port)
|
||||
{
|
||||
@@ -751,6 +753,13 @@ int PGA460::take_measurement(const uint8_t mode)
|
||||
return PX4_OK;
|
||||
}
|
||||
|
||||
int PGA460::run_trampoline(int argc, char *argv[])
|
||||
{
|
||||
return ModuleBase::run_trampoline_impl(desc, [](int ac, char *av[]) -> ModuleBase * {
|
||||
return PGA460::instantiate(ac, av);
|
||||
}, argc, argv);
|
||||
}
|
||||
|
||||
int PGA460::task_spawn(int argc, char *argv[])
|
||||
{
|
||||
px4_main_t entry_point = (px4_main_t)&run_trampoline;
|
||||
@@ -765,7 +774,7 @@ int PGA460::task_spawn(int argc, char *argv[])
|
||||
return -errno;
|
||||
}
|
||||
|
||||
_task_id = task_id;
|
||||
desc.task_id = task_id;
|
||||
|
||||
return PX4_OK;
|
||||
}
|
||||
@@ -905,5 +914,5 @@ int PGA460::write_register(const uint8_t reg, const uint8_t val)
|
||||
|
||||
extern "C" __EXPORT int pga460_main(int argc, char *argv[])
|
||||
{
|
||||
return PGA460::main(argc, argv);
|
||||
return ModuleBase::main(PGA460::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -207,10 +207,12 @@
|
||||
#define P2_THR_15 0x0 //reg addr 0x7E
|
||||
#define THR_CRC 0x1D //reg addr 0x7F
|
||||
|
||||
class PGA460 : public ModuleBase<PGA460>
|
||||
class PGA460 : public ModuleBase
|
||||
{
|
||||
public:
|
||||
|
||||
static Descriptor desc;
|
||||
|
||||
PGA460(const char *port = PGA460_DEFAULT_PORT);
|
||||
|
||||
virtual ~PGA460();
|
||||
@@ -245,6 +247,11 @@ public:
|
||||
*/
|
||||
static int task_spawn(int argc, char *argv[]);
|
||||
|
||||
/**
|
||||
* @see ModuleBase
|
||||
*/
|
||||
static int run_trampoline(int argc, char *argv[]);
|
||||
|
||||
/**
|
||||
* @brief Closes the serial port.
|
||||
* @return Returns 0 if success or ERRNO.
|
||||
|
||||
@@ -67,9 +67,11 @@ static constexpr uint32_t HXSRX0X_CONVERSION_INTERVAL{50_ms};
|
||||
// Maximum time to wait for a conversion to complete.
|
||||
static constexpr uint32_t HXSRX0X_CONVERSION_TIMEOUT{30_ms};
|
||||
|
||||
class SRF05 : public ModuleBase<SRF05>, public px4::ScheduledWorkItem
|
||||
class SRF05 : public ModuleBase, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
SRF05(const uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING);
|
||||
virtual ~SRF05() override;
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
|
||||
#include <px4_arch/micro_hal.h>
|
||||
|
||||
ModuleBase::Descriptor SRF05::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
SRF05::SRF05(const uint8_t rotation) :
|
||||
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default),
|
||||
_px4_rangefinder(0 /* no device type for GPIO input */, rotation)
|
||||
@@ -114,7 +116,7 @@ SRF05::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
ScheduleClear();
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,8 +197,8 @@ int SRF05::task_spawn(int argc, char *argv[])
|
||||
SRF05 *instance = new SRF05(rotation);
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init() == PX4_OK) {
|
||||
return PX4_OK;
|
||||
@@ -207,8 +209,8 @@ int SRF05::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -251,7 +253,7 @@ SRF05::print_status()
|
||||
|
||||
extern "C" __EXPORT int srf05_main(int argc, char *argv[])
|
||||
{
|
||||
return SRF05::main(argc, argv);
|
||||
return ModuleBase::main(SRF05::desc, argc, argv);
|
||||
}
|
||||
#else
|
||||
# error ("GPIO_ULTRASOUND_xxx not defined. Driver not supported.");
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
#include <px4_platform_common/sem.hpp>
|
||||
|
||||
ModuleBase::Descriptor DShot::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
char DShot::_telemetry_device[] {};
|
||||
bool DShot::_telemetry_swap_rxtx{false};
|
||||
px4::atomic_bool DShot::_request_telemetry_init{false};
|
||||
@@ -81,8 +83,8 @@ int DShot::task_spawn(int argc, char *argv[])
|
||||
DShot *instance = new DShot();
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init() == PX4_OK) {
|
||||
return PX4_OK;
|
||||
@@ -93,8 +95,8 @@ int DShot::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -466,7 +468,7 @@ void DShot::Run()
|
||||
ScheduleClear();
|
||||
_mixing_output.unregister();
|
||||
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -698,16 +700,16 @@ int DShot::custom_command(int argc, char *argv[])
|
||||
|
||||
for (unsigned i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i) {
|
||||
if (!strcmp(verb, commands[i].name)) {
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
PX4_ERR("module not running");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return get_instance()->send_command_thread_safe(commands[i].command, commands[i].num_repetitions, motor_index);
|
||||
return get_instance<DShot>(desc)->send_command_thread_safe(commands[i].command, commands[i].num_repetitions, motor_index);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
int ret = DShot::task_spawn(argc, argv);
|
||||
|
||||
if (ret) {
|
||||
@@ -805,5 +807,5 @@ After saving, the reversed direction will be regarded as the normal one. So to r
|
||||
|
||||
extern "C" __EXPORT int dshot_main(int argc, char *argv[])
|
||||
{
|
||||
return DShot::main(argc, argv);
|
||||
return ModuleBase::main(DShot::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -57,9 +57,11 @@ static constexpr int DSHOT_DISARM_VALUE = 0;
|
||||
static constexpr int DSHOT_MIN_THROTTLE = 1;
|
||||
static constexpr int DSHOT_MAX_THROTTLE = 1999;
|
||||
|
||||
class DShot final : public ModuleBase<DShot>, public OutputModuleInterface
|
||||
class DShot final : public ModuleBase, public OutputModuleInterface
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
DShot();
|
||||
~DShot() override;
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ using namespace device;
|
||||
namespace septentrio
|
||||
{
|
||||
|
||||
ModuleBase::Descriptor SeptentrioDriver::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
/**
|
||||
* RTC drift time when time synchronization is needed (in seconds).
|
||||
*/
|
||||
@@ -347,6 +349,13 @@ void SeptentrioDriver::run()
|
||||
|
||||
}
|
||||
|
||||
int SeptentrioDriver::run_trampoline(int argc, char *argv[])
|
||||
{
|
||||
return ModuleBase::run_trampoline_impl(desc, [](int ac, char *av[]) -> ModuleBase * {
|
||||
return SeptentrioDriver::instantiate(ac, av);
|
||||
}, argc, argv);
|
||||
}
|
||||
|
||||
int SeptentrioDriver::task_spawn(int argc, char *argv[])
|
||||
{
|
||||
return task_spawn(argc, argv, Instance::Main);
|
||||
@@ -372,14 +381,14 @@ int SeptentrioDriver::task_spawn(int argc, char *argv[], Instance instance)
|
||||
(char *const *)argv);
|
||||
|
||||
if (task_id < 0) {
|
||||
// `_task_id` of module that hasn't been started before or has been stopped should already be -1.
|
||||
// `desc.task_id` of module that hasn't been started before or has been stopped should already be -1.
|
||||
// This is just to make sure.
|
||||
_task_id = -1;
|
||||
desc.task_id = -1;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (instance == Instance::Main) {
|
||||
_task_id = task_id;
|
||||
desc.task_id = task_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -489,12 +498,12 @@ int SeptentrioDriver::custom_command(int argc, char *argv[])
|
||||
const char *failure_reason {"unknown command"};
|
||||
SeptentrioDriver *driver_instance;
|
||||
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
PX4_INFO("not running");
|
||||
return -1;
|
||||
}
|
||||
|
||||
driver_instance = get_instance();
|
||||
driver_instance = get_instance<SeptentrioDriver>(desc);
|
||||
|
||||
if (argc >= 1 && strcmp(argv[0], "reset") == 0) {
|
||||
if (argc == 2) {
|
||||
@@ -1861,5 +1870,5 @@ uint32_t SeptentrioDriver::get_parameter(const char *name, float *value)
|
||||
|
||||
extern "C" __EXPORT int septentrio_main(int argc, char *argv[])
|
||||
{
|
||||
return septentrio::SeptentrioDriver::main(argc, argv);
|
||||
return ModuleBase::main(septentrio::SeptentrioDriver::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -227,9 +227,11 @@ enum class ReceiverOutputTracker {
|
||||
PositioningMessages = DOP + PVTGeodetic + VelCovGeodetic + AttEuler + AttCovEuler,
|
||||
};
|
||||
|
||||
class SeptentrioDriver : public ModuleBase<SeptentrioDriver>, public device::Device
|
||||
class SeptentrioDriver : public ModuleBase, public device::Device
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
SeptentrioDriver(const char *device_path, Instance instance, uint32_t baud_rate);
|
||||
~SeptentrioDriver() override;
|
||||
|
||||
@@ -244,6 +246,9 @@ public:
|
||||
|
||||
static int task_spawn(int argc, char *argv[], Instance instance);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int run_trampoline(int argc, char *argv[]);
|
||||
|
||||
/**
|
||||
* @brief Secondary run trampoline to support two driver instances.
|
||||
*/
|
||||
|
||||
@@ -117,7 +117,7 @@ struct GPS_Sat_Info {
|
||||
static constexpr int TASK_STACK_SIZE = PX4_STACK_ADJUSTED(2040);
|
||||
|
||||
|
||||
class GPS : public ModuleBase<GPS>, public device::Device
|
||||
class GPS : public ModuleBase, public device::Device
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -133,6 +133,8 @@ public:
|
||||
unsigned configured_baudrate);
|
||||
~GPS() override;
|
||||
|
||||
static Descriptor desc;
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int task_spawn(int argc, char *argv[]);
|
||||
|
||||
@@ -150,6 +152,11 @@ public:
|
||||
/** @see ModuleBase */
|
||||
static int print_usage(const char *reason = nullptr);
|
||||
|
||||
/**
|
||||
* task spawn trampoline for the primary GPS
|
||||
*/
|
||||
static int run_trampoline(int argc, char *argv[]);
|
||||
|
||||
/**
|
||||
* task spawn trampoline for the secondary GPS
|
||||
*/
|
||||
@@ -302,6 +309,7 @@ private:
|
||||
|
||||
px4::atomic_bool GPS::_is_gps_main_advertised{false};
|
||||
px4::atomic<GPS *> GPS::_secondary_instance{nullptr};
|
||||
ModuleBase::Descriptor GPS::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
/*
|
||||
* Driver 'main' command.
|
||||
@@ -1418,12 +1426,12 @@ int
|
||||
GPS::custom_command(int argc, char *argv[])
|
||||
{
|
||||
// Check if the driver is running.
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
PX4_INFO("not running");
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
GPS *_instance = get_instance();
|
||||
GPS *_instance = get_instance<GPS>(desc);
|
||||
|
||||
bool res = false;
|
||||
|
||||
@@ -1517,17 +1525,24 @@ int GPS::task_spawn(int argc, char *argv[], Instance instance)
|
||||
entry_point, (char *const *)argv);
|
||||
|
||||
if (task_id < 0) {
|
||||
_task_id = -1;
|
||||
desc.task_id = -1;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (instance == Instance::Main) {
|
||||
_task_id = task_id;
|
||||
desc.task_id = task_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GPS::run_trampoline(int argc, char *argv[])
|
||||
{
|
||||
return ModuleBase::run_trampoline_impl(desc, [](int ac, char *av[]) -> ModuleBase * {
|
||||
return GPS::instantiate(ac, av);
|
||||
}, argc, argv);
|
||||
}
|
||||
|
||||
int GPS::run_trampoline_secondary(int argc, char *argv[])
|
||||
{
|
||||
// the task name is the first argument
|
||||
@@ -1693,5 +1708,5 @@ GPS *GPS::instantiate(int argc, char *argv[], Instance instance)
|
||||
int
|
||||
gps_main(int argc, char *argv[])
|
||||
{
|
||||
return GPS::main(argc, argv);
|
||||
return ModuleBase::main(GPS::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <drivers/drv_io_heater.h>
|
||||
|
||||
ModuleBase::Descriptor Heater::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
#if defined(BOARD_USES_PX4IO_VERSION) and defined(PX4IO_HEATER_ENABLED)
|
||||
// Heater on some boards is on IO MCU
|
||||
// Use ioctl calls to IO driver to turn heater on/off
|
||||
@@ -75,7 +77,7 @@ Heater::~Heater()
|
||||
int Heater::custom_command(int argc, char *argv[])
|
||||
{
|
||||
// Check if the driver is running.
|
||||
if (!is_running()) {
|
||||
if (!is_running(desc)) {
|
||||
PX4_INFO("not running");
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -180,7 +182,7 @@ void Heater::Run()
|
||||
}
|
||||
|
||||
#endif
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -292,8 +294,8 @@ int Heater::task_spawn(int argc, char *argv[])
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
_object.store(heater);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(heater);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
heater->start();
|
||||
return 0;
|
||||
@@ -334,5 +336,5 @@ This task can be started at boot from the startup scripts by setting SENS_EN_THE
|
||||
|
||||
extern "C" __EXPORT int heater_main(int argc, char *argv[])
|
||||
{
|
||||
return Heater::main(argc, argv);
|
||||
return ModuleBase::main(Heater::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -60,9 +60,11 @@ using namespace time_literals;
|
||||
#define CONTROLLER_PERIOD_DEFAULT 10000
|
||||
#define TEMPERATURE_TARGET_THRESHOLD 2.5f
|
||||
|
||||
class Heater : public ModuleBase<Heater>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
class Heater : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
Heater();
|
||||
|
||||
virtual ~Heater();
|
||||
|
||||
@@ -43,6 +43,6 @@
|
||||
|
||||
extern "C" __EXPORT int eulernav_bahrs_main(int argc, char *argv[])
|
||||
{
|
||||
EulerNavDriver::main(argc, argv);
|
||||
ModuleBase::main(EulerNavDriver::desc, argc, argv);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -52,20 +52,27 @@ EulerNavDriver::~EulerNavDriver()
|
||||
deinitialize();
|
||||
}
|
||||
|
||||
int EulerNavDriver::run_trampoline(int argc, char *argv[])
|
||||
{
|
||||
return ModuleBase::run_trampoline_impl(desc, [](int ac, char *av[]) -> ModuleBase * {
|
||||
return EulerNavDriver::instantiate(ac, av);
|
||||
}, argc, argv);
|
||||
}
|
||||
|
||||
int EulerNavDriver::task_spawn(int argc, char *argv[])
|
||||
{
|
||||
int task_id = px4_task_spawn_cmd("bahrs", SCHED_DEFAULT, SCHED_PRIORITY_FAST_DRIVER,
|
||||
Config::TASK_STACK_SIZE, (px4_main_t)&run_trampoline, argv);
|
||||
|
||||
if (task_id < 0) {
|
||||
_task_id = -1;
|
||||
desc.task_id = -1;
|
||||
PX4_ERR("Failed to spawn task.");
|
||||
|
||||
} else {
|
||||
_task_id = task_id;
|
||||
desc.task_id = task_id;
|
||||
}
|
||||
|
||||
return (_task_id < 0) ? 1 : 0;
|
||||
return (desc.task_id < 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
EulerNavDriver *EulerNavDriver::instantiate(int argc, char *argv[])
|
||||
@@ -232,6 +239,8 @@ void EulerNavDriver::deinitialize()
|
||||
_is_initialized = false;
|
||||
}
|
||||
|
||||
ModuleBase::Descriptor EulerNavDriver::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
void EulerNavDriver::processDataBuffer()
|
||||
{
|
||||
static_assert(Config::MIN_MESSAGE_LENGTH >= (sizeof(CSerialProtocol::SMessageHeader) + sizeof(CSerialProtocol::CrcType_t)));
|
||||
|
||||
@@ -45,9 +45,11 @@
|
||||
#include <containers/Array.hpp>
|
||||
#include "CSerialProtocol.h"
|
||||
|
||||
class EulerNavDriver : public ModuleBase<EulerNavDriver>, public ModuleParams
|
||||
class EulerNavDriver : public ModuleBase, public ModuleParams
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
/// @brief Class constructor
|
||||
/// @param device_name Serial port to open
|
||||
EulerNavDriver(const char *device_name);
|
||||
@@ -57,6 +59,9 @@ public:
|
||||
/// @brief Required by ModuleBase
|
||||
static int task_spawn(int argc, char *argv[]);
|
||||
|
||||
/// @brief Required by ModuleBase
|
||||
static int run_trampoline(int argc, char *argv[]);
|
||||
|
||||
/// @brief Required by ModuleBase
|
||||
static EulerNavDriver *instantiate(int argc, char *argv[]);
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
ModuleBase::Descriptor ILabs::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
// GPS epoch: 1980-01-06 00:00:00 UTC
|
||||
constexpr uint64_t GPS_EPOCH_SECS = 315964800ULL;
|
||||
|
||||
@@ -152,8 +154,8 @@ int ILabs::task_spawn(int argc, char *argv[]) {
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
instance->ScheduleNow();
|
||||
|
||||
@@ -227,7 +229,7 @@ int ILabs::print_status() {
|
||||
void ILabs::Run() {
|
||||
if (should_exit()) {
|
||||
_sensor.deinit();
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -530,5 +532,5 @@ void ILabs::processData(InertialLabs::SensorsData *data) {
|
||||
}
|
||||
|
||||
extern "C" __EXPORT int ilabs_main(int argc, char *argv[]) {
|
||||
return ILabs::main(argc, argv);
|
||||
return ModuleBase::main(ILabs::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -59,8 +59,10 @@
|
||||
|
||||
#include "sensor.h"
|
||||
|
||||
class ILabs : public ModuleBase<ILabs>, public ModuleParams, public px4::ScheduledWorkItem {
|
||||
class ILabs : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem {
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
ILabs(const char *port);
|
||||
~ILabs() override;
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "MicroStrain.hpp"
|
||||
|
||||
ModuleBase::Descriptor MicroStrain::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
device::Serial device_uart{};
|
||||
|
||||
MicroStrain::MicroStrain(const char *uart_port) :
|
||||
@@ -1851,7 +1853,7 @@ void MicroStrain::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
ScheduleClear();
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1911,8 +1913,8 @@ int MicroStrain::task_spawn(int argc, char *argv[])
|
||||
|
||||
if (dev == nullptr || strlen(dev) == 0) {
|
||||
print_usage("no device specified");
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -1921,8 +1923,8 @@ int MicroStrain::task_spawn(int argc, char *argv[])
|
||||
MicroStrain *instance = new MicroStrain(dev);
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init()) {
|
||||
return PX4_OK;
|
||||
@@ -1933,8 +1935,8 @@ int MicroStrain::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -1995,5 +1997,5 @@ $ microstrain stop
|
||||
|
||||
extern "C" __EXPORT int microstrain_main(int argc, char *argv[])
|
||||
{
|
||||
return MicroStrain::main(argc, argv);
|
||||
return ModuleBase::main(MicroStrain::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -86,9 +86,11 @@ using matrix::Vector2f;
|
||||
|
||||
static constexpr float sq(float x) { return x * x; };
|
||||
|
||||
class MicroStrain : public ModuleBase<MicroStrain>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
class MicroStrain : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
MicroStrain(const char *_device);
|
||||
~MicroStrain() override;
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
|
||||
using matrix::Vector2f;
|
||||
|
||||
ModuleBase::Descriptor SbgEcom::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
SbgEcom::SbgEcom(const char *device_name, uint32_t baudrate, const char *config_file, const char *config_string):
|
||||
ModuleParams(nullptr),
|
||||
ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device_name)),
|
||||
@@ -952,7 +954,7 @@ void SbgEcom::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
ScheduleClear();
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1065,8 +1067,8 @@ int SbgEcom::task_spawn(int argc, char **argv)
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
_task_id = task_id_is_work_queue;
|
||||
_object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
instance->ScheduleNow();
|
||||
return PX4_OK;
|
||||
|
||||
@@ -1121,5 +1123,5 @@ int SbgEcom::print_status()
|
||||
|
||||
extern "C" __EXPORT int sbgecom_main(int argc, char **argv)
|
||||
{
|
||||
return SbgEcom::main(argc, argv);
|
||||
return ModuleBase::main(SbgEcom::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -63,10 +63,12 @@
|
||||
#include <uORB/topics/vehicle_local_position.h>
|
||||
#include <uORB/topics/vehicle_magnetometer.h>
|
||||
|
||||
class SbgEcom : public ModuleBase<SbgEcom>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
class SbgEcom : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
|
||||
static Descriptor desc;
|
||||
|
||||
SbgEcom(const char *port, uint32_t baudrate, const char *config_file, const char *config_string);
|
||||
~SbgEcom() override;
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
using matrix::Vector2f;
|
||||
|
||||
ModuleBase::Descriptor VectorNav::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
VectorNav::VectorNav(const char *port) :
|
||||
ModuleParams(nullptr),
|
||||
ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(port)),
|
||||
@@ -682,7 +684,7 @@ void VectorNav::Run()
|
||||
if (should_exit()) {
|
||||
VnSensor_unregisterAsyncPacketReceivedHandler(&_vs);
|
||||
VnSensor_disconnect(&_vs);
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
|
||||
} else if (!_initialized) {
|
||||
@@ -797,8 +799,8 @@ int VectorNav::task_spawn(int argc, char *argv[])
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
instance->ScheduleNow();
|
||||
|
||||
@@ -858,5 +860,5 @@ $ vectornav stop
|
||||
|
||||
extern "C" __EXPORT int vectornav_main(int argc, char *argv[])
|
||||
{
|
||||
return VectorNav::main(argc, argv);
|
||||
return ModuleBase::main(VectorNav::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -75,9 +75,11 @@ extern "C" {
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
class VectorNav : public ModuleBase<VectorNav>, public ModuleParams, public px4::ScheduledWorkItem
|
||||
class VectorNav : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
VectorNav(const char *port);
|
||||
~VectorNav() override;
|
||||
|
||||
|
||||
@@ -49,9 +49,11 @@
|
||||
#include <px4_platform_common/module.h>
|
||||
#include <drivers/drv_neopixel.h>
|
||||
|
||||
class NEOPIXEL : public px4::ScheduledWorkItem, public ModuleBase<NEOPIXEL>
|
||||
class NEOPIXEL : public px4::ScheduledWorkItem, public ModuleBase
|
||||
{
|
||||
public:
|
||||
static Descriptor desc;
|
||||
|
||||
NEOPIXEL(unsigned int number_of_packages);
|
||||
virtual ~NEOPIXEL();
|
||||
|
||||
@@ -84,6 +86,8 @@ private:
|
||||
neopixel::NeoLEDData *_leds;
|
||||
};
|
||||
|
||||
ModuleBase::Descriptor NEOPIXEL::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
NEOPIXEL::NEOPIXEL(unsigned int number_of_packages) :
|
||||
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::lp_default),
|
||||
_number_of_packages(number_of_packages)
|
||||
@@ -131,8 +135,8 @@ int NEOPIXEL::task_spawn(int argc, char *argv[])
|
||||
NEOPIXEL *instance = new NEOPIXEL(number_of_packages);
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init() == PX4_OK) {
|
||||
return PX4_OK;
|
||||
@@ -143,8 +147,8 @@ int NEOPIXEL::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
return PX4_ERROR;
|
||||
}
|
||||
|
||||
@@ -190,7 +194,7 @@ void NEOPIXEL::Run()
|
||||
{
|
||||
if (should_exit()) {
|
||||
ScheduleClear();
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,5 +250,5 @@ void NEOPIXEL::Run()
|
||||
|
||||
extern "C" __EXPORT int neopixel_main(int argc, char *argv[])
|
||||
{
|
||||
return NEOPIXEL::main(argc, argv);
|
||||
return ModuleBase::main(NEOPIXEL::desc, argc, argv);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
using namespace pwm_out;
|
||||
|
||||
ModuleBase::Descriptor LinuxPWMOut::desc{task_spawn, custom_command, print_usage};
|
||||
|
||||
LinuxPWMOut::LinuxPWMOut() :
|
||||
OutputModuleInterface(MODULE_NAME, px4::wq_configurations::hp_default),
|
||||
_cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")),
|
||||
@@ -77,8 +79,8 @@ int LinuxPWMOut::task_spawn(int argc, char *argv[])
|
||||
LinuxPWMOut *instance = new LinuxPWMOut();
|
||||
|
||||
if (instance) {
|
||||
_object.store(instance);
|
||||
_task_id = task_id_is_work_queue;
|
||||
desc.object.store(instance);
|
||||
desc.task_id = task_id_is_work_queue;
|
||||
|
||||
if (instance->init() == PX4_OK) {
|
||||
return PX4_OK;
|
||||
@@ -89,8 +91,8 @@ int LinuxPWMOut::task_spawn(int argc, char *argv[])
|
||||
}
|
||||
|
||||
delete instance;
|
||||
_object.store(nullptr);
|
||||
_task_id = -1;
|
||||
desc.object.store(nullptr);
|
||||
desc.task_id = -1;
|
||||
|
||||
return PX4_ERROR;
|
||||
}
|
||||
@@ -108,7 +110,7 @@ void LinuxPWMOut::Run()
|
||||
ScheduleClear();
|
||||
_mixing_output.unregister();
|
||||
|
||||
exit_and_cleanup();
|
||||
exit_and_cleanup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -166,5 +168,5 @@ Linux PWM output driver with board-specific backend implementation.
|
||||
|
||||
extern "C" __EXPORT int linux_pwm_out_main(int argc, char *argv[])
|
||||
{
|
||||
return LinuxPWMOut::main(argc, argv);
|
||||
return ModuleBase::main(LinuxPWMOut::desc, argc, argv);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user