AP_HAL_SITL: prepare for reboot at the HAL rc output level

ensures that the 0s get to the hardware

significantly reduces the race conditions which might allow a thread to write after values are zeroed
This commit is contained in:
Peter Barker
2026-09-18 00:10:02 +10:00
committed by Peter Barker
parent c05eb925b1
commit 94800d5ae6
2 changed files with 30 additions and 0 deletions
+19
View File
@@ -49,6 +49,11 @@ void RCOutput::disable_ch(uint8_t ch)
void RCOutput::write(uint8_t ch, uint16_t period_us)
{
if (_outputs_frozen) {
// outputs are frozen, drop the write. See prepare_for_reboot().
return;
}
if (safety_state == AP_HAL::Util::SAFETY_DISARMED) {
const auto *board_config = AP_BoardConfig::get_singleton();
const uint32_t safety_mask = board_config != nullptr? board_config->get_safety_mask() : 0;
@@ -83,6 +88,20 @@ void RCOutput::read(uint16_t* period_us, uint8_t len)
memcpy(period_us, _sitlState->pwm_output, len * sizeof(uint16_t));
}
/*
called once a reboot has been commanded: zero the outputs and stop
accepting writes, so that nothing can drive an output over the
interval between the command and the reboot itself
*/
void RCOutput::prepare_for_reboot(void)
{
_outputs_frozen = true;
memset(_pending, 0, sizeof(_pending));
memset(_sitlState->pwm_output, 0, sizeof(_sitlState->pwm_output));
_corked = false;
}
void RCOutput::cork(void)
{
if (!_corked) {
+11
View File
@@ -19,6 +19,12 @@ public:
void cork(void) override;
void push(void) override;
/*
zero the outputs and refuse any further writes once a reboot has
been commanded
*/
void prepare_for_reboot(void) override;
/*
force the safety switch on, disabling PWM output from the IO board
*/
@@ -54,6 +60,11 @@ private:
bool _corked;
uint16_t _pending[SITL_NUM_CHANNELS];
// while set, no value reaches the outputs. Set by
// prepare_for_reboot() and never cleared; SITL re-executes rather
// than returning.
bool _outputs_frozen;
AP_HAL::Util::safety_state safety_state = AP_HAL::Util::safety_state::SAFETY_DISARMED;
};