PWM out: Robustify initialization

This ensures that all PWM outputs get correctly inialized on targets that only support one.
This commit is contained in:
Lorenz Meier
2021-03-21 00:20:52 +01:00
parent f6eae08597
commit 6e9f745809
+33 -12
View File
@@ -35,6 +35,7 @@
pthread_mutex_t pwm_out_module_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t pwm_out_module_mutex = PTHREAD_MUTEX_INITIALIZER;
static px4::atomic<PWMOut *> _objects[PWM_OUT_MAX_INSTANCES] {}; static px4::atomic<PWMOut *> _objects[PWM_OUT_MAX_INSTANCES] {};
static bool _pwm_out_started = false;
static bool is_running() { return (_objects[0].load() != nullptr) || (_objects[1].load() != nullptr); } static bool is_running() { return (_objects[0].load() != nullptr) || (_objects[1].load() != nullptr); }
@@ -473,25 +474,36 @@ void PWMOut::update_current_rate()
int PWMOut::task_spawn(int argc, char *argv[]) int PWMOut::task_spawn(int argc, char *argv[])
{ {
for (int instance = 0; instance < PWM_OUT_MAX_INSTANCES; instance++) { for (unsigned instance = 0; instance < (sizeof(_objects) / sizeof(_objects[0])); instance++) {
uint8_t base = instance * 8; // TODO: configurable
PWMOut *dev = new PWMOut(instance, base);
if (dev) { if (instance < PWM_OUT_MAX_INSTANCES) {
_objects[instance].store(dev); uint8_t base = instance * 8; // TODO: configurable
PWMOut *dev = new PWMOut(instance, base);
if (dev->init() != PX4_OK) { if (dev) {
PX4_ERR("%d - init failed", instance); _objects[instance].store(dev);
delete dev;
_objects[instance].store(nullptr); if (dev->init() != PX4_OK) {
return PX4_ERROR; PX4_ERR("%d - init failed", instance);
delete dev;
_objects[instance].store(nullptr);
return PX4_ERROR;
}
} else {
PX4_ERR("alloc failed");
} }
} else { } else {
PX4_ERR("alloc failed"); // This hardware platform does not support
// this many devices, set the storage to
// a sane default
_objects[instance].store(nullptr);
} }
} }
_pwm_out_started = true;
return PX4_OK; return PX4_OK;
} }
@@ -1984,7 +1996,8 @@ int PWMOut::custom_command(int argc, char *argv[])
/* start pwm_out if not running */ /* start pwm_out if not running */
if (_objects[0].load() == nullptr) { if (!_pwm_out_started) {
int ret = PWMOut::task_spawn(argc, argv); int ret = PWMOut::task_spawn(argc, argv);
if (ret) { if (ret) {
@@ -2244,7 +2257,13 @@ extern "C" __EXPORT int pwm_out_main(int argc, char *argv[])
} }
if (strcmp(argv[1], "start") == 0) { if (strcmp(argv[1], "start") == 0) {
if (_pwm_out_started) {
return 0;
}
int ret = 0; int ret = 0;
PWMOut::lock_module(); PWMOut::lock_module();
ret = PWMOut::task_spawn(argc - 1, argv + 1); ret = PWMOut::task_spawn(argc - 1, argv + 1);
@@ -2324,6 +2343,8 @@ extern "C" __EXPORT int pwm_out_main(int argc, char *argv[])
} }
} }
_pwm_out_started = false;
PWMOut::unlock_module(); PWMOut::unlock_module();
return PX4_OK; return PX4_OK;
} }