Example #1
0
    def copy_file(self, source, destination):
        """
        copy file from os
        """
        self.logger.debug('read source file')
        try:
            with open(source, 'rb') as source_file:
                aux_source = source_file.read()
        except (IOError, OSError):
            self.logger.exception("File couldn't be read")
            raise FlashError(message="File couldn't be read",
                             return_code=EXIT_CODE_FILE_COULD_NOT_BE_READ)

        self.logger.debug("SHA1: %s", hashlib.sha1(aux_source).hexdigest())

        self.logger.debug("writing binary: %s (size=%i bytes)", destination, len(aux_source))
        try:
            with open(destination, "wb", 0) as new_file:
                new_file.write(aux_source)
                new_file.flush()
                os.fsync(new_file.fileno())
        except (IOError, OSError):
            self.logger.exception("File couldn't be copied")
            raise FlashError(message="File couldn't be copied",
                             return_code=EXIT_CODE_OS_ERROR)
Example #2
0
    def try_pyocd_flash(self, source, target):
        """
        try pyOCD flash
        """
        try:
            from pyOCD.board import MbedBoard
        except ImportError:
            # python 3 compatibility
            # pylint: disable=superfluous-parens
            raise FlashError(message="PyOCD is missing",
                             return_code=EXIT_CODE_PYOCD_NOT_INSTALLED)

        try:
            with MbedBoard.chooseBoard(board_id=target["target_id"]) as board:
                ocd_target = board.target
                ocd_flash = board.flash
                self.logger.debug("resetting device: %s", target["target_id"])
                sleep(0.5)  # small sleep for lesser HW ie raspberry
                ocd_target.reset()
                self.logger.debug("flashing device: %s", target["target_id"])
                ocd_flash.flashBinary(source)
                self.logger.debug("resetting device: %s", target["target_id"])
                sleep(0.5)  # small sleep for lesser HW ie raspberry
                ocd_target.reset()
            return EXIT_CODE_SUCCESS
        except AttributeError as err:
            msg = "Flashing failed: {}. tid={}".format(err, target["target_id"])
            self.logger.error(msg)
            raise FlashError(message="PyOCD flash failed",
                             return_code=EXIT_CODE_FLASH_FAILED)
Example #3
0
 def _do_flash(flasher, build, target, method, no_reset):
     try:
         return flasher.flash(
             source=build, target=target, method=method, no_reset=no_reset)
     except KeyboardInterrupt:
         raise FlashError(message="Aborted by user",
                          return_code=EXIT_CODE_KEYBOARD_INTERRUPT)
     except SystemExit:
         raise FlashError(message="Aborted by SystemExit event",
                          return_code=EXIT_CODE_SYSTEM_INTERRUPT)
Example #4
0
    def flash(self, source, target, method, no_reset, target_filename=None):
        """flash device
        :param source: binary to be flashed
        :param target: target to be flashed
        :param method: method to use when flashing
        :param no_reset: do not reset flashed board at all
        :param target_filename: target filename (not in use)
        :return: 0 when flashing success
        """

        cmd_script = tempfile.NamedTemporaryFile(delete=False)
        FlasherJLink._write_file_contents(cmd_script, source, no_reset)
        cmd_script.close()

        def remove_commander_script():
            """
            Removes the temporary file. Cannot use delete=True for NamedTemporaryFile
            since Windows doesn't allow another program to read it while not closed.
            """
            os.remove(cmd_script.name)

        try:
            args = [
                FlasherJLink.executable,
                "-if", "swd",
                "-speed", "auto",
                "-device", target["jlink_device_name"],
                "-SelectEmuBySN", target["target_id"],
                "-commanderscript", cmd_script.name
            ]
        except KeyError:
            remove_commander_script()
            raise FlashError(message="Invalid target", return_code=EXIT_CODE_FLASH_FAILED)

        try:
            self.logger.info("Flashing {} with command {}".format(target["target_id"], args))
            returncode, output = self._start_and_wait_flash(args, FlasherJLink.executable)
        except queue.Empty:
            raise FlashError(message="No returncode from JLinkExe",
                             return_code=EXIT_CODE_FLASH_FAILED)
        finally:
            remove_commander_script()

        if returncode != 0:
            self.logger.error("Flash of {} failed, with returncode {}"
                              .format(target["target_id"], returncode))
            msg = "Flash failed with JLink return code: {}".format(returncode)
            raise FlashError(message=msg, return_code=EXIT_CODE_FLASH_FAILED)

        self.logger.info("Flash of {} succeeded".format(target["target_id"]))
        self.logger.debug(output)
        return EXIT_CODE_SUCCESS
Example #5
0
    def copy_file(self, source, destination):
        """
        copy file from os
        """
        self.logger.debug('read source file')
        with open(source, 'rb') as source_file:
            aux_source = source_file.read()

        if not aux_source:
            raise FlashError(message="File couldn't be read",
                             return_code=EXIT_CODE_FILE_COULD_NOT_BE_READ)

        self.logger.debug("SHA1: %s", hashlib.sha1(aux_source).hexdigest())

        if platform.system() == 'Windows':
            self.logger.debug("copying file: \"%s\" to \"%s\"", source,
                              destination)
            os.system("copy \"%s\" \"%s\"" %
                      (os.path.abspath(source), destination))
        else:
            self.logger.debug("writing binary: %s (size=%i bytes)",
                              destination, len(aux_source))
            new_file = self.get_file(destination)
            os.write(new_file, aux_source)
            os.close(new_file)
Example #6
0
    def flash(self, source, target, method, no_reset):
        """copy file to the destination
        :param source: binary to be flashed
        :param target: target to be flashed
        :param method: method to use when flashing
        :param no_reset: do not reset flashed board at all
        """
        if not isinstance(source, six.string_types):
            return

        if method == 'pyocd':
            self.logger.debug("pyOCD selected for flashing")
            return self.try_pyocd_flash(source, target)

        if method == 'edbg':
            raise FlashError(message="edbg is not supported for Mbed devices",
                             return_code=EXIT_CODE_EGDB_NOT_SUPPORTED)

        return retry(
            logger=self.logger,
            func=self.try_drag_and_drop_flash,
            func_args=(source, target, no_reset),
            retries=FlasherMbed.DRAG_AND_DROP_FLASH_RETRIES,
            conditions=[EXIT_CODE_OS_ERROR,
                        EXIT_CODE_DAPLINK_TRANSIENT_ERROR,
                        EXIT_CODE_DAPLINK_SOFTWARE_ERROR])
Example #7
0
 def test_flash_fails(self, mock_build, mock_flasher, mocked_logger,
                      mock_inspect, mock_bench_logger):
     mock_build_object = mock.MagicMock()
     mock_build_object.get_file = mock.MagicMock(return_value="Thisbin")
     mock_build.init = mock.MagicMock(return_value=mock_build_object)
     mock_inspect.return_value = MockArgspec(["logger"])
     mocked_logger_for_flasher = mock.MagicMock()
     mocked_logger.return_value = mocked_logger_for_flasher
     mock_flasher_object = mock.MagicMock()
     mock_flasher.return_value = mock_flasher_object
     mock_flasher_object.flash = mock.MagicMock()
     mock_flasher_object.flash.side_effect = [
         NotImplementedError, SyntaxError, 1
     ]
     if FlashError is not None:
         mock_flasher_object.flash.side_effect = [
             NotImplementedError, SyntaxError, 1,
             FlashError("Error", 10)
         ]
     dut = DutSerial(port="test",
                     config={
                         "allocated": {
                             "target_id": "thing"
                         },
                         "application": "thing"
                     })
     with self.assertRaises(DutConnectionError):
         dut.flash("try")
     with self.assertRaises(DutConnectionError):
         dut.flash("try2")
     self.assertFalse(dut.flash("try3"))
     if FlashError is not None:
         with self.assertRaises(DutConnectionError):
             dut.flash("try4")
Example #8
0
    def flash_multiple(self,
                       build,
                       platform_name,
                       method='simple',
                       target_ids_or_prefix='',
                       no_reset=None):
        """
        :param build: build
        :param platform_name: platform name
        :param method: method
        :param target_ids_or_prefix: target ids or prefix
        :param no_reset: with/without reset
        :return:
        """
        device_mapping_table = Common(
            self.logger).get_available_device_mapping(self._flashers)

        if not platform_name:
            Flash._verify_platform_coherence(device_mapping_table)

        if isinstance(target_ids_or_prefix, list):
            aux_device_mapping_table = Flash._map_by_target_id(
                device_mapping_table=device_mapping_table,
                platform_name=platform_name,
                target_ids=target_ids_or_prefix)
        elif target_ids_or_prefix:
            aux_device_mapping_table = Flash._map_by_prefix(
                device_mapping_table=device_mapping_table,
                platform_name=platform_name,
                prefix=target_ids_or_prefix)
        else:
            aux_device_mapping_table = Flash._map_by_platform(
                device_mapping_table=device_mapping_table,
                platform_name=platform_name)

        if aux_device_mapping_table:
            device_mapping_table = aux_device_mapping_table

        if not device_mapping_table:
            raise FlashError(
                message="no devices to flash",
                return_code=EXIT_CODE_COULD_NOT_MAP_TARGET_ID_TO_DEVICE)

        self.logger.debug(device_mapping_table)

        self.logger.info('Going to flash following devices:')
        for item in device_mapping_table:
            self.logger.info(item['target_id'])

        for device in device_mapping_table:
            self.flash(build=build,
                       target_id=device['target_id'],
                       platform_name=None,
                       device_mapping_table=device_mapping_table,
                       method=method,
                       no_reset=no_reset)

        return EXIT_CODE_SUCCESS
Example #9
0
    def try_drag_and_drop_flash(self, source, target, target_filename,
                                no_reset):
        """
        Try to flash the target using drag and drop method.
        :param source: file to be flashed
        :param target: target board to be flashed
        :param no_reset: whether to reset the board after flash
        :return: 0 if success
        """

        target = MbedCommon.refresh_target(target["target_id"])
        if not target:
            raise FlashError(message="Target ID is missing",
                             return_code=EXIT_CODE_TARGET_ID_MISSING)

        destination = MbedCommon.get_binary_destination(
            target["mount_point"], target_filename)

        try:
            if 'serial_port' in target and not no_reset:
                Reset(logger=self.logger).reset_board(target["serial_port"])
                sleep(0.1)

            self.copy_file(source, destination)
            self.logger.debug("copy finished")

            target = MbedCommon.wait_for_file_disappear(
                target, target_filename)

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

            # verify flashing went as planned
            self.logger.debug("verifying flash")
            return self.verify_flash_success(
                target,
                MbedCommon.get_binary_destination(target["mount_point"],
                                                  target_filename))
        # In python3 IOError is just an alias for OSError
        except (OSError, IOError) as error:
            msg = "File copy failed due to: {}".format(str(error))
            self.logger.exception(msg)
            raise FlashError(message=msg, return_code=EXIT_CODE_OS_ERROR)
Example #10
0
    def flash(self, source, target, method, no_reset, target_filename=None):
        """flash device
        :param source: binary to be flashed
        :param target: target to be flashed
        :param method: method to use when flashing
        :param no_reset: do not reset flashed board at all
        :param target_filename: target filename (not in use)
        :return: 0 when flashing success
        """
        try:
            args = [
                FlasherSTLink.executable,
                "-c",
                "SN=" + target['target_id_usb_id'],  # chip to be flash
                "-P",
                source,
                "0x08000000",  # Loads file into device memory
                "-V"  # Verifies that the programming operation was performed successfully.
            ]
        except KeyError:
            raise FlashError(message="Invalid target",
                             return_code=EXIT_CODE_FLASH_FAILED)

        try:
            self.logger.info("Flashing {} with command {}".format(
                target["target_id"], args))
            returncode, output = self._start_and_wait_flash(
                args, FlasherSTLink.executable)
        except queue.Empty:
            raise FlashError(message="No returncode from ST-LINK_CLI",
                             return_code=EXIT_CODE_FLASH_FAILED)

        if returncode != 0:
            self.logger.error("Flash of {} failed, with returncode {}".format(
                target["target_id"], returncode))
            self.logger.debug(output if output else "")
            msg = "Flash failed with STLink return code: {}".format(returncode)
            raise FlashError(message=msg, return_code=EXIT_CODE_FLASH_FAILED)

        self.logger.info("Flash of {} succeeded".format(target["target_id"]))
        self.logger.debug(output)
        return EXIT_CODE_SUCCESS
Example #11
0
    def verify_flash_success(self, target, file_path):
        """
        verify flash went well
        """
        mount = target['mount_point']
        if isfile(join(mount, 'FAIL.TXT')):
            fault = FlasherMbed._read_file(mount, "FAIL.TXT")
            self.logger.error("Flashing failed: %s. tid=%s", fault,
                              target["target_id"])

            try:
                errors = [error for error in DAPLINK_ERRORS if error in fault]
                assert len(errors) <= 1
                raise FlashError(message=fault,
                                 return_code=DAPLINK_ERRORS[errors[0]])
            except AssertionError:
                msg = "Found multiple errors from FAIL.TXT: {}".format(fault)
                self.logger.exception(msg)
                raise FlashError(message=msg,
                                 return_code=EXIT_CODE_FLASH_FAILED)
            except IndexError:
                msg = "Error in FAIL.TXT is unknown: {}".format(fault)
                self.logger.exception(msg)
                raise FlashError(message=msg,
                                 return_code=EXIT_CODE_FLASH_FAILED)

        if isfile(join(mount, 'ASSERT.TXT')):
            fault = FlasherMbed._read_file(mount, "ASSERT.TXT")
            msg = "Found ASSERT.TXT: {}".format(fault)
            self.logger.error("{} found ASSERT.txt: {}".format(
                target["target_id"], fault))
            raise FlashError(message=msg, return_code=EXIT_CODE_FLASH_FAILED)

        if isfile(file_path):
            msg = "File still present in mount point"
            self.logger.error("{} file still present in mount point".format(
                target["target_id"]))
            raise FlashError(message=msg,
                             return_code=EXIT_CODE_FILE_STILL_PRESENT)

        self.logger.debug("ready")
        return EXIT_CODE_SUCCESS
Example #12
0
    def get_flasher(flasher=None):
        """
        :param flasher: None, if not given a flasher
        :return: return available flasher if found, otherwise return exit code
        """
        for available_flasher in AvailableFlashers:
            if available_flasher.name.lower() == flasher.lower():
                return available_flasher

        raise FlashError(message="Requested flasher does not exist",
                         return_code=EXIT_CODE_REQUESTED_FLASHER_DOES_NOT_EXIST)
Example #13
0
    def verify_flash_success(self, target, file_path):
        """
        verify flash went well
        """
        mount = target['mount_point']
        if isfile(join(mount, 'FAIL.TXT')):
            fault = FlasherMbed._read_file(mount, "FAIL.TXT")
            self.logger.error("Flashing failed: %s. tid=%s", fault,
                              target["target_id"])

            try:
                errors = [error for error in DAPLINK_ERRORS if error in fault]
                assert len(errors) == 1
                raise FlashError(message=fault,
                                 return_code=DAPLINK_ERRORS[errors[0]])
            except AssertionError:
                msg = "Expected to find exactly one error in fault: {}".format(
                    fault)
                self.logger.exception(msg)
                raise FlashError(message=msg,
                                 return_code=EXIT_CODE_FLASH_FAILED)
            except KeyError:
                msg = "Did not find error with key {}".format(fault)
                self.logger.exception(msg)
                raise FlashError(message=msg,
                                 return_code=EXIT_CODE_FLASH_FAILED)

        if isfile(join(mount, 'ASSERT.TXT')):
            fault = FlasherMbed._read_file(mount, "ASSERT.TXT")
            msg = "Flashing failed: {}. tid={}".format(fault, target)
            raise FlashError(message=msg, return_code=EXIT_CODE_FLASH_FAILED)

        if isfile(file_path):
            msg = "Flashing failed: File still present in mount point. tid info: {}".format(
                target)
            raise FlashError(message=msg,
                             return_code=EXIT_CODE_FILE_STILL_PRESENT)

        self.logger.debug("ready")
        return EXIT_CODE_SUCCESS
Example #14
0
 def _verify_platform_coherence(device_mapping_table):
     """
     Verify platform is same across devices.
     :param device_mapping_table: list of devices to verify
     :return: return code
     """
     found_platform = ''
     for item in device_mapping_table:
         if not found_platform:
             found_platform = item['platform_name']
         elif item['platform_name'] != found_platform:
             msg = "Multiple devices and platforms found, please specify " \
                   "preferred platform with -t <platform>."
             raise FlashError(message=msg,
                              return_code=EXIT_CODE_PLATFORM_REQUIRED)
Example #15
0
    def copy_file(self, source, destination):
        """
        copy file from os
        """
        self.logger.debug('read source file')
        try:
            with open(source, 'rb') as source_file:
                aux_source = source_file.read()
        except (IOError, OSError):
            self.logger.exception("File couldn't be read")
            raise FlashError(message="File couldn't be read",
                             return_code=EXIT_CODE_FILE_COULD_NOT_BE_READ)

        self.logger.debug("SHA1: %s", hashlib.sha1(aux_source).hexdigest())

        try:
            if platform.system() == "Windows":
                self._copy_file_windows(source, destination)
            else:
                self._copy_file(aux_source, destination)
        except (IOError, OSError, subprocess.CalledProcessError):
            self.logger.exception("File couldn't be copied")
            raise FlashError(message="File couldn't be copied",
                             return_code=EXIT_CODE_OS_ERROR)
Example #16
0
    def test_does_not_retry_on_daplink_user_error(self, mock_copy_file,
                                                  mock_reset_board,
                                                  mock_refresh_target):
        target = {"target_id": "a", "mount_point": ""}
        mock_copy_file.side_effect = FlashError(
            message="", return_code=EXIT_CODE_DAPLINK_USER_ERROR)
        mock_reset_board.return_value = True
        mock_refresh_target.return_value = target
        flasher = FlasherMbed()

        with self.assertRaises(FlashError) as cm:
            flasher.flash(source="",
                          target=target,
                          method="simple",
                          no_reset=False)

        self.assertEqual(cm.exception.return_code,
                         EXIT_CODE_DAPLINK_USER_ERROR)
        self.assertEqual(mock_copy_file.call_count, 1)
Example #17
0
    def reset_board(self, serial_port):
        """
        Reset board
        """
        try:
            port = EnhancedSerial(serial_port)
        except SerialException as err:
            self.logger.exception("reset could not be sent")
            # SerialException.message is type "string"
            # pylint: disable=no-member
            if err.message.find('could not open port') != -1:
                # python 3 compatibility
                # pylint: disable=superfluous-parens
                self.logger.error(
                    "Reset could not be given. Close your Serial connection to device."
                )

            raise FlashError(message="Reset failed",
                             return_code=EXIT_CODE_RESET_FAIL)

        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:
                self.logger.info("reset failed")

        port.close()
Example #18
0
    def subcmd_flash_handler(self, args):
        """
        flash command handler
        """
        if not args.tid:
            msg = "Target_id is missing"
            raise FlashError(message=msg,
                             return_code=EXIT_CODE_TARGET_ID_MISSING)

        check_file(self.logger, args.target_filename or args.input)
        check_file(self.logger, args.input)
        check_file_exists(self.logger, args.input)
        check_file_extension(self.logger, args.target_filename or args.input)

        flasher = Flash()
        available = Common(self.logger).get_available_device_mapping(
            flasher.get_all_flashers(), args.tid)
        available_target_ids = []
        retcode = EXIT_CODE_SUCCESS
        if args.platform_name:
            if args.platform_name not in flasher.get_supported_targets():
                self.logger.error("Not supported platform: %s",
                                  args.platform_name)
                self.logger.error("Supported platforms: %s",
                                  flasher.get_supported_targets())
                raise FlashError(message="Platform {} not supported".format(
                    args.platform_name),
                                 return_code=EXIT_CODE_NOT_SUPPORTED_PLATFORM)

        if 'all' in args.tid:
            retcode = flasher.flash(build=args.input,
                                    target_id='all',
                                    platform_name=args.platform_name,
                                    target_filename=args.target_filename,
                                    method=args.method,
                                    no_reset=args.no_reset)

        if len(available) <= 0:
            msg = "Could not find any connected device"
            raise FlashError(message=msg,
                             return_code=EXIT_CODE_DEVICES_MISSING)

        available_platforms, target_ids_to_flash = \
            self.prepare_platforms_and_targets(available, args.tid, available_target_ids)

        if not target_ids_to_flash:
            self.logger.error(
                "Could not find given target_id from attached devices")
            self.logger.error("Available target_ids: %s", available_target_ids)
            raise FlashError(message="Could not map device",
                             return_code=EXIT_CODE_COULD_NOT_MAP_DEVICE)
        elif len(available_platforms) > 1:
            if not args.platform_name:
                self.logger.error(
                    "More than one platform detected for given target_id")
                self.logger.error(
                    "Please specify the platform with -t <PLATFORM_NAME>")
                self.logger.error("Found platforms: %s", available_platforms)
                raise FlashError(
                    message=
                    "More than one platform detected for given target id",
                    return_code=EXIT_CODE_PLATFORM_REQUIRED)
        else:
            retcode = flasher.flash(build=args.input,
                                    target_id=target_ids_to_flash,
                                    target_filename=args.target_filename,
                                    platform_name=available_platforms[0],
                                    method=args.method,
                                    no_reset=args.no_reset)

        return retcode
Example #19
0
 def func():
     self.call_count += 1
     raise FlashError(message="", return_code=1)
Example #20
0
    def flash(self, build, target_id=None, platform_name=None,
              device_mapping_table=None, method='simple', no_reset=None,
              target_filename=None):
        """Flash (mbed) device
        :param build: string (file-path)
        :param target_id: target_id
        :param platform_name: platform_name, to flash multiple devices of same type
        :param device_mapping_table: individual devices mapping table
        :param method: method for flashing i.e. simple, pyocd or edbg
        :param no_reset: whether to reset the board after flash
        :param target_filename: optional Target filename
        """

        k64f_target_id_length = 48

        if target_id is None and platform_name is None:
            raise SyntaxError("target_id or target_name is required")

        target_filename = target_filename or build

        check_file(self.logger, target_filename)
        check_file(self.logger, build)
        check_file_extension(self.logger, target_filename)
        check_file_exists(self.logger, build)

        if (isinstance(target_id, list) or
                target_id.lower() == 'all' or
                (len(target_id) < k64f_target_id_length and device_mapping_table is None)):
            if isinstance(target_id, str) and target_id.lower() == 'all':
                target_id = ''
            return self.flash_multiple(
                build=build,
                platform_name=platform_name,
                method=method,
                target_ids_or_prefix=target_id,
                no_reset=no_reset,
                target_filename=target_filename)

        device_mapping_table = self._refine__device_mapping_table(
            device_mapping_table, target_id)

        try:
            if target_id:
                target_mbed = self.__find_by_target_id(target_id, device_mapping_table)
            else:
                target_mbed = self.__find_by_platform_name(platform_name,
                                                           device_mapping_table)
        except KeyError:
            msg = "Could not find required device"
            self.logger.exception(msg)
            raise FlashError(message=msg,
                             return_code=EXIT_CODE_COULD_NOT_MAP_TARGET_ID_TO_DEVICE)

        platform_name = self._get_platform_name(platform_name, target_mbed)

        self.logger.debug("Flashing: %s", target_mbed["target_id"])

        flasher = self.__get_flasher(platform_name, target_mbed)
        retcode = Flash._do_flash(flasher=flasher,
                                  build=build,
                                  target=target_mbed,
                                  method=method,
                                  no_reset=no_reset,
                                  target_filename=target_filename)
        if retcode == EXIT_CODE_SUCCESS:
            self.logger.info("%s flash success", target_mbed["target_id"])
        else:
            self.logger.warning("%s flash fails with code %d",
                                target_mbed["target_id"], retcode)

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

        self.assertEqual(cm.exception.message, "test")
        self.assertEqual(cm.exception.return_code, 0)