gps: use px4::atomic instead of volatile

This commit is contained in:
Beat Küng
2020-08-27 16:18:22 +02:00
committed by Daniel Agar
parent e906106ea2
commit 2b0396d5df
+20 -19
View File
@@ -50,6 +50,7 @@
#include <lib/parameters/param.h> #include <lib/parameters/param.h>
#include <mathlib/mathlib.h> #include <mathlib/mathlib.h>
#include <matrix/math.hpp> #include <matrix/math.hpp>
#include <px4_platform_common/atomic.h>
#include <px4_platform_common/cli.h> #include <px4_platform_common/cli.h>
#include <px4_platform_common/getopt.h> #include <px4_platform_common/getopt.h>
#include <px4_platform_common/module.h> #include <px4_platform_common/module.h>
@@ -179,12 +180,12 @@ private:
gps_dump_s *_dump_from_device{nullptr}; gps_dump_s *_dump_from_device{nullptr};
bool _should_dump_communication{false}; ///< if true, dump communication bool _should_dump_communication{false}; ///< if true, dump communication
static volatile bool _is_gps_main_advertised; ///< for the second gps we want to make sure that it gets instance 1 static px4::atomic_bool _is_gps_main_advertised; ///< for the second gps we want to make sure that it gets instance 1
/// and thus we wait until the first one publishes at least one message. /// and thus we wait until the first one publishes at least one message.
static volatile GPS *_secondary_instance; static px4::atomic<GPS *> _secondary_instance;
volatile GPSRestartType _scheduled_reset{GPSRestartType::None}; px4::atomic<int> _scheduled_reset{(int)GPSRestartType::None};
/** /**
* Publish the gps struct * Publish the gps struct
@@ -243,8 +244,8 @@ private:
void initializeCommunicationDump(); void initializeCommunicationDump();
}; };
volatile bool GPS::_is_gps_main_advertised = false; px4::atomic_bool GPS::_is_gps_main_advertised{false};
volatile GPS *GPS::_secondary_instance = nullptr; px4::atomic<GPS *> GPS::_secondary_instance{nullptr};
/* /*
* Driver 'main' command. * Driver 'main' command.
@@ -280,7 +281,7 @@ GPS::GPS(const char *path, gps_driver_mode_t mode, GPSHelper::Interface interfac
GPS::~GPS() GPS::~GPS()
{ {
GPS *secondary_instance = (GPS *) _secondary_instance; GPS *secondary_instance = _secondary_instance.load();
if (_instance == Instance::Main && secondary_instance) { if (_instance == Instance::Main && secondary_instance) {
secondary_instance->request_stop(); secondary_instance->request_stop();
@@ -291,7 +292,7 @@ GPS::~GPS()
do { do {
px4_usleep(20000); // 20 ms px4_usleep(20000); // 20 ms
++i; ++i;
} while (_secondary_instance && i < 100); } while (_secondary_instance.load() && i < 100);
} }
delete _sat_info; delete _sat_info;
@@ -892,8 +893,8 @@ GPS::print_status()
print_message(_report_gps_pos); print_message(_report_gps_pos);
} }
if (_instance == Instance::Main && _secondary_instance) { if (_instance == Instance::Main && _secondary_instance.load()) {
GPS *secondary_instance = (GPS *)_secondary_instance; GPS *secondary_instance = _secondary_instance.load();
secondary_instance->print_status(); secondary_instance->print_status();
} }
@@ -903,10 +904,10 @@ GPS::print_status()
void void
GPS::schedule_reset(GPSRestartType restart_type) GPS::schedule_reset(GPSRestartType restart_type)
{ {
_scheduled_reset = restart_type; _scheduled_reset.store((int)restart_type);
if (_instance == Instance::Main && _secondary_instance) { if (_instance == Instance::Main && _secondary_instance.load()) {
GPS *secondary_instance = (GPS *)_secondary_instance; GPS *secondary_instance = _secondary_instance.load();
secondary_instance->schedule_reset(restart_type); secondary_instance->schedule_reset(restart_type);
} }
} }
@@ -914,10 +915,10 @@ GPS::schedule_reset(GPSRestartType restart_type)
void void
GPS::reset_if_scheduled() GPS::reset_if_scheduled()
{ {
GPSRestartType restart_type = _scheduled_reset; GPSRestartType restart_type = (GPSRestartType)_scheduled_reset.load();
if (restart_type != GPSRestartType::None) { if (restart_type != GPSRestartType::None) {
_scheduled_reset = GPSRestartType::None; _scheduled_reset.store((int)GPSRestartType::None);
int res = _helper->reset(restart_type); int res = _helper->reset(restart_type);
if (res == -1) { if (res == -1) {
@@ -935,12 +936,12 @@ GPS::reset_if_scheduled()
void void
GPS::publish() GPS::publish()
{ {
if (_instance == Instance::Main || _is_gps_main_advertised) { if (_instance == Instance::Main || _is_gps_main_advertised.load()) {
_report_gps_pos_pub.publish(_report_gps_pos); _report_gps_pos_pub.publish(_report_gps_pos);
// Heading/yaw data can be updated at a lower rate than the other navigation data. // Heading/yaw data can be updated at a lower rate than the other navigation data.
// The uORB message definition requires this data to be set to a NAN if no new valid data is available. // The uORB message definition requires this data to be set to a NAN if no new valid data is available.
_report_gps_pos.heading = NAN; _report_gps_pos.heading = NAN;
_is_gps_main_advertised = true; _is_gps_main_advertised.store(true);
} }
} }
@@ -1087,10 +1088,10 @@ int GPS::run_trampoline_secondary(int argc, char *argv[])
GPS *gps = instantiate(argc, argv, Instance::Secondary); GPS *gps = instantiate(argc, argv, Instance::Secondary);
if (gps) { if (gps) {
_secondary_instance = gps; _secondary_instance.store(gps);
gps->run(); gps->run();
_secondary_instance = nullptr; _secondary_instance.store(nullptr);
delete gps; delete gps;
} }
return 0; return 0;
@@ -1207,7 +1208,7 @@ GPS *GPS::instantiate(int argc, char *argv[], Instance instance)
/* wait up to 1s */ /* wait up to 1s */
px4_usleep(2500); px4_usleep(2500);
} while (!_secondary_instance && ++i < 400); } while (!_secondary_instance.load() && ++i < 400);
if (i == 400) { if (i == 400) {
PX4_ERR("Timed out while waiting for thread to start"); PX4_ERR("Timed out while waiting for thread to start");