def search_nxp_uart_devices() -> Sequence[DeviceDescription]: """Returns a list of all NXP devices connected via UART. :retval: list of UartDeviceDescription devices from devicedescription module """ retval = [] # Get all available COM ports on target PC ports = [port.device for port in comports()] # Iterate over every com port we have and check, whether mboot or sdp responds for port in ports: if mb_scan_uart(port=port, timeout=50): uart_dev = UartDeviceDescription(name=port, dev_type="mboot device") retval.append(uart_dev) continue # Seems the port is not mboot, let's try SDP protocol # The SDP protocol is on uart interface, so opening just the port is not # sufficient, to say, that the interface is SDP compared to mboot, where # ping command must be sent. # So we create an SDP interface and try to read the status code. If # we get a response, we are connecte to an SDP device. sdp_com = SDP(SDP_Uart(port=port, timeout=50)) if sdp_com.read_status() is not None: uart_dev = UartDeviceDescription(name=port, dev_type="SDP device") retval.append(uart_dev) return retval
def init_flashloader(cpu_params: CpuParams) -> McuBoot: """Load an execute flash-loader binary in i.MX-RT The function signs the flashloader if needed (if HAB enabled) :param cpu_params: processor specific parameters of the test :return: McuBoot instance to communicate with flash-loader :raises ConnectionError: if connection cannot be established """ devs = mboot_scan_usb(cpu_params.com_processor_name ) # check whether flashloader is already running if len(devs) == 0: # if flash-loader not running yet, it must be downloaded to RAM and launched flshldr_img = BootImgRT.parse( load_binary(cpu_params.data_dir, 'ivt_flashloader.bin')) devs = sdp_scan_usb(cpu_params.com_processor_name) if len(devs) != 1: raise ConnectionError('Cannot connect to ROM bootloader') with SDP(devs[0], cmd_exception=True) as sd: assert sd.is_opened try: sd.read(INT_RAM_ADDR_CODE, 4) # dummy read to receive response except SdpCommandError: # there is an exception if HAB is locked, cause read not supported pass if (sd.status_code == StatusCode.HAB_IS_LOCKED) and (sd.response_value == ResponseValue.LOCKED): auth_flshldr_img = BootImgRT(flshldr_img.address, BootImgRT.IVT_OFFSET_OTHER) _to_authenticated_image( cpu_params, auth_flshldr_img, flshldr_img.app.data, 0, flshldr_img.ivt.app_address ) # entry addr cannot be detected from img else: auth_flshldr_img = flshldr_img assert sd.write_file(auth_flshldr_img.address, auth_flshldr_img.export()) try: assert sd.jump_and_run(auth_flshldr_img.address + auth_flshldr_img.ivt_offset) except SdpCommandError: pass # SDP may return an exception if HAB locked for _ in range(10): # wait 10 sec until flash-loader is inited sleep(1) # Scan for MCU-BOOT device devs = mboot_scan_usb(cpu_params.com_processor_name) if len(devs) == 1: break if len(devs) != 1: raise ConnectionError('Cannot connect to Flash-Loader') result = McuBoot(devs[0], cmd_exception=True) result.open() assert result.is_opened result.reopen = False # reopen not supported for RT1050??? return result
def read_register( ctx: click.Context, address: int, item_length: int, count: int, file: click.File, use_hexdump: bool, ) -> None: """Reads the contents of a memory location or register value. The address of the register or memory location should be passed in as the first argument. Optional arguments include the data format of the register value in the number of bits and number of bytes to read. \b ADDRESS - starting address where to read FORMAT - bits per item: valid values: 8, 16, 32; default 32 COUNT - bytes to read; default size of FORMAT FILE - write data into a file; write to stdout if not specified """ with SDP(ctx.obj["interface"]) as sdp: response = sdp.read_safe(address, count, item_length) if not response: click.echo( f"Error: invalid sub-command or arguments 'read-register {address:#8X} {item_length} {count}'" ) sys.exit(1) if file: file.write(response) # type: ignore else: click.echo(format_raw_data(response, use_hexdump=use_hexdump)) display_output([], sdp.hab_status, ctx.obj["use_json"])
def error_status(ctx: click.Context) -> None: """Get error code of last operation.""" with SDP(ctx.obj['interface']) as sdp: response = sdp.read_status() display_output( [response], sdp.response_value, ctx.obj['use_json'], extra_output=f"Response status = {decode_status_code(response)}." )
def jump_address(ctx: click.Context, address: int) -> None: """Jump to entry point of image with IVT at specified address. \b ADDRESS - starting address of the image """ with SDP(ctx.obj['interface']) as sdp: sdp.jump_and_run(address) display_output([], sdp.response_value)
def error_status(ctx: click.Context) -> None: """Reads the error code from the device.""" with SDP(ctx.obj["interface"]) as sdp: response = sdp.read_status() display_output( [response], sdp.hab_status, ctx.obj["use_json"], extra_output=f"Response status = {decode_status_code(response)}.", )
def jump_address(ctx: click.Context, address: int) -> None: """Jumps to the entry point of the image at the given address. jump-address will result in the execution of the image once the ROM process the IVT and on successful authentication of the image. \b ADDRESS - starting address of the image """ with SDP(ctx.obj["interface"]) as sdp: sdp.jump_and_run(address) display_output([], sdp.hab_status)
def write_file(ctx: click.Context, address: int, bin_file: click.File, count: int) -> None: """Write file at address. \b ADDRESS - starting address of the image FILE - binary file to write COUNT - Count is size of data to write in bytes (default: whole file) """ data = bin_file.read(count) # type: ignore with SDP(ctx.obj['interface']) as sdp: sdp.write_file(address, data) display_output([], sdp.response_value)
def write_file(ctx: click.Context, address: int, bin_file: click.File, count: int) -> None: """Writes file to the device’s memory address. \b ADDRESS - starting address of the image FILE - binary file to write COUNT - Count is the size of data to write in bytes (default: whole file) """ data = bin_file.read(count) # type: ignore with SDP(ctx.obj["interface"]) as sdp: sdp.write_file(address, data) display_output( [], sdp.hab_status, extra_output=f"Response status = {decode_status_code(sdp.cmd_status)}.", )
def read_memory(address: int, length: int, device_name: str = None) -> Optional[bytes]: """Read memory using USB interface. To see all availabe device names (and their respective VID:PID): spsdk/sdp/interfaces/usb.py -> USB_DEVICES If device_name is not specified, function will use first available SDP device. :param address: The address in target memory :param length: Count of bytes to read :param device_name: i.MX-RT device name or VID:PID :return: bytes or None """ devices = scan_usb(device_name) if devices: with SDP(devices[0]) as sdp: return sdp.read(address, length, 8) return None
def read_register(ctx: click.Context, address: int, item_length: int, count: int, file: click.File, use_hexdump: bool) -> None: """Read one or more registers. \b ADDRESS - starting address where to read FORMAT - bits per item: valid values: 8, 16, 32; default 32 COUNT - items to read; default 1 FILE - write data into a file; write to stdout if not specified """ with SDP(ctx.obj['interface']) as sdp: response = sdp.read_safe(address, count, item_length) if not response: click.echo(f"Error: invalid command or arguments 'read-register {address:#8X} {item_length} {count}'") sys.exit(1) if file: file.write(response) # type: ignore else: click.echo(format_raw_data(response, use_hexdump=use_hexdump)) display_output([], sdp.response_value, ctx.obj['use_json'])