Exemple #1
0
    def _erase_board_simple(self, target, no_reset):
        """
        :param target: target to which perform the erase
        :param no_reset: erase with/without reset
        :return: exit code
        """
        if "mount_point" not in target:
            raise EraseError(message="mount point missing from target",
                             return_code=EXIT_CODE_MOUNT_POINT_MISSING)

        if "serial_port" not in target:
            raise EraseError(message="serial port missing from target",
                             return_code=EXIT_CODE_SERIAL_PORT_MISSING)

        Erase._can_be_erased(target)

        # Copy ERASE.ACT to target mount point, this will trigger the erasing.
        destination = MbedCommon.get_binary_destination(target["mount_point"], "ERASE.ACT")
        with open(destination, "wb"):
            pass

        target = MbedCommon.wait_for_file_disappear(target, "ERASE.ACT")

        if not no_reset:
            Reset(logger=self.logger).reset_board(target["serial_port"])

        self._verify_erase_success(MbedCommon.get_binary_destination(
            target["mount_point"], "ERASE.ACT"))

        self.logger.info("erase %s completed", target["target_id"])
        return EXIT_CODE_SUCCESS
Exemple #2
0
 def _verify_erase_success(self, destination):
     """
     Verify that ERASE.ACT is not present in the target mount point.
     :param destination: target mount point
     :return: None on success, raises otherwise
     """
     if isfile(destination):
         msg = "Erase failed: ERASE.ACT still present in mount point"
         self.logger.error(msg)
         raise EraseError(message=msg, return_code=EXIT_CODE_FILE_STILL_PRESENT)
Exemple #3
0
    def erase(self, target_id=None, no_reset=None, method=None):
        """
        Erase (mbed) device(s).
        :param target_id: target_id
        :param no_reset: erase with/without reset
        :param method: method for erase i.e. simple, pyocd or edbg
        """
        if target_id is None:
            raise EraseError(message="target id is missing",
                             return_code=EXIT_CODE_TARGET_ID_MISSING)

        self.logger.info("Starting erase for given target_id %s", target_id)
        self.logger.info("method used for reset: %s", method)
        available_devices = Common(self.logger).get_available_device_mapping(
            self.flashers, target_id)

        targets_to_erase = self.prepare_target_to_erase(
            target_id, available_devices)

        if len(targets_to_erase) <= 0:
            msg = "Could not map given target_id(s) to available devices"
            raise EraseError(
                message=msg,
                return_code=EXIT_CODE_COULD_NOT_MAP_TARGET_ID_TO_DEVICE)

        for item in targets_to_erase:
            if method == 'simple':
                erase_fnc = self._erase_board_simple
            elif method == 'pyocd':
                erase_fnc = self._erase_board_with_pyocd
            elif method == 'edbg':
                raise EraseError(message="egdb not supported",
                                 return_code=EXIT_CODE_IMPLEMENTATION_MISSING)
            else:
                raise EraseError(
                    message="Selected method {} not supported".format(method),
                    return_code=EXIT_CODE_MISUSE_CMD)

            erase_fnc(target=item, no_reset=no_reset)

        return EXIT_CODE_SUCCESS
Exemple #4
0
    def reset_board(self, serial_port):
        """
        :param serial_port: board serial port
        :return: return exit code based on if successfully reset a board
        """
        from mbed_flasher.flashers.enhancedserial import EnhancedSerial
        from serial.serialutil import SerialException

        try:
            port = EnhancedSerial(serial_port)
        except SerialException as err:
            self.logger.error(err)
            # SerialException.message is type "string", it has 'find'
            #  pylint: disable=no-member
            if err.message.find('could not open port') != -1:
                self.logger.error(
                    'Reset could not be given. Close your Serial connection to device.'
                )

            raise EraseError(message="reset could not be sent",
                             return_code=EXIT_CODE_SERIAL_PORT_OPEN_FAILED)

        port.baudrate = 115200
        port.timeout = 1
        port.xonxoff = False
        port.rtscts = False
        port.flushInput()
        port.flushOutput()
        if port:
            self.logger.info("sendBreak to device to reboot")
            result = port.safe_send_break()
            if result:
                self.logger.info("reset completed")
            else:
                raise EraseError(message="reset failed",
                                 return_code=EXIT_CODE_SERIAL_RESET_FAILED)

        port.close()
        return EXIT_CODE_SUCCESS
Exemple #5
0
    def subcmd_erase_handler(self, args):
        """
        erase command handler
        """
        eraser = Erase()
        if not args.tid:
            msg = "Target_id is missing"
            raise EraseError(message=msg,
                             return_code=EXIT_CODE_TARGET_ID_MISSING)

        ids = self.parse_id_to_devices(args.tid)
        return eraser.erase(target_id=ids,
                            no_reset=args.no_reset,
                            method=args.method)
Exemple #6
0
    def _erase_board_with_pyocd(self, target, no_reset):
        try:
            from pyOCD.board import MbedBoard
            from pyOCD.pyDAPAccess import DAPAccessIntf
        except ImportError:
            raise EraseError(message="pyOCD is not installed",
                             return_code=EXIT_CODE_PYOCD_MISSING)

        target_id = target["target_id"]
        board = MbedBoard.chooseBoard(board_id=target_id)
        self.logger.info("erasing device: %s", target_id)
        ocd_target = board.target
        flash = ocd_target.flash
        try:
            flash.eraseAll()
            if not no_reset:
                ocd_target.reset()
        except DAPAccessIntf.TransferFaultError as error:
            raise EraseError(message=error,
                             return_code=EXIT_CODE_PYOCD_ERASE_FAILED)

        self.logger.info("erase completed for target: %s", target_id)
        return EXIT_CODE_SUCCESS
Exemple #7
0
    def _can_be_erased(target):
        """
        Check if target can be erased.
        :param target: target board to be checked
        :return: None if can be erased, raises otherwise
        """
        try:
            with open(join(target["mount_point"], 'DETAILS.TXT'), 'rb') as new_file:
                details_txt = new_file.readlines()
        except (OSError, IOError):
            raise EraseError(message="No DETAILS.TXT found",
                             return_code=EXIT_CODE_IMPLEMENTATION_MISSING)

        automation_activated = False
        daplink_version = 0
        for line in details_txt:
            if line.find(b"Automation allowed: 1") != -1:
                automation_activated = True
            if line.find(b"Interface Version") != -1:
                try:
                    if six.PY2:
                        daplink_version = int(line.split(' ')[-1])
                    else:
                        daplink_version = int(line.decode('utf-8').split(' ')[-1])
                except (IndexError, ValueError):
                    raise EraseError(message="Failed to parse DAPLINK version from DETAILS.TXT",
                                     return_code=EXIT_CODE_IMPLEMENTATION_MISSING)

        if not automation_activated:
            msg = "Selected device does not have automation activated in DAPLINK"
            raise EraseError(message=msg, return_code=EXIT_CODE_IMPLEMENTATION_MISSING)

        if daplink_version < ERASE_DAPLINK_SUPPORT_VERSION:
            msg = "Selected device has Daplink version {}," \
                  "erasing supported from version {} onwards". \
                format(daplink_version, ERASE_DAPLINK_SUPPORT_VERSION)
            raise EraseError(message=msg, return_code=EXIT_CODE_IMPLEMENTATION_MISSING)
Exemple #8
0
    def subcmd_erase_handler(self, args):
        """
        erase command handler
        """
        eraser = Erase()
        if args.tid:
            ids = self.parse_id_to_devices(args.tid)
            if isinstance(ids, int):
                retcode = ids
            else:
                retcode = eraser.erase(target_id=ids,
                                       no_reset=args.no_reset,
                                       method=args.method)
        else:
            msg = "Target_id is missing"
            print(msg)
            raise EraseError(message=msg,
                             return_code=EXIT_CODE_TARGET_ID_MISSING)

        return retcode
Exemple #9
0
    def test_can_be_risen(self):
        with self.assertRaises(FlashError) as cm:
            raise EraseError(message="test", return_code=0)

        self.assertEqual(cm.exception.message, "test")
        self.assertEqual(cm.exception.return_code, 0)
Exemple #10
0
    def _erase_board_simple(self, target, no_reset):
        """
        :param target: target to which perform the erase
        :param no_reset: erase with/without reset
        :return: exit code
        """
        if 'mount_point' not in target:
            raise EraseError(message="mount point missing from target",
                             return_code=EXIT_CODE_MOUNT_POINT_MISSING)
        if 'serial_port' not in target:
            raise EraseError(message="serial port missing from target",
                             return_code=EXIT_CODE_SERIAL_PORT_MISSING)

        automation_activated = False
        daplink_version = 0
        if not isfile(join(target["mount_point"], 'DETAILS.TXT')):
            raise EraseError(message="No DETAILS.TXT found",
                             return_code=EXIT_CODE_IMPLEMENTATION_MISSING)

        self.logger.debug(join(target["mount_point"], 'DETAILS.TXT'))
        with open(join(target["mount_point"], 'DETAILS.TXT'),
                  'rb') as new_file:
            for line in new_file:
                if line.find(b"Automation allowed: 1") != -1:
                    automation_activated = True
                if line.find(b"Interface Version") != -1:
                    try:
                        if six.PY2:
                            daplink_version = int(line.split(' ')[-1])
                        else:
                            daplink_version = int(
                                line.decode('utf-8').split(' ')[-1])
                    except (IndexError, ValueError):
                        raise EraseError(
                            message=
                            "Failed to parse DAPLINK version from DETAILS.TXT",
                            return_code=EXIT_CODE_IMPLEMENTATION_MISSING)

        if not automation_activated:
            msg = "Selected device does not have automation activated in DAPLINK"
            raise EraseError(message=msg,
                             return_code=EXIT_CODE_IMPLEMENTATION_MISSING)

        if daplink_version < ERASE_DAPLINK_SUPPORT_VERSION:
            msg = "Selected device has Daplink version {}," \
                  "erasing supported from version {} onwards".\
                format(daplink_version, ERASE_DAPLINK_SUPPORT_VERSION)
            raise EraseError(message=msg,
                             return_code=EXIT_CODE_IMPLEMENTATION_MISSING)

        with open(join(target["mount_point"], 'ERASE.ACT'), 'wb'):
            pass

        auto_thread = Thread(target=self.wait_to_disappear,
                             args=(target["mount_point"], ))
        auto_thread.start()
        while auto_thread.is_alive():
            auto_thread.join(0.5)

        target = FlasherMbed.refresh_target(target["target_id"])
        if not target:
            raise EraseError(message="target id is missing",
                             return_code=EXIT_CODE_TARGET_ID_MISSING)

        auto_thread = Thread(target=self.runner,
                             args=(target["mount_point"], 'ERASE.ACT'))
        auto_thread.start()
        while auto_thread.is_alive():
            auto_thread.join(0.5)

        if not no_reset:
            success = self.reset_board(target["serial_port"])
            if success != 0:
                raise EraseError(message="erase failed", return_code=success)

        self.logger.info("erase %s completed", target['target_id'])
        return EXIT_CODE_SUCCESS