From a9a5f3a19ecc2a85cfc87d4a95e8f7c9951c5645 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Wed, 13 Jul 2016 14:37:01 +0200 Subject: [PATCH] px4io: add FMU fail test mode In order to test what happens in px4iofirmware when the FMU stops sending PWM or control commands, I added a test mode. When the test mode is activated, no controls are sent. --- src/drivers/px4io/px4io.cpp | 62 ++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index e97b8db898..4d6cf7d449 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -218,6 +218,16 @@ public: */ int print_debug(); + /* + * To test what happens if IO stops receiving updates from FMU. + * + * @param is_fail true for failure condition, false for normal operation. + */ + void test_fmu_fail(bool is_fail) + { + _test_fmu_fail = is_fail; + }; + #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1 /** * Set the DSM VCC is controlled by relay one flag @@ -315,6 +325,7 @@ private: float _analog_rc_rssi_volt; ///< analog RSSI voltage float _last_throttle; ///< last throttle value for battery calculation + bool _test_fmu_fail; ///< To test what happens if IO looses FMU #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1 bool _dsm_vcc_ctl; ///< true if relay 1 controls DSM satellite RX power @@ -549,7 +560,8 @@ PX4IO::PX4IO(device::Device *interface) : _rssi_pwm_min(0), _analog_rc_rssi_stable(false), _analog_rc_rssi_volt(-1.0f), - _last_throttle(0.0f) + _last_throttle(0.0f), + _test_fmu_fail(false) #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1 , _dsm_vcc_ctl(false) #endif @@ -1349,8 +1361,12 @@ PX4IO::io_set_control_state(unsigned group) _last_throttle = controls.control[3]; } - /* copy values to registers in IO */ - return io_reg_set(PX4IO_PAGE_CONTROLS, group * PX4IO_PROTOCOL_MAX_CONTROL_COUNT, regs, _max_controls); + if (!_test_fmu_fail) { + /* copy values to registers in IO */ + return io_reg_set(PX4IO_PAGE_CONTROLS, group * PX4IO_PROTOCOL_MAX_CONTROL_COUNT, regs, _max_controls); + } else { + return OK; + } } @@ -2735,8 +2751,14 @@ PX4IO::ioctl(file *filep, int cmd, unsigned long arg) ret = -EINVAL; } else { - /* send a direct PWM value */ - ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, channel, arg); + if (!_test_fmu_fail) { + /* send a direct PWM value */ + ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, channel, arg); + } else { + /* Just silently accept the ioctl without doing anything + * in test mode. */ + ret = OK; + } } break; @@ -3037,7 +3059,12 @@ PX4IO::write(file * /*filp*/, const char *buffer, size_t len) if (count > 0) { perf_begin(_perf_write); - int ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, (uint16_t *)buffer, count); + + int ret = OK; + /* The write() is silently ignored in test mode. */ + if (!_test_fmu_fail) { + ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, (uint16_t *)buffer, count); + } perf_end(_perf_write); if (ret != OK) { @@ -3869,8 +3896,29 @@ px4io_main(int argc, char *argv[]) exit(0); } + if (!strcmp(argv[1], "test_fmu_fail")) { + if (g_dev != nullptr) { + g_dev->test_fmu_fail(true); + exit(0); + } else { + + errx(1, "px4io must be started first"); + } + } + + if (!strcmp(argv[1], "test_fmu_ok")) { + if (g_dev != nullptr) { + g_dev->test_fmu_fail(false); + exit(0); + } else { + + errx(1, "px4io must be started first"); + } + } + out: errx(1, "need a command, try 'start', 'stop', 'status', 'test', 'monitor', 'debug ',\n" "'recovery', 'limit ', 'current', 'bind', 'checkcrc', 'safety_on', 'safety_off',\n" - "'forceupdate', 'update', 'sbus1_out', 'sbus2_out', 'rssi_analog' or 'rssi_pwm'"); + "'forceupdate', 'update', 'sbus1_out', 'sbus2_out', 'rssi_analog' or 'rssi_pwm',\n" + "'test_fmu_fail', 'test_fmu_ok'"); }