예제 #1
0
    def start(self):
        GPIOUtils.setup()
        hwprofile = GPIOUtils.get_hardware_profile()

        while hwprofile is None or "HARDWARE_VERSION" not in hwprofile:
            logger.error("Fetch hardware profile failed: %s", hwprofile)

            try:
                logger.error("Re-burn firmware")
                fsrc = resource_stream("fluxmonitor", "data/mainboard.bin")
                storage = Storage("update_fw")
                with storage.open("mainboard.bin", "wb") as fdst:
                    copyfileobj(fsrc, fdst)
                GPIOUtils.update_mbfw()
            except RuntimeWarning as e:
                logger.error("%s", e.args[0])
            except Exception:
                logger.exception("Re-burn firmware failed")

            sleep(3.0)
            hwprofile = GPIOUtils.get_hardware_profile()

        self.hwprofile = hwprofile

        if get_model_id() == MODEL_D1P:
            self.gpio = PinMappingV1(self.meta)
        else:
            self.gpio = PinMappingV0(self.meta)

        self.btn_monitor = FrontButtonMonitor(self.gpio, self.kernel.loop,
                                              self.send_button_event)
        self.connect_uart()
예제 #2
0
    def on_binary(self, buf, handler):
        try:
            l = len(buf)

            if self.padding_length > l:
                self.tmpfile.write(buf)
                self.padding_length -= l

            else:
                if self.padding_length == l:
                    self.tmpfile.write(buf)
                else:
                    self.tmpfile.write(buf[:self.padding_length])
                    logger.error("Recv data length error")

                handler.binary_mode = False

                logger.info("New firmware received")
                self.tmpfile.file.flush()
                self.tmpfile.seek(0)
                s = Storage("update_fw")
                with s.open("upload.fxfw", "wb") as f:
                    f.write(self.tmpfile.read())

                proc = Popen(["fxupdate.py", "--dryrun", self.tmpfile.name])
                self.subwatcher = self.stack.loop.child(
                    proc.pid, False, self.on_verified, (handler, proc))
                self.subwatcher.start()

        except RuntimeError as e:
            handler.send_text(("error %s" % e.args[0]).encode())
        except Exception:
            logger.exception("Unhandle Error")
            handler.send_text("error %s" % UNKNOWN_ERROR)
예제 #3
0
    def on_binary(self, buf, handler):
        try:
            l = len(buf)

            if self.padding_length > l:
                self.tmpfile.write(buf)
                self.padding_length -= l

            else:
                if self.padding_length == l:
                    self.tmpfile.write(buf)
                else:
                    self.tmpfile.write(buf[:self.padding_length])
                handler.binary_mode = False

                self.tmpfile.seek(0)
                s = Storage("update_fw")

                with s.open("head.bin", "wb") as f:
                    f.write(self.tmpfile.read())

                logger.info("Head fireware uploaded, start processing")
                handler.send_text("ok")
                self.process_update(handler)
                # Note: self.process_update will invoke self.stack.exit_task
        except RuntimeError as e:
            handler.send_text(("error %s" % e.args[0]).encode())
        except Exception:
            logger.exception("Unhandle Error")
            handler.send_text("error " + UNKNOWN_ERROR)
예제 #4
0
    def on_binary(self, buf, handler):
        try:
            l = len(buf)

            if self.padding_length > l:
                self.tmpfile.write(buf)
                self.padding_length -= l

            else:
                if self.padding_length == l:
                    self.tmpfile.write(buf)
                else:
                    self.tmpfile.write(buf[:self.padding_length])
                handler.binary_mode = False

                self.tmpfile.seek(0)
                s = Storage("update_fw")

                with s.open("mainboard.bin", "wb") as f:
                    f.write(self.tmpfile.read())

                logging.warn("Fireware uploaded, start processing")
                self.send_upload_request()
                handler.send_text("ok")

                self.stack.exit_task(self, True)
        except RuntimeError as e:
            handler.send_text(("error %s" % e.args[0]).encode())
        except Exception:
            logger.exception("Unhandle Error")
            handler.send_text("error %s" % UNKNOWN_ERROR)
예제 #5
0
    def update_hbfw(self, stage_cb=lambda m: None):
        raspi_uart = Serial(port="/dev/ttyAMA0",
                            baudrate=115200,
                            stopbits=1,
                            xonxoff=0,
                            rtscts=0,
                            timeout=0)

        def wait_ack(stage):
            t = time()
            while time() - t < 5.0:
                rl = select((raspi_uart, ), (), (), 5.0)[0]
                if rl:
                    ret = raspi_uart.read(1)
                    if ret == 'y':
                        return
                    elif ret == '\x1f':
                        raise RuntimeError(SUBSYSTEM_ERROR, "HEAD RETURN 0x1f")
                    else:
                        raise RuntimeError(UNKNOWN_ERROR,
                                           "HEAD RETURN %s" % repr(ret))
            raise RuntimeError(NO_RESPONSE, stage)

        def send_cmd(cmd, stage):
            raspi_uart.write(chr(cmd))
            raspi_uart.write(chr(cmd ^ 0xFF))
            wait_ack(stage)
            sleep(0.1)

        def crc8(msg, init=0):
            crc = init
            for c in msg:
                crc = crc ^ ord(c)
            return chr(crc)

        def bootloader_hello():
            raspi_uart.write('\x7f')
            wait_ack("HELLO")

        logger.debug("Update head fw")
        storage = Storage("update_fw")
        if not storage.exists("head.bin"):
            raise RuntimeError(NOT_FOUND)

        with storage.open("head.bin", "rb") as f:
            fw = f.read()

        size = len(fw)
        pages = size // 2048
        if size % 2048 > 0:
            pages += 1
        logger.debug("Fw size=%i, use page=%i", size, pages)

        try:
            # Bootstrap
            stage_cb(b"B")

            raspi_uart.parity = PARITY_EVEN

            GPIO.output(self.TOOLHEAD_POWER, self.TOOLHEAD_POWER_OFF)
            GPIO.output(self.TOOLHEAD_BOOT, GPIO.HIGH)
            sleep(0.5)

            GPIO.output(self.TOOLHEAD_POWER, self.TOOLHEAD_POWER_ON)
            sleep(0.5)

            raspi_uart.setRTS(0)
            raspi_uart.setDTR(0)
            sleep(0.1)
            raspi_uart.setDTR(1)
            sleep(0.5)

            # Hello
            stage_cb(b"H")

            try:
                bootloader_hello()
            except Exception:
                sleep(0.5)
                bootloader_hello()

            send_cmd(0x00, "G_VR")
            l = ord(raspi_uart.read())
            version = raspi_uart.read(1)
            a = raspi_uart.read(l)
            logger.debug("VER %s", repr(a))
            wait_ack("G_VRL")
            logger.debug("Update head: bootloader ver=%s", version)
            if version != '1':
                raise RuntimeError(NOT_SUPPORT)

            # Earse
            stage_cb(b"E")

            send_cmd(0x44, "G_ERASE")
            cmd = struct.pack(">H", pages - 1)
            cmd += "".join([struct.pack(">H", i) for i in xrange(pages)])
            raspi_uart.write(cmd)
            raspi_uart.write(crc8(cmd))
            wait_ack("G_E")

            # Write
            stage_cb(b"W")
            offset = 0
            while offset < size:
                stage_cb(("%07x" % (size - offset)).encode())
                l = min(size - offset, 128)
                send_cmd(0x31, "G_WINIT")
                addr = struct.pack(">I", 0x08000000 + offset)
                raspi_uart.write(addr)
                raspi_uart.write(crc8(addr))
                wait_ack("G_WREADY")
                payload = chr(l - 1) + fw[offset:offset + l]
                raspi_uart.write(payload)
                raspi_uart.write(crc8(payload))
                wait_ack("G_WDONE")
                offset += l

            stage_cb("00000000")
        finally:
            GPIO.output(self.TOOLHEAD_BOOT, GPIO.LOW)
            GPIO.output(self.TOOLHEAD_POWER, self.TOOLHEAD_POWER_OFF)
            sleep(0.5)
            GPIO.output(self.TOOLHEAD_POWER, self._head_power_stat)
            raspi_uart.parity = PARITY_NONE
            raspi_uart.close()

        logger.debug("Update fw end")