示例#1
0
class BoardAllocator:
    def __init__(self, platforms_supported: List[str], binaries: Mapping[str,
                                                                         str]):
        mbed_ls = mbed_lstools.create()
        boards = mbed_ls.list_mbeds(filter_function=lambda m: m[
            'platform_name'] in platforms_supported)
        self.board_description = boards
        self.binaries = binaries
        self.allocation = []  # type: List[BoardAllocation]
        self.flasher = None
        for desc in boards:
            self.allocation.append(BoardAllocation(desc))

    def allocate(self, name: str = None) -> Optional[BleDevice]:
        for alloc in self.allocation:
            if alloc.ble_device is None:
                # Flash if a binary is provided and the board hasn't been flashed yet
                platform = alloc.description['platform_name']
                binary = self.binaries.get(platform)
                if alloc.flashed is False and binary:
                    if self.flasher is None:
                        self.flasher = Flash()
                    self.flasher.flash(
                        build=binary, target_id=alloc.description["target_id"])
                    alloc.flashed = True

                # Create the serial connection
                connection = SerialConnection(
                    port=alloc.description["serial_port"], baudrate=115200)
                connection.open()

                # Create the serial device
                serial_device = SerialDevice(connection, name)
                serial_device.reset(duration=1)
                serial_device.flush(1)

                # Create the BleDevice
                alloc.ble_device = BleDevice(serial_device)

                alloc.ble_device.send('set --retcode true', 'retcode: 0')
                alloc.ble_device.send('echo off', 'retcode: 0')
                alloc.ble_device.send('set --vt100 off', 'retcode: 0')

                return alloc.ble_device
        return None

    def release(self, ble_device: BleDevice) -> None:
        for alloc in self.allocation:
            if alloc.ble_device == ble_device and alloc.ble_device is not None:
                # Restore the board
                alloc.ble_device.send('echo on', 'retcode: 0')
                alloc.ble_device.send('set --vt100 on', 'retcode: 0')
                alloc.ble_device.send('set retcode false')

                # Stop activities
                alloc.ble_device.device.stop()
                alloc.ble_device.device.serial.close()

                # Cleanup
                alloc.ble_device = None
示例#2
0
    def test_run_fail_binary(self, mock_stdout):
        mbeds = mbed_lstools.create()
        targets = mbeds.list_mbeds()
        target_id = None
        mount_point = None
        fail_bin_path = os.path.join('test', 'fail.bin')
        for target in targets:
            if target['platform_name'] == 'K64F':
                if 'target_id' in target and 'mount_point' in target:
                    target_id = target['target_id']
                    mount_point = target['mount_point']
                    break

        with open(fail_bin_path, 'w') as new_file:
            new_file.write("0000000000000000000000000000000000")

        with self.assertRaises(FlashError) as cm:
            flasher = Flash()
            flasher.flash(build=fail_bin_path,
                          target_id=target_id,
                          platform_name='K64F',
                          device_mapping_table=None,
                          method='simple')

        if platform.system() == 'Windows':
            os.system('del /F %s' % os.path.join(mount_point, 'FAIL.TXT'))
            os.system('del %s' % os.path.join(os.getcwd(), fail_bin_path))
        else:
            os.system('rm -f %s' % os.path.join(mount_point, 'FAIL.TXT'))
            os.system('rm %s' % os.path.join(os.getcwd(), fail_bin_path))

        self.assertEqual(cm.exception.return_code,
                         EXIT_CODE_DAPLINK_USER_ERROR)
示例#3
0
class BoardAllocator:
    def __init__(self, platforms_supported: List[str],
                 binaries: Mapping[str, str], serial_inter_byte_delay: float,
                 baudrate: int, command_delay: float):
        mbed_ls = mbed_lstools.create()
        boards = mbed_ls.list_mbeds(filter_function=lambda m: m[
            'platform_name'] in platforms_supported)
        self.board_description = boards
        self.binaries = binaries
        self.allocation = []  # type: List[BoardAllocation]
        self.flasher = None
        self.serial_inter_byte_delay = serial_inter_byte_delay
        self.baudrate = baudrate
        self.command_delay = command_delay
        for desc in boards:
            self.allocation.append(BoardAllocation(desc))

    def allocate(self, name: str = None) -> Optional[SerialDevice]:
        for alloc in self.allocation:
            if alloc.ble_device is None:
                # Flash if a binary is provided and the board hasn't been flashed yet
                platform = alloc.description['platform_name']
                binary = self.binaries.get(platform)
                if alloc.flashed is False and binary:
                    if self.flasher is None:
                        self.flasher = Flash()
                    self.flasher.flash(
                        build=binary, target_id=alloc.description["target_id"])
                    alloc.flashed = True

                # Create the serial connection
                connection = SerialConnection(
                    port=alloc.description["serial_port"],
                    baudrate=self.baudrate,
                    inter_byte_delay=self.serial_inter_byte_delay)
                connection.open()

                # Create the serial device
                serial_device = SerialDevice(connection, name)
                serial_device.reset(duration=1)
                serial_device.flush(1)

                # Create the SerialDevice
                alloc.ble_device = serial_device

                return alloc.ble_device
        return None

    def release(self, ble_device: SerialDevice) -> None:
        for alloc in self.allocation:
            if alloc.ble_device == ble_device and alloc.ble_device is not None:
                # Stop activities
                alloc.ble_device.stop()
                alloc.ble_device.serial.close()

                # Cleanup
                alloc.ble_device = None
示例#4
0
 def test_run_file_does_not_exist(self):
     flasher = Flash()
     with self.assertRaises(SyntaxError) as context:
         flasher.flash(build='file.bin',
                       target_id=None,
                       platform_name=None,
                       device_mapping_table=None,
                       method='simple')
     self.assertIn("target_id or target_name is required",
                   context.exception.msg)
示例#5
0
    def test_run_target_id_and_platform_missing(self):
        flasher = Flash()
        with self.assertRaises(FlashError) as cm:
            flasher.flash(build='file.bin',
                          target_id=True,
                          platform_name=False,
                          device_mapping_table=None,
                          method='simple')

        self.assertEqual(cm.exception.return_code, EXIT_CODE_FILE_MISSING)
示例#6
0
    def test_run_with_file_with_one_target_id(self, mock_sleep):
        flasher = Flash()
        with self.assertRaises(FlashError) as cm:
            flasher.flash(
                build=self.bin_path,
                target_id='0240000029164e45002f0012706e0006f301000097969900',
                platform_name=False,
                device_mapping_table=None,
                method='simple')

        self.assertEqual(cm.exception.return_code,
                         EXIT_CODE_COULD_NOT_MAP_DEVICE)
示例#7
0
    def test_raises_with_bad_file_extension(self):
        flasher = Flash()
        with self.assertRaises(FlashError) as cm:
            flasher.flash(
                build=__file__,
                target_id='0240000029164e45002f0012706e0006f301000097969900',
                platform_name=False,
                device_mapping_table=None,
                method='simple')

        self.assertEqual(cm.exception.return_code,
                         EXIT_CODE_DAPLINK_USER_ERROR)
示例#8
0
    def test_run_with_file_with_target_id_all(self, mock_device_mapping):
        flasher = Flash()
        mock_device_mapping.return_value = []
        with self.assertRaises(FlashError) as cm:
            flasher.flash(build=self.bin_path,
                          target_id='all',
                          platform_name=False,
                          device_mapping_table=None,
                          method='simple')

        self.assertEqual(cm.exception.return_code,
                         EXIT_CODE_COULD_NOT_MAP_TARGET_ID_TO_DEVICE)
示例#9
0
    def test_verify_hw_flash_no_reset(self):
        mbeds = mbed_lstools.create()
        targets = mbeds.list_mbeds()
        flasher = Flash()
        resetter = Reset()
        target_id = None
        serial_port = None
        for target in targets:
            if target['platform_name'] == 'K64F':
                if 'serial_port' and 'target_id' in target:
                    target_id = target['target_id']
                    serial_port = target['serial_port']
                    break
        if target_id and serial_port:
            second_binary = find_second_binary()
            self.assertIsNotNone(second_binary, 'Second binary not found')
            ret = flasher.flash(build=second_binary,
                                target_id=target_id,
                                platform_name='K64F',
                                device_mapping_table=False,
                                method='simple')
            self.assertEqual(ret, 0)
            if not verify_output_per_device(serial_port, 'help', 'echo'):
                self.assertEqual(
                    verify_output_per_device(serial_port, 'help', 'echo'),
                    True)

            ret = flasher.flash(build=second_binary,
                                target_id=target_id,
                                platform_name='K64F',
                                device_mapping_table=False,
                                method='simple',
                                no_reset=True)
            self.assertEqual(ret, 0)
            self.assertEqual(
                verify_output_per_device(serial_port, 'help', 'echo'), False)
            ret = resetter.reset(target_id=target_id, method='simple')
            self.assertEqual(ret, 0)
            if not verify_output_per_device(serial_port, 'help', 'echo'):
                self.assertEqual(
                    verify_output_per_device(serial_port, 'help', 'echo'),
                    True)
            ret = flasher.flash(build=self.bin_path,
                                target_id=target_id,
                                platform_name='K64F',
                                device_mapping_table=False,
                                method='simple')
            self.assertEqual(ret, 0)
            self.assertEqual(
                verify_output_per_device(serial_port, 'help', 'echo'), False)
示例#10
0
    def test_run_with_lowercase_HTM(self, mock_popen, mock_verifier, mock_copy_file):
        mock_verifier.return_value = {'target_id': '123',
                                      'platform_name': 'K64F',
                                      'mount_point': 'path/'}

        mock_stdout = mock.Mock()
        mock_out = mock.Mock(side_effect=[b"no-htm", b"test.htm", b"no-htm"])
        mock_stdout.read = mock_out
        mock_popen.return_value.stdout = mock_stdout

        mock_popen.return_value.communicate.return_value = ('', '')

        flasher = Flash()
        ret = flasher.flash(build=self.bin_path,
                            target_id='123',
                            platform_name='K64F',
                            device_mapping_table=[{
                                'target_id': '123',
                                'platform_name': 'K64F',
                                'mount_point': '',
                            }],
                            method='simple',
                            no_reset=True)
        self.assertEqual(ret, 0)
        self.assertEqual(2, mock_out.call_count)
示例#11
0
 def test_run_with_file_with_one_target_id(self):
     flasher = Flash()
     ret = flasher.flash(build=self.bin_path,
                         target_id='0240000029164e45002f0012706e0006f301000097969900',
                         platform_name=False,
                         device_mapping_table=None,
                         method='simple')
     self.assertEqual(ret, 55)
示例#12
0
 def test_run_with_file_with_target_id_all(self):
     flasher = Flash()
     ret = flasher.flash(build=self.bin_path,
                         target_id='all',
                         platform_name=False,
                         device_mapping_table=None,
                         method='simple')
     self.assertEqual(ret, 40)
示例#13
0
 def test_run_with_file_with_one_target_id_wrong_platform(self):
     mbeds = mbed_lstools.create()
     targets = mbeds.list_mbeds()
     target_id = None
     for target in targets:
         if target['platform_name'] == 'K64F':
             if 'target_id' in target:
                 target_id = target['target_id']
                 break
     if target_id:
         flasher = Flash()
         with self.assertRaises(NotImplementedError) as context:
             flasher.flash(build=self.bin_path,
                           target_id=target_id,
                           platform_name='K65G',
                           device_mapping_table=None,
                           method='simple')
         self.assertIn("Platform 'K65G' is not supported by mbed-flasher",
                       str(context.exception))
示例#14
0
 def test_run_with_file_with_prefix(self, mock_stdout):
     flasher = Flash()
     ret = flasher.flash(build=self.bin_path,
                         target_id='02',
                         platform_name='K64F',
                         device_mapping_table=None,
                         method='simple')
     self.assertEqual(ret, EXIT_CODE_SUCCESS)
     if mock_stdout:
         pass
示例#15
0
 def test_verify_hw_flash(self):
     mbeds = mbed_lstools.create()
     targets = mbeds.list_mbeds()
     flasher = Flash()
     target_id = None
     serial_port = None
     for target in targets:
         if target['platform_name'] == 'K64F':
             if 'serial_port' and 'target_id' in target:
                 target_id = target['target_id']
                 serial_port = target['serial_port']
                 break
     if target_id and serial_port:
         ret = flasher.flash(build=self.bin_path,
                             target_id=target_id,
                             platform_name='K64F',
                             device_mapping_table=False,
                             method='simple')
         self.assertEqual(ret, EXIT_CODE_SUCCESS)
         self.assertEqual(
             verify_output_per_device(serial_port, 'help', 'echo'), False)
         ret = flasher.flash(build=self.second_bin_path,
                             target_id=target_id,
                             platform_name='K64F',
                             device_mapping_table=False,
                             method='simple')
         self.assertEqual(ret, EXIT_CODE_SUCCESS)
         if not verify_output_per_device(serial_port, 'help', 'echo'):
             self.assertEqual(
                 verify_output_per_device(serial_port, 'help', 'echo'),
                 True)
         ret = flasher.flash(build=self.bin_path,
                             target_id=target_id,
                             platform_name='K64F',
                             device_mapping_table=False,
                             method='simple')
         self.assertEqual(ret, EXIT_CODE_SUCCESS)
         self.assertEqual(
             verify_output_per_device(serial_port, 'help', 'echo'), False)
示例#16
0
 def test_hw_flash(self):
     mbeds = mbed_lstools.create()
     targets = mbeds.list_mbeds()
     target_id = None
     for target in targets:
         if target['platform_name'] == 'K64F':
             if 'target_id' in target:
                 target_id = target['target_id']
                 break
     if target_id:
         flasher = Flash()
         ret = flasher.flash(build=self.bin_path,
                             target_id=target_id,
                             platform_name=False,
                             device_mapping_table=None,
                             method='simple')
         self.assertEqual(ret, EXIT_CODE_SUCCESS)
示例#17
0
 def test_run_with_lowercase_HTM(self, mock_refresh_target, mock_copy_file):
     mock_refresh_target.return_value = {
         'target_id': '123',
         'platform_name': 'K64F',
         'mount_point': 'path/'
     }
     flasher = Flash()
     ret = flasher.flash(build=self.bin_path,
                         target_id='123',
                         platform_name='K64F',
                         device_mapping_table=[{
                             'target_id': '123',
                             'platform_name': 'K64F',
                             'mount_point': '',
                         }],
                         method='simple',
                         no_reset=True)
     self.assertEqual(ret, EXIT_CODE_SUCCESS)
示例#18
0
    def flash(self, binary_location=None, forceflash=None):
        """
        Flash a binary to the target device using mbed-flasher.

        :param binary_location: Binary to flash to device.
        :param forceflash: Not used.
        :return: False if an unknown error was encountered during flashing.
        True if flasher retcode == 0
        :raises: ImportError if mbed-flasher not installed.
        :raises: DutConnectionError if flashing fails.
        """
        if not Flash:
            self.logger.error("Mbed-flasher not installed!")
            raise ImportError("Mbed-flasher not installed!")

        try:
            # create build object
            self.build = Build.init(binary_location)
        except NotImplementedError as error:
            self.logger.error("Build initialization failed. "
                              "Check your build location.")
            self.logger.debug(error)
            raise DutConnectionError(error)

        # check if need to flash - depend on forceflash -option
        if not self._flash_needed(forceflash=forceflash):
            self.logger.info("Skipping flash, not needed.")
            return True
        # initialize mbed-flasher with proper logger
        logger = get_external_logger("mbed-flasher", "FLS")
        flasher = Flash(logger=logger)

        if not self.device:
            self.logger.error(
                "Trying to flash device but device is not there?")
            return False

        try:
            buildfile = self.build.get_file()
            if not buildfile:
                raise DutConnectionError(
                    "Binary {} not found".format(buildfile))
            self.logger.info('Flashing dev: %s', self.device['target_id'])
            target_id = self.device.get("target_id")
            retcode = flasher.flash(build=buildfile,
                                    target_id=target_id,
                                    device_mapping_table=[self.device])
        except FLASHER_ERRORS as error:
            if error.__class__ == NotImplementedError:
                self.logger.error("Flashing not supported for this platform!")
            elif error.__class__ == SyntaxError:
                self.logger.error("target_id required by mbed-flasher!")
            if FlashError is not None:
                if error.__class__ == FlashError:
                    self.logger.error(
                        "Flasher raised the following error: %s Error code: %i",
                        error.message, error.return_code)
            raise DutConnectionError(error)
        if retcode == 0:
            self.dutinformation.build_binary_sha1 = self.build.sha1
            return True
        self.dutinformation.build_binary_sha1 = None
        return False
示例#19
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
示例#20
0
    def flash(self, binary, forceflash=None):  # pylint: disable=too-many-branches
        """
        Flash a binary to the target device using mbed-flasher.

        :param binary: Binary to flash to device
        :param forceflash: Boolean
        :return: False if an error was encountered during flashing. True if flasher retcode == 0
        :raises: ImportError if mbed-flasher not installed.
        :raises: DutConnectionError if Build initialization fails (binary not found usually).
        """
        error_occured = False
        if Flash is None:
            self.logger.warning("mbed-flasher not installed. "
                                "(https://github.com/ARMmbed/mbed-flasher)")
            raise ImportError("Mbed-flasher not installed.")

        try:
            # Create build object.
            self.build = Build.init(binary)
        except NotImplementedError as error:
            self.logger.error(
                "Build initialization failed. Check your build location.")
            self.logger.debug(error)
            raise DutConnectionError(error)

        # Check if flashing is needed. Depends on forceflash-option.
        if not self._flash_needed(forceflash=forceflash):
            self.logger.info("Skipping flash, not needed.")
            return True

        if "logger" in getargspec(Flash.__init__).args:
            # get_resourceprovider_logger returns previous logger if one already exists.
            # If no logger with name mbed-flasher exists, a new one is created.
            logger = get_resourceprovider_logger("mbed-flasher", "FLS")
            flasher = Flash(logger=logger)
        else:
            # Backwards compatibility for older mbed-flasher versions.
            flasher = Flash()
        retcode = None
        try:
            if self.device:
                buildfile = self.build.get_file()
                if not buildfile:
                    raise DutConnectionError(
                        "Binary {} not found".format(buildfile))
                self.logger.info('Flashing dev: %s', self.device['target_id'])
                target_id = self.device.get("target_id")
                retcode = flasher.flash(build=buildfile,
                                        target_id=target_id,
                                        device_mapping_table=[self.device])
            else:
                error_occured = True
        except FLASHER_ERRORS as error:
            if error.__class__ == NotImplementedError:
                self.logger.error("Flashing not supported for this platform!")
            elif error.__class__ == SyntaxError:
                self.logger.error("target_id required by mbed-flasher!")
            if FlashError is not None:
                if error.__class__ == FlashError:
                    self.logger.error(
                        "Flasher raised the following error: %s Error code: %i",
                        error.message, error.return_code)
            raise DutConnectionError(error)
        if retcode != 0:
            error_occured = True
        else:
            self.dutinformation.build_binary_sha1 = self.build.sha1
        return not error_occured
示例#21
0
 def test_run_target_id_and_platform_missing(self):
     flasher = Flash()
     ret = flasher.flash(build='file.bin', target_id=True,
                         platform_name=False, device_mapping_table=None,
                         method='simple')
     self.assertEqual(ret, 45)
示例#22
0
    def subcmd_flash_handler(self, args):
        """
        flash command handler
        """
        flasher = Flash()
        available = flasher.get_available_device_mapping()
        available_target_ids = []
        retcode = 0
        #print(args)
        if args.input:
            if not isfile(args.input):
                print("Could not find given file: %s" % args.input)
                return EXIT_CODE_FILE_MISSING
        else:
            print("File is missing")
            return EXIT_CODE_FILE_MISSING
        if args.platform_name:
            if args.platform_name not in flasher.get_supported_targets():
                print("Not supported platform: %s" % args.platform_name)
                print("Supported platforms: %s" %
                      flasher.get_supported_targets())
                return EXIT_CODE_NOT_SUPPORTED_PLATFORM

        if not args.tid:
            print("Target_id is missing")
            return EXIT_CODE_NO_TARGET_ID

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

        if len(available) <= 0:
            print("Could not find any connected device")
            return 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:
            print("Could not find given target_id from attached devices")
            print("Available target_ids:")
            print(available_target_ids)
            return EXIT_CODE_COULD_NOT_MAP_DEVICE

        elif len(available_platforms) > 1:
            if not args.platform_name:
                print("More than one platform detected for given target_id")
                print("Please specify the platform with -t <PLATFORM_NAME>")
                print("Found platforms:")
                print(available_platforms)
                return EXIT_CODE_PLATFORM_REQUIRED
        else:
            #print(target_ids_to_flash)
            retcode = flasher.flash(build=args.input,
                                    target_id=target_ids_to_flash,
                                    platform_name=available_platforms[0],
                                    method=args.method,
                                    no_reset=args.no_reset)

        return retcode
示例#23
0
class BoardAllocator:
    ALLOCATION_RETRIES = 3

    def __init__(self, platforms_supported: List[str],
                 binaries: Mapping[str, str], serial_inter_byte_delay: float,
                 baudrate: int, command_delay: float):
        mbed_ls = mbed_lstools.create()
        boards = mbed_ls.list_mbeds(filter_function=lambda m: m[
            'platform_name'] in platforms_supported)
        self.board_description = boards
        self.binaries = binaries
        self.allocation = []  # type: List[BoardAllocation]
        self.flasher = None
        self.serial_inter_byte_delay = serial_inter_byte_delay
        self.baudrate = baudrate
        self.command_delay = command_delay
        for desc in boards:
            self.allocation.append(BoardAllocation(desc))

    def allocate(self, name: str = None) -> Optional[BleDevice]:
        for alloc in self.allocation:
            if alloc.ble_device is None:
                # Flash if a binary is provided and the board hasn't been flashed yet
                platform = alloc.description['platform_name']
                binary = self.binaries.get(platform)
                if alloc.flashed is False and binary:
                    if self.flasher is None:
                        self.flasher = Flash()
                    self.flasher.flash(
                        build=binary, target_id=alloc.description["target_id"])
                    alloc.flashed = True

                # Create the serial connection
                connection = SerialConnection(
                    port=alloc.description["serial_port"],
                    baudrate=self.baudrate,
                    inter_byte_delay=self.serial_inter_byte_delay)
                connection.open()

                retry = BoardAllocator.ALLOCATION_RETRIES
                serial_device = None

                while True:
                    try:
                        # Create the serial device
                        serial_device = SerialDevice(connection, name)
                        serial_device.reset(duration=1)
                        serial_device.flush(1)

                        # Create the BleDevice
                        alloc.ble_device = BleDevice(
                            serial_device, command_delay=self.command_delay)

                        alloc.ble_device.send('set --retcode true',
                                              'retcode: 0',
                                              wait_for_response=5)
                        alloc.ble_device.send('echo off', 'retcode: 0')
                        alloc.ble_device.send('set --vt100 off', 'retcode: 0')

                        break

                    except serial_device.BoardCommunicationFailed:
                        if retry:
                            retry -= 1
                            self.release(serial_device)
                            log.warning("Board failed to allocate, retrying")
                        else:
                            raise

                return alloc.ble_device
        return None

    def release(self, ble_device: BleDevice) -> None:
        for alloc in self.allocation:
            if alloc.ble_device == ble_device and alloc.ble_device is not None:
                # Restore the board
                alloc.ble_device.send('echo on', 'retcode: 0')
                alloc.ble_device.send('set --vt100 on', 'retcode: 0')
                alloc.ble_device.send('set retcode false')

                # Stop activities
                alloc.ble_device.device.stop()
                alloc.ble_device.device.serial.close()

                # Cleanup
                alloc.ble_device = None