/* discard any pending bytes */ void AP_IOMCU::drain(void) { uint8_t c; bool ret; do { ret = recv_byte_with_timeout(&c, 40); } while (ret); }
int PX4IO_Uploader::recv_bytes(uint8_t *p, unsigned count) { int ret = OK; while (count--) { ret = recv_byte_with_timeout(p++, 5000); if (ret != OK) break; } return ret; }
/* wait for bootloader protocol sync */ bool AP_IOMCU::get_sync(uint32_t timeout_ms) { uint8_t c[2]; bool ret; ret = recv_byte_with_timeout(c, timeout_ms); if (!ret) { return false; } ret = recv_byte_with_timeout(c + 1, timeout_ms); if (!ret) { return ret; } if ((c[0] != PROTO_INSYNC) || (c[1] != PROTO_OK)) { debug("bad sync 0x%02x,0x%02x", c[0], c[1]); return false; } return true; }
/* receive multiple bytes from the bootloader */ bool AP_IOMCU::recv_bytes(uint8_t *p, uint32_t count) { bool ret = true; while (count--) { ret = recv_byte_with_timeout(p++, 5000); if (!ret) { break; } } return ret; }
/* verify firmware for a rev2 bootloader */ bool AP_IOMCU::verify_rev2(uint32_t fw_size) { ssize_t count; bool ret; size_t sent = 0; debug("verify..."); send(PROTO_CHIP_VERIFY); send(PROTO_EOC); ret = get_sync(); if (!ret) { return ret; } while (sent < fw_size) { /* get more bytes to verify */ uint32_t n = fw_size - sent; if (n > 4) { n = 4; } send(PROTO_READ_MULTI); send(n); send(PROTO_EOC); for (uint8_t i = 0; i<n; i++) { uint8_t c; ret = recv_byte_with_timeout(&c, 5000); if (!ret) { debug("%d: got %d waiting for bytes", sent + i, ret); return ret; } if (c != fw[sent+i]) { debug("%d: got 0x%02x expected 0x%02x", sent + i, c, fw[sent+i]); return false; } } sent += count; ret = get_sync(); if (!ret) { debug("timeout waiting for post-verify sync"); return ret; } } return true; }
int PX4IO_Uploader::get_sync(unsigned timeout) { uint8_t c[2]; int ret; ret = recv_byte_with_timeout(c, timeout); if (ret != OK) return ret; ret = recv_byte_with_timeout(c + 1, timeout); if (ret != OK) return ret; if ((c[0] != PROTO_INSYNC) || (c[1] != PROTO_OK)) { log("bad sync 0x%02x,0x%02x", c[0], c[1]); return -EIO; } return OK; }
void PX4IO_Uploader::drain() { uint8_t c; int ret; do { // the small recv_bytes timeout here is to allow for fast // drain when rebooting the io board for a forced // update of the fw without using the safety switch ret = recv_byte_with_timeout(&c, 40); #ifdef UDEBUG if (ret == OK) { log("discard 0x%02x", c); } #endif } while (ret == OK); }
int PX4IO_Uploader::verify_rev2(size_t fw_size) { uint8_t file_buf[4]; ssize_t count; int ret; size_t sent = 0; log("verify..."); lseek(_fw_fd, 0, SEEK_SET); send(PROTO_CHIP_VERIFY); send(PROTO_EOC); ret = get_sync(); if (ret != OK) return ret; while (sent < fw_size) { /* get more bytes to verify */ size_t n = fw_size - sent; if (n > sizeof(file_buf)) { n = sizeof(file_buf); } count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)sent, (int)count, (int)errno); } if (count == 0) break; sent += count; if (count < 0) return -errno; ASSERT((count % 4) == 0); send(PROTO_READ_MULTI); send(count); send(PROTO_EOC); for (ssize_t i = 0; i < count; i++) { uint8_t c; ret = recv_byte_with_timeout(&c, 5000); if (ret != OK) { log("%d: got %d waiting for bytes", sent + i, ret); return ret; } if (c != file_buf[i]) { log("%d: got 0x%02x expected 0x%02x", sent + i, c, file_buf[i]); return -EINVAL; } } ret = get_sync(); if (ret != OK) { log("timeout waiting for post-verify sync"); return ret; } } return OK; }