PX4 IO: Retry upgrades of IO

This adds robustness to system timing and bad link.
This commit is contained in:
Lorenz Meier
2021-02-20 11:07:53 +01:00
parent ed20bc92c3
commit 4984c19700
+25 -10
View File
@@ -2960,7 +2960,7 @@ PX4IO::ioctl(file *filep, int cmd, unsigned long arg)
} }
/* reboot into bootloader - arg must be PX4IO_REBOOT_BL_MAGIC */ /* reboot into bootloader - arg must be PX4IO_REBOOT_BL_MAGIC */
usleep(1); usleep(50);
io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_REBOOT_BL, arg); io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_REBOOT_BL, arg);
// we don't expect a reply from this operation // we don't expect a reply from this operation
ret = OK; ret = OK;
@@ -3451,13 +3451,22 @@ px4io_main(int argc, char *argv[])
the user to hold the safety switch down the user to hold the safety switch down
*/ */
if (argc <= 3) { if (argc <= 3) {
warnx("usage: px4io forceupdate MAGIC filename"); PX4_WARN("usage: px4io forceupdate MAGIC filename");
exit(1); exit(1);
} }
if (g_dev == nullptr) { uint16_t arg = atol(argv[2]);
warnx("px4io is not started, still attempting upgrade"); constexpr unsigned MAX_RETRIES = 5;
unsigned retries = 0;
int ret = PX4_ERROR;
while (ret != OK && retries < MAX_RETRIES) {
retries++;
// Sleep 200 ms before the next attempt
usleep(200 * 1000);
if (g_dev == nullptr) {
/* allocate the interface */ /* allocate the interface */
device::Device *interface = get_interface(); device::Device *interface = get_interface();
@@ -3470,11 +3479,11 @@ px4io_main(int argc, char *argv[])
} }
} }
uint16_t arg = atol(argv[2]); // Try to reboot
int ret = g_dev->ioctl(nullptr, PX4IO_REBOOT_BOOTLOADER, arg); ret = g_dev->ioctl(nullptr, PX4IO_REBOOT_BOOTLOADER, arg);
if (ret != OK) { if (ret != OK) {
warnx("reboot failed - %d", ret); PX4_WARN("reboot failed - %d", ret);
exit(1); exit(1);
} }
@@ -3487,9 +3496,15 @@ px4io_main(int argc, char *argv[])
fn[0] = argv[3]; fn[0] = argv[3];
fn[1] = nullptr; fn[1] = nullptr;
PX4IO_Uploader *up = new PX4IO_Uploader; PX4IO_Uploader *up = new PX4IO_Uploader;
up->upload(&fn[0]);
// Upload and retry if it fails
ret = up->upload(&fn[0]);
delete up; delete up;
exit(0); }
PX4_INFO("IO update: %s, retries: %d (reboot)", (ret == OK) ? "done" : "failed", retries);
exit(ret);
} }
/* commands below here require a started driver */ /* commands below here require a started driver */
@@ -3671,6 +3686,6 @@ px4io_main(int argc, char *argv[])
out: out:
errx(1, "need a command, try 'start', 'stop', 'status', 'monitor', 'debug <level>',\n" errx(1, "need a command, try 'start', 'stop', 'status', 'monitor', 'debug <level>',\n"
"'recovery', 'bind', 'checkcrc', 'safety_on', 'safety_off',\n" "'recovery', 'bind', 'checkcrc', 'safety_on', 'safety_off',\n"
"'forceupdate', 'update', 'sbus1_out', 'sbus2_out', 'rssi_analog' or 'rssi_pwm',\n" "'forceupdate 14662', 'sbus1_out', 'sbus2_out', 'rssi_analog' or 'rssi_pwm',\n"
"'test_fmu_fail', 'test_fmu_ok'"); "'test_fmu_fail', 'test_fmu_ok'");
} }