Browse Source

fix pwm_out: avoid race condition when setting mode

Bootup failed in some cases with:
ERROR [mixer] can't reset mixers on /dev/pwm_output1

The reason was the mode change was not applied yet.
release/1.12
Beat Küng 4 years ago committed by Lorenz Meier
parent
commit
faaee0f077
  1. 20
      src/drivers/pwm_out/PWMOut.cpp
  2. 6
      src/drivers/pwm_out/PWMOut.hpp

20
src/drivers/pwm_out/PWMOut.cpp

@ -580,9 +580,9 @@ void PWMOut::Run() @@ -580,9 +580,9 @@ void PWMOut::Run()
// push backup schedule
ScheduleDelayed(_backup_schedule_interval_us);
if (_new_mode_request.load() != _mode) {
if (_new_mode_request.load() != MODE_NO_REQUEST) {
set_mode(_new_mode_request.load());
_new_mode_request.store(_mode);
_new_mode_request.store(MODE_NO_REQUEST);
}
_mixing_output.update();
@ -1762,6 +1762,22 @@ int PWMOut::fmu_new_mode(PortMode new_mode) @@ -1762,6 +1762,22 @@ int PWMOut::fmu_new_mode(PortMode new_mode)
return OK;
}
void PWMOut::request_mode(Mode new_mode)
{
if (_new_mode_request.load() != MODE_NO_REQUEST) {
PX4_ERR("already being set"); // not expected to happen
return;
}
_new_mode_request.store(new_mode);
ScheduleNow();
// wait until processed
int max_time = 1000;
while (_new_mode_request.load() != MODE_NO_REQUEST && max_time-- > 0) {
px4_usleep(1000);
}
}
namespace
{

6
src/drivers/pwm_out/PWMOut.hpp

@ -118,6 +118,8 @@ public: @@ -118,6 +118,8 @@ public:
MODE_4CAP,
MODE_5CAP,
MODE_6CAP,
MODE_NO_REQUEST
};
PWMOut() = delete;
@ -157,7 +159,7 @@ public: @@ -157,7 +159,7 @@ public:
int set_mode(Mode mode);
Mode get_mode() { return _mode; }
void request_mode(Mode new_mode) { _new_mode_request.store(new_mode); }
void request_mode(Mode new_mode);
static int set_i2c_bus_clock(unsigned bus, unsigned clock_hz);
@ -181,7 +183,7 @@ private: @@ -181,7 +183,7 @@ private:
Mode _mode{MODE_NONE};
px4::atomic<Mode> _new_mode_request{MODE_NONE};
px4::atomic<Mode> _new_mode_request{MODE_NO_REQUEST};
uint32_t _backup_schedule_interval_us{1_s};

Loading…
Cancel
Save