mirror of
https://github.com/ArduPilot/ardupilot.git
synced 2026-10-02 10:23:25 +08:00
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:
committed by
Peter Barker
parent
c05eb925b1
commit
94800d5ae6
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user