Example #1
0
 def read_target_memory(self, addr, size, resume=True):
     assert self.get_mode() == self.MODE_IF
     with ConnectHelper.session_with_chosen_probe(
             unique_id=self.get_unique_id(),
             resume_on_disconnect=resume) as session:
         data = session.target.read_memory_block8(addr, size)
     return bytearray(data)
Example #2
0
 def test_connect(connect_mode, expected_state, resume):
     print("Connecting with connect_mode=%s" % connect_mode)
     live_session = ConnectHelper.session_with_chosen_probe(
                     unique_id=board_id,
                     init_board=False,
                     connect_mode=connect_mode,
                     resume_on_disconnect=resume,
                     **get_session_options())
     live_session.open()
     live_board = live_session.board
     print("Verifying target is", STATE_NAMES.get(expected_state, "unknown"))
     actualState = live_board.target.get_state()
     # Accept sleeping for running, as a hack to work around nRF52840-DK test binary.
     # TODO remove sleeping hack.
     if (actualState == expected_state) \
             or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING):
         passed = 1
         print("TEST PASSED")
     else:
         passed = 0
         print("TEST FAILED (state={}, expected={})".format(
             STATE_NAMES.get(actualState, "unknown"),
             STATE_NAMES.get(expected_state, "unknown")))
     print("Disconnecting with resume=%s" % resume)
     live_session.close()
     live_session = None
     return passed
Example #3
0
def _read_continuous_memory(address=0x0, count=4):
    """Read any continuous memory area from the micro:bit.

    Reads the contents of any micro:bit continuous memory area, starting from
    the 'address' argument for as many bytes as indicated by 'count'.
    There is no input sanitation in this function and is the responsibility of
    the caller to input values within range of the target board or deal with
    any exceptions raised by PyOCD.

    :param address: Integer indicating the start address to read.
    :param count: Integer, how many bytes to read.
    :return: A list of integers, each representing a byte of data.
    """
    read_data = None
    try:
        with ConnectHelper.session_with_chosen_probe(
                blocking=False,
                auto_unlock=False,
                halt_on_connect=True,
                resume_on_disconnect=True,
        ) as session:
            board = session.board
            target = board.target
            read_data = target.read_memory_block8(address, count)
    except Exception as e:
        raise Exception("{}\nDid not find any connected boards.".format(
            str(e)))
    return read_data
Example #4
0
    def execute(self, capability, *args, **kwargs):
        """! Executes capability by name
        @param capability Capability name
        @param args Additional arguments
        @param kwargs Additional arguments
        @details Each capability e.g. may directly just call some command line program or execute building pythonic function
        @return Capability call return value
        """
        if not PYOCD_PRESENT:
            self.print_plugin_error(
                'The "pyocd" feature is not installed. Please run '
                '"pip install mbed-os-tools[pyocd]" to enable the "pyocd" reset plugin.'
            )
            return False

        if not kwargs['target_id']:
            self.print_plugin_error("Error: target_id not set")
            return False

        result = False
        if self.check_parameters(capability, *args, **kwargs) is True:
            if kwargs['target_id']:
                if capability == 'pyocd':
                    target_id = kwargs['target_id']
                    with ConnectHelper.session_with_chosen_probe(
                            unique_id=target_id,
                            resume_on_disconnect=False) as session:
                        session.target.reset()
                        session.target.resume()
                        result = True
        return result
Example #5
0
 def _connect(self):
     """Connect PyOCD to the main micro:bit microcontroller."""
     if not self.session:
         try:
             self.session = ConnectHelper.session_with_chosen_probe(
                 blocking=False,
                 auto_unlock=False,
                 halt_on_connect=True,
                 resume_on_disconnect=True,
             )
             if self.session is None:
                 raise Exception("Could not open the debugger session.")
             self.session.open()
             self.board = self.session.board
             self.target = self.board.target
             self.board_id = self.board.unique_id[:4]
         except Exception as e:
             raise Exception(
                 "{}\n{}\n".format(str(e), "-" * 70)
                 + "Error: Did not find any connected boards."
             )
         if self.board_id not in MICROBIT_MEM_REGIONS:
             self._disconnect()
             raise Exception("Incompatible board ID from connected device.")
         self.mem = MICROBIT_MEM_REGIONS[self.board_id]
Example #6
0
    def validate_boards(data):
        did_pass = True

        print('boards', end=' ')
        p = 'boards' in data and type(data['boards']) is list
        if p:
            b = data['boards']
        if p:
            print("PASSED")
        else:
            did_pass = False
            print("FAILED")

        # Only if we're running this test standalone do we want to compare against the list
        # of boards returned by ConnectHelper.get_sessions_for_all_connected_probes(). When running in the full
        # automated test suite, there could be other test jobs running concurrently that have
        # exclusive access to the boards they are testing. Thus, those boards will not show up
        # in the return list and this test will fail.
        if testing_standalone:
            try:
                all_sessions = ConnectHelper.get_sessions_for_all_connected_probes(
                    blocking=False)
                all_mbeds = [x.board for x in all_sessions]
                p = len(all_mbeds) == len(b)
                matching_boards = 0
                if p:
                    for mbed in all_mbeds:
                        for brd in b:
                            if mbed.unique_id == brd['unique_id']:
                                matching_boards += 1
                                p = 'info' in brd and 'target' in brd and 'board_name' in brd
                                if not p:
                                    break
                        if not p:
                            break
                    p = matching_boards == len(all_mbeds)
                if p:
                    print("PASSED")
                else:
                    did_pass = False
                    print("FAILED")
            except Exception as e:
                print("FAILED")
                traceback.print_exc(file=sys.stdout)
                did_pass = False
        else:
            # Check for required keys in all board info dicts.
            p = True
            for brd in b:
                p = ('unique_id' in brd and 'info' in brd and 'target' in brd
                     and 'board_name' in brd)
                if not p:
                    break
            if p:
                print("PASSED")
            else:
                did_pass = False
                print("FAILED")

        return did_pass
Example #7
0
    def execute(self, capability, *args, **kwargs):
        """Reset a target using pyOCD.

        The "capability" name must be "pyocd". If it isn't this method will just fail.

        Args:
            capability: Capability name.

        Returns:
            True if the reset was successful, otherwise False.
        """
        if not PYOCD_PRESENT:
            self.print_plugin_error(
                'The "pyocd" feature is not installed. Please run '
                '"pip install mbed-os-tools[pyocd]" to enable the "pyocd" reset plugin.'
            )
            return False

        if not kwargs["target_id"]:
            self.print_plugin_error("Error: target_id not set")
            return False

        result = False
        if self.check_parameters(capability, *args, **kwargs) is True:
            if kwargs["target_id"]:
                if capability == "pyocd":
                    target_id = kwargs["target_id"]
                    with ConnectHelper.session_with_chosen_probe(
                        unique_id=target_id, resume_on_disconnect=False
                    ) as session:
                        session.target.reset()
                        session.target.resume()
                        result = True
        return result
Example #8
0
    def open_session(self):
        if self.session is not None and self.session.is_open:
            self.session.close()

        if self.probe is None:
            QMessageBox.information(self.window, "ERROR", "No probe",
                                    QMessageBox.Ok)
            return

        target_device = "stm32f103c8"

        if target_device not in TARGET:
            QMessageBox.information(self.window, "ERROR", "MCU not supported",
                                    QMessageBox.Ok)
            return

        self.session = ConnectHelper.session_with_chosen_probe(
            target_override=target_device, unique_id=self.probe.unique_id)
        self.session.open()

        # print(self.probe.unique_id)
        board = self.session.board
        self.target = board.target

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_default_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()

        self.addr_bin = rom_region.start
        self.ui.flash.setEnabled(True)
Example #9
0
    def open(self) -> None:
        """Open PyOCD interface for NXP SPSDK.

        The PyOCD opening function for SPSDK library to support various DEBUG PROBES.
        The function is used to initialize the connection to target and enable using debug probe
        for DAT purposes.
        :raises ProbeNotFoundError: The probe has not found
        :raises DebugMailBoxAPNotFoundError: The debug mailbox access port NOT found
        :raises DebugProbeError: The PyOCD cannot establish communication with target
        """
        try:
            self.pyocd_session = ConnectHelper.session_with_chosen_probe(
                blocking=False, unique_id=self.hardware_id)

            if self.pyocd_session is None:
                raise ProbeNotFoundError("No probe available!")
            self.pyocd_session.options.set("probe_all_aps", True)
            self.pyocd_session.delegate = self
            self.pyocd_session.open()
            logger.info(
                f"PyOCD connected via {self.pyocd_session.probe.product_name} probe."
            )
        except PyOCDError:
            raise DebugProbeError(
                "PyOCD cannot establish communication with target.")
        self.di = self._get_dmbox_ap()
        # TODO move this functionality into higher level of code
        if self.di is None:
            raise DebugMailBoxAPNotFoundError(
                "No debug mail box access point available!")
Example #10
0
 def test_connect(halt_on_connect, expected_state, resume):
     print("Connecting with halt_on_connect=%s" % halt_on_connect)
     live_session = ConnectHelper.session_with_chosen_probe(
                     board_id=board_id,
                     init_board=False,
                     halt_on_connect=halt_on_connect,
                     resume_on_disconnect=resume,
                     **get_session_options())
     live_session.open()
     live_board = live_session.board
     print("Verifying target is", STATE_NAMES.get(expected_state, "unknown"))
     actualState = live_board.target.get_state()
     # Accept sleeping for running, as a hack to work around nRF52840-DK test binary.
     # TODO remove sleeping hack.
     if (actualState == expected_state) \
             or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING):
         passed = 1
         print("TEST PASSED")
     else:
         passed = 0
         print("TEST FAILED (state={}, expected={})".format(
             STATE_NAMES.get(actualState, "unknown"),
             STATE_NAMES.get(expected_state, "unknown")))
     print("Disconnecting with resume=%s" % resume)
     live_session.close()
     live_session = None
     return passed
Example #11
0
    def __init__(self):
        app = QApplication(sys.argv)
        self.window = QWidget()

        self.ui = Ui_Form()
        self.ui.setupUi(self.window)
        self.session = None

        probes = ConnectHelper.get_all_connected_probes(blocking=False)
        for probe in probes:
            self.ui.daplink_list.addItem(probe.description)
        if len(probes) > 0:
            self.probe = probes[0]
            # print(self.probe)
        else:
            self.probe = None

        # logger = logging.getLogger(__name__)
        # logger.setLevel(level=logging.DEBUG)

        # StreamHandler
        # stream_handler = logging.StreamHandler(self.ui.log.append)
        # stream_handler.setLevel(level=logging.DEBUG)
        # logger.addHandler(stream_handler)

        self.ui.flash.clicked.connect(self.flash_device_run)
        self.ui.update_dap.clicked.connect(self.update_daplink)
        self.ui.connect.clicked.connect(self.open_session)
        self.ui.selsec_firmware.clicked.connect(self.select_file)
        self.ui.daplink_list.currentIndexChanged.connect(self.daplink_change)

        self.ui.flash.setDisabled(True)
        self.ui.progressBar.setValue(0)
        self.window.show()
        app.exec_()
Example #12
0
    def open(self) -> None:
        """Open PyOCD interface for NXP SPSDK.

        The PyOCD opening function for SPSDK library to support various DEBUG PROBES.
        The function is used to initialize the connection to target and enable using debug probe
        for DAT purposes.

        :raises SPSDKProbeNotFoundError: The probe has not found
        :raises SPSDKDebugMailBoxAPNotFoundError: The debug mailbox access port NOT found
        :raises SPSDKDebugProbeError: The PyOCD cannot establish communication with target
        """
        try:
            self.pyocd_session = ConnectHelper.session_with_chosen_probe(
                blocking=False, unique_id=self.hardware_id)

            if self.pyocd_session is None:
                raise SPSDKProbeNotFoundError("No probe available!")
            self.pyocd_session.options.set("scan_all_aps", True)
            self.pyocd_session.delegate = self
            self.pyocd_session.open()
            logger.info(
                f"PyOCD connected via {self.pyocd_session.probe.product_name} probe."
            )
        except PyOCDError as exc:
            raise SPSDKDebugProbeError(
                "PyOCD cannot establish communication with target.") from exc
        self.dbgmlbx_ap = self._get_dmbox_ap()
        self.mem_ap = self._get_mem_ap()
        if self.mem_ap is None:
            logger.warning(
                "The memory interface not found - probably locked device")
        if self.dbgmlbx_ap is None:
            raise SPSDKDebugMailBoxAPNotFoundError(
                "No debug mail box access point available!")
Example #13
0
def search_and_lock(board_id):
    """Repeatedly lock a board with the given ID"""
    for _ in range(0, 20):
        device = DAPAccess.get_device(board_id)
        device.open()
        device.close()
        with ConnectHelper.session_with_chosen_probe(unique_id=board_id):
            pass
Example #14
0
def search_and_lock(board_id):
    """Repeatedly lock a board with the given ID"""
    for _ in range(0, 20):
        device = DAPAccess.get_device(board_id)
        device.open()
        device.close()
        with ConnectHelper.session_with_chosen_probe(unique_id=board_id):
            pass
Example #15
0
    def daplink_change(self):
        probes = ConnectHelper.get_all_connected_probes(blocking=False)

        for probe in probes:
            if probe.description == self.ui.daplink_list.currentText():
                self.probe = probe
            else:
                self.probe = None
Example #16
0
    def execute(self, capability, *args, **kwargs):
        """Flash a firmware image to a device using pyOCD.

        In this implementation we don't seem to care what the capability name is.

        Args:
            capability: Capability name.
            args: Additional arguments.
            kwargs: Additional arguments.

        Returns:
            True if flashing succeeded, otherwise False.
        """
        if not PYOCD_PRESENT:
            self.print_plugin_error(
                'The "pyocd" feature is not installed. Please run '
                '"pip install mbed-os-tools[pyocd]" to enable the "pyocd" copy plugin.'
            )
            return False

        if not self.check_parameters(capability, *args, **kwargs):
            return False

        if not kwargs["image_path"]:
            self.print_plugin_error("Error: image path not specified")
            return False

        if not kwargs["target_id"]:
            self.print_plugin_error("Error: Target ID")
            return False

        target_id = kwargs["target_id"]
        image_path = os.path.normpath(kwargs["image_path"])
        with ConnectHelper.session_with_chosen_probe(
            unique_id=target_id, resume_on_disconnect=False
        ) as session:
            # Performance hack!
            # Eventually pyOCD will know default clock speed
            # per target
            test_clock = 10000000
            target_type = session.board.target_type
            if target_type == "nrf51":
                # Override clock since 10MHz is too fast
                test_clock = 1000000
            if target_type == "ncs36510":
                # Override clock since 10MHz is too fast
                test_clock = 1000000

            # Configure link
            session.probe.set_clock(test_clock)

            # Program the file
            programmer = FileProgrammer(session)
            programmer.program(image_path, format=kwargs["format"])

        return True
Example #17
0
    def update_daplink(self):
        self.ui.daplink_list.clear()
        probes = ConnectHelper.get_all_connected_probes(blocking=False)

        for probe in probes:
            self.ui.daplink_list.addItem(probe.description)
        if len(probes) > 0:
            self.probe = probes[0]
        else:
            self.probe = None
Example #18
0
        def __init__(self, elf_filepath):
            self.session = ConnectHelper.session_with_chosen_probe(
                return_first=True,  # Assuming that 1 board is attached. Or, we just use the first one.
                connect_mode='attach')  # This will keep the target running. default is 'halt' in which case target.resume() should be called.

            self.target = self.session.board.target

            self.target.elf = elf_filepath

            self.provider = ELFSymbolProvider(self.target.elf)
Example #19
0
    def connect(self,
                target_name=None,
                interface=None,
                probe_id=None,
                ap='cm4',
                blocking=True):
        """
        Connects to target using default debug interface.
        :param target_name: The target name.
        :param interface: Debug interface.
        :param ap: The access port used for communication (cm0 or cm4).
        :param probe_id: Probe serial number.
        :param blocking: Specifies whether to wait for a probe to be
               connected if there are no available probes.
        :return: True if connected successfully, otherwise False.
        """
        if interface:
            raise NotImplementedError
        else:
            if target_name:
                logger.info(f'Target: {target_name}')
                # Search for device in target map
                with open(TARGET_MAP) as f:
                    file_content = f.read()
                    json_data = json.loads(file_content)
                for json_target in json_data:
                    if target_name.lower().strip() == json_target.lower(
                    ).strip():
                        target_name = json_data[json_target][ap.lower()]
                        break
                options = {'target_override': target_name}
            else:
                options = {}

            if self.wait_for_target is not None:
                blocking = self.wait_for_target

            self.session = \
                ConnectHelper.session_with_chosen_probe(blocking=blocking,
                                                        options=options,
                                                        board_id=probe_id,
                                                        unique_id=probe_id)
            if self.session is None:
                return False
            self.board = self.session.board
            self.session.open()

            self.target = self.board.target
            self.probe = self.session.probe
            self.ap = ap
            self.set_ap(AP.SYS)
            logger.info(f'Probe ID: {self.probe.unique_id}')
            return True
    def execute(self, capability, *args, **kwargs):
        """! Executes capability by name
        @param capability Capability name
        @param args Additional arguments
        @param kwargs Additional arguments
        @return Capability call return value
        """
        if not PYOCD_PRESENT:
            self.print_plugin_error(
                'The "pyocd" feature is not installed. Please run '
                '"pip install mbed-os-tools[pyocd]" to enable the "pyocd" copy plugin.'
            )
            return False

        if not self.check_parameters(capability, *args, **kwargs):
            return False

        if not kwargs['image_path']:
            self.print_plugin_error("Error: image path not specified")
            return False

        if not kwargs['target_id']:
            self.print_plugin_error("Error: Target ID")
            return False

        target_id = kwargs['target_id']
        image_path = os.path.normpath(kwargs['image_path'])
        with ConnectHelper.session_with_chosen_probe(unique_id=target_id, resume_on_disconnect=False) as session:
            # Performance hack!
            # Eventually pyOCD will know default clock speed
            # per target
            test_clock = 10000000
            target_type = session.board.target_type
            if target_type == "nrf51":
                # Override clock since 10MHz is too fast
                test_clock = 1000000
            if target_type == "ncs36510":
                # Override clock since 10MHz is too fast
                test_clock = 1000000

            # Configure link
            session.probe.set_clock(test_clock)

            # Program the file
            programmer = FileProgrammer(session)
            programmer.program(image_path, format=kwargs['format'])

        return True
Example #21
0
    def connect(self, target_name=None, interface=None, probe_id=None):
        """
        Connects to target using default debug interface.
        :param target_name: The target name.
        :param interface: Debug interface.
        :param probe_id: Probe serial number.
        :return: True if connected successfully, otherwise False.
        """
        if interface:
            raise NotImplementedError
        else:
            if target_name:
                # Search for device in target map
                with open(TARGET_MAP) as f:
                    file_content = f.read()
                    json_data = json.loads(file_content)
                for json_target in json_data:
                    if target_name.lower().strip() == json_target.lower(
                    ).strip():
                        target_name = json_data[json_target]
                        break
                options = {'target_override': target_name}
            else:
                options = {}
            self.session = ConnectHelper.session_with_chosen_probe(
                blocking=True,
                options=options,
                board_id=probe_id,
                unique_id=probe_id)
            if self.session is None:
                return False
            self.board = self.session.board
            self.session.open()

            self.target = self.board.target
            self.probe = self.session.probe

            # Write infinite loop into RAM and start core execution
            self.halt()
            # B662 - CPSIE I - Enable IRQ by clearing PRIMASK
            # E7FE - B - Jump to address (argument is an offset)
            self.write32(0x08000000, 0xE7FEB662)
            self.write_reg('pc', 0x08000000)
            self.write_reg('sp', 0x08001000)
            self.write_reg('xpsr', 0x01000000)
            self.resume()

            return True
Example #22
0
def tgt(request):
    board = None
    try:
        session = ConnectHelper.session_with_chosen_probe(blocking=False, return_first=True)
    except Exception as error:
        logging.error("Exception during session_with_chosen_probe", exc_info=error)
    if session is None:
        pytest.skip("No probe present")
        return
    board = session.board
    session.options['resume_on_disconnect'] = False
    board.target.reset_stop_on_reset()

    def cleanup():
        board.uninit()

    request.addfinalizer(cleanup)
    return board.target
Example #23
0
def tgt(request):
    session = None
    try:
        session = ConnectHelper.session_with_chosen_probe(blocking=False, return_first=True)
    except Exception as error:
        logging.error("Exception during session_with_chosen_probe", exc_info=error)
    if session is None:
        pytest.skip("No probe present")
        return
    session.open()
    session.options['resume_on_disconnect'] = False
    assert session.target
    session.target.reset_and_halt()

    def close_session():
        session.close()

    request.addfinalizer(close_session)
    return session.target
Example #24
0
 def __init__(self, path):
     self.var = {}
     self.path = path
     files = os.listdir(path)
     self.project = ''
     for file in files:
         if file.split('.')[-1] == 'uvprojx':
             self.project = file.replace('.uvprojx', '')
     if self.project == '':
         raise NameError("Can't find keil project file")
     print(path)
     self.session = ConnectHelper.session_with_chosen_probe()
     print('ok')
     self.session.open()
     print('ok')
     self.board = self.session.board
     self.target = self.board.target
     self.target.elf = os.path.join(path, '%s/%s.axf' % (self.project, self.project))
     print(self.target.elf)
     self.provider = ELFSymbolProvider(self.target.elf)
Example #25
0
def tgt(request):
    board = None
    try:
        session = ConnectHelper.session_with_chosen_probe(blocking=False,
                                                          return_first=True)
    except Exception as error:
        logging.error("Exception during session_with_chosen_probe",
                      exc_info=error)
    if session is None:
        pytest.skip("No probe present")
        return
    board = session.board
    session.options['resume_on_disconnect'] = False
    board.target.reset_and_halt()

    def cleanup():
        board.uninit()

    request.addfinalizer(cleanup)
    return board.target
Example #26
0
    def get_connected_probes(cls,
                             hardware_id: str = None
                             ) -> List[ProbeDescription]:
        """Get all connected probes over PyOCD.

        This functions returns the list of all connected probes in system by PyOCD package.
        :param hardware_id: None to list all probes, otherwice the the only probe with matching
            hardware id is listed.
        :return: probe_description
        """
        from .utils import DebugProbes

        probes = DebugProbes()
        connected_probes = ConnectHelper.get_all_connected_probes(
            blocking=False, unique_id=hardware_id)
        for probe in connected_probes:
            probes.append(
                ProbeDescription("PyOCD", probe.unique_id, probe.description,
                                 DebugProbePyOCD))

        return probes
Example #27
0
def user_script_test(board_id):
    with ConnectHelper.session_with_chosen_probe(
            unique_id=board_id,
            user_script=TEST_USER_SCRIPT,
            **get_session_options()) as session:
        board = session.board
        target = session.target

        test_params = get_target_test_params(session)
        session.probe.set_clock(test_params['test_clock'])

        memory_map = target.get_memory_map()
        boot_region = memory_map.get_boot_memory()
        ram_region = memory_map.get_default_region_of_type(MemoryType.RAM)
        binary_file = get_test_binary_path(board.test_binary)

        test_pass_count = 0
        test_count = 0
        result = UserScriptTestResult()

        target.reset_and_halt()
        target.resume()
        target.halt()
        target.step()

        test_count += 1
        test_pass_count += 1

        print("\nTest Summary:")
        print("Pass count %i of %i tests" % (test_pass_count, test_count))
        if test_pass_count == test_count:
            print("USER SCRIPT TEST PASSED")
        else:
            print("USER SCRIPT TEST FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result
    def open_session(self):
        # print("open session")
        if self.probe is None:
            QMessageBox.information(self.window, "ERROR", "No probe",
                                    QMessageBox.Ok)
            return

        if self.ui.device_list.currentText() is "":
            QMessageBox.information(self.window, "ERROR", "select mcu first",
                                    QMessageBox.Ok)
            return

        self.session = ConnectHelper.session_with_chosen_probe(
            target_override=self.ui.device_list.currentText(),
            unique_id=self.probe.unique_id)
        self.session.open()

        # print(self.probe.unique_id)
        board = self.session.board
        self.target = board.target
        # print("Board's name:%s" % board.name)
        # print("Board's description:%s" % board.description)
        # print("Board's target_type:%s" % board.target_type)
        # print("Board's unique_id:%s" % board.unique_id)
        # print("Board's test_binary:%s" % board.test_binary)
        # print("Unique ID: %s" % board.unique_id)

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_default_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()

        self.addr_bin = rom_region.start
        self.ui.erase.setEnabled(True)
        self.ui.flash.setEnabled(True)
        self.ui.run.setEnabled(True)
        self.ui.halt.setEnabled(True)
        self.ui.flash_run.setEnabled(True)
        self.ui.resume.setEnabled(True)
Example #29
0
 def stlinkFlash(self):
     self.Log.write(" Flash PLC use STLink\n")
     try:
         with ConnectHelper.session_with_chosen_probe() as session:
             target = session.target
             # todo:stlink read cpu id
             # if self.dev_id and stm._dev_id != self.dev_id:
             #     self.Log.write_error(_("MCU ID Don't Match!"))
             #     return
             if self.prgBoot.IsChecked():
                 self.Log.write(_('Flash BootLoader ...'))
                 with FileProgrammer(session,
                                     chip_erase='auto',
                                     smart_flash=True) as programmer:
                     programmer.program(self.bootbin,
                                        file_format='bin',
                                        base_address=0x8000000)
             if self.prgRte.IsChecked():
                 self.Log.write(_('Flash RTE firmware ...'))
                 with FileProgrammer(session,
                                     chip_erase='auto',
                                     smart_flash=True) as programmer:
                     programmer.program(self.rtebin,
                                        file_format='bin',
                                        base_address=self.adrRte)
             if self.prgApp.IsChecked():
                 self.Log.write(_('Flash PLC APP ...'))
                 with FileProgrammer(session,
                                     chip_erase='auto',
                                     smart_flash=True) as programmer:
                     programmer.program(self.appBin,
                                        file_format='bin',
                                        base_address=self.adrApp)
         self.Log.write(_('Flash end.'))
     except Exception as e:
         self.Log.write_error(_('Error:%s') % str(e))
         self.Log.write_error(_('Flash Failed.'))
Example #30
0
    def get_connected_probes(cls,
                             hardware_id: str = None,
                             user_params: Dict = None) -> list:
        """Get all connected probes over PyOCD.

        This functions returns the list of all connected probes in system by PyOCD package.

        :param hardware_id: None to list all probes, otherwise the the only probe with matching
            hardware id is listed.
        :param user_params: The user params dictionary
        :return: probe_description
        """
        # pylint: disable=import-outside-toplevel
        from .utils import DebugProbes, ProbeDescription

        probes = DebugProbes()
        connected_probes = ConnectHelper.get_all_connected_probes(
            blocking=False, unique_id=hardware_id)
        for probe in connected_probes:
            probes.append(
                ProbeDescription("PyOCD", probe.unique_id, probe.description,
                                 DebugProbePyOCD))

        return probes
Example #31
0
def flash_loader_test(board_id):
    with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session:
        board = session.board
        target = session.target
        target_type = board.target_type

        test_clock = 10000000
        if target_type == "nrf51":
            # Override clock since 10MHz is too fast
            test_clock = 1000000
        if target_type == "ncs36510":
            # Override clock since 10MHz is too fast
            test_clock = 1000000
        session.probe.set_clock(test_clock)

        memory_map = board.target.get_memory_map()
        boot_region = memory_map.get_boot_memory()
        boot_start_addr = boot_region.start
        boot_end_addr = boot_region.end
        boot_blocksize = boot_region.blocksize

        test_pass_count = 0
        test_count = 0
        result = FlashLoaderTestResult()
        
        binary_file_path = os.path.join(parentdir, 'binaries', board.test_binary)
        with open(binary_file_path, "rb") as f:
            data = list(bytearray(f.read()))
        data_length = len(data)
        
        print("\n------ Test Basic Load ------")
        loader = FlashLoader(session, chip_erase=False)
        loader.add_data(boot_start_addr, data)
        loader.commit()
        verify_data = target.read_memory_block8(boot_start_addr, data_length)
        if same(verify_data, data):
            print("TEST PASSED")
            test_pass_count += 1
        else:
            print("TEST FAILED")
        test_count += 1
        
        print("\n------ Test Load Sector Erase ------")
        test_data = [0x55] * boot_blocksize
        addr = (boot_end_addr + 1) - (boot_blocksize * 2)
        loader = FlashLoader(session, chip_erase=False)
        loader.add_data(addr, test_data)
        loader.add_data(addr + boot_blocksize, test_data)
        loader.commit()
        verify_data = target.read_memory_block8(addr, boot_blocksize * 2)
        verify_data2 = target.read_memory_block8(boot_start_addr, data_length)
        if same(verify_data, test_data * 2) and same(verify_data2, data):
            print("TEST PASSED")
            test_pass_count += 1
        else:
            print("TEST FAILED")
        test_count += 1
        
        print("\n------ Test Basic Sector Erase ------")
        eraser = FlashEraser(session, FlashEraser.Mode.SECTOR)
        eraser.erase(["0x%x+0x%x" % (addr, boot_blocksize)])
        verify_data = target.read_memory_block8(addr, boot_blocksize)
        if target.memory_map.get_region_for_address(addr).is_erased(verify_data):
            print("TEST PASSED")
            test_pass_count += 1
        else:
            print("TEST FAILED")
        test_count += 1
        
        print("\n------ Test Load Chip Erase ------")
        loader = FlashLoader(session, chip_erase=True)
        loader.add_data(boot_start_addr, data)
        loader.commit()
        verify_data = target.read_memory_block8(boot_start_addr, data_length)
        verify_data2 = target.read_memory_block8(addr, boot_blocksize * 2)
        if same(verify_data, data) and target.memory_map.get_region_for_address(addr).is_erased(verify_data2):
            print("TEST PASSED")
            test_pass_count += 1
        else:
            print("TEST FAILED")
        test_count += 1
        
        print("\n------ Test Binary File Load ------")
        programmer = FileProgrammer(session)
        programmer.program(binary_file_path, format='bin', base_address=boot_start_addr)
        verify_data = target.read_memory_block8(boot_start_addr, data_length)
        if same(verify_data, data):
            print("TEST PASSED")
            test_pass_count += 1
        else:
            print("TEST FAILED")
        test_count += 1

        print("\n\nTest Summary:")
        print("Pass count %i of %i tests" % (test_pass_count, test_count))
        if test_pass_count == test_count:
            print("FLASH TEST SCRIPT PASSED")
        else:
            print("FLASH TEST SCRIPT FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Example #32
0
def basic_test(board_id, file):
    with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session:
        board = session.board
        addr = 0
        size = 0
        f = None
        binary_file = "l1_"

        if file is None:
            binary_file = os.path.join(parentdir, 'binaries', board.test_binary)
        else:
            binary_file = file

        print("binary file: %s" % binary_file)

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()

        addr = ram_region.start
        size = 0x502
        addr_bin = rom_region.start
        addr_flash = rom_region.start + rom_region.length // 2

        target = board.target
        flash = rom_region.flash

        print("\n\n------ GET Unique ID ------")
        print("Unique ID: %s" % board.unique_id)

        print("\n\n------ TEST READ / WRITE CORE REGISTER ------")
        pc = target.read_core_register('pc')
        print("initial pc: 0x%X" % target.read_core_register('pc'))
        # write in pc dummy value
        target.write_core_register('pc', 0x3D82)
        print("now pc: 0x%X" % target.read_core_register('pc'))
        # write initial pc value
        target.write_core_register('pc', pc)
        print("initial pc value rewritten: 0x%X" % target.read_core_register('pc'))

        msp = target.read_core_register('msp')
        psp = target.read_core_register('psp')
        print("MSP = 0x%08x; PSP = 0x%08x" % (msp, psp))

        control = target.read_core_register('control')
        faultmask = target.read_core_register('faultmask')
        basepri = target.read_core_register('basepri')
        primask = target.read_core_register('primask')
        print("CONTROL = 0x%02x; FAULTMASK = 0x%02x; BASEPRI = 0x%02x; PRIMASK = 0x%02x" % (control, faultmask, basepri, primask))

        target.write_core_register('primask', 1)
        newPrimask = target.read_core_register('primask')
        print("New PRIMASK = 0x%02x" % newPrimask)
        target.write_core_register('primask', primask)
        newPrimask = target.read_core_register('primask')
        print("Restored PRIMASK = 0x%02x" % newPrimask)

        if target.has_fpu:
            s0 = target.read_core_register('s0')
            print("S0 = %g (0x%08x)" % (s0, float32_to_u32(s0)))
            target.write_core_register('s0', math.pi)
            newS0 = target.read_core_register('s0')
            print("New S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0)))
            target.write_core_register('s0', s0)
            newS0 = target.read_core_register('s0')
            print("Restored S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0)))


        print("\n\n------ TEST HALT / RESUME ------")

        print("resume")
        target.resume()
        sleep(0.2)

        print("halt")
        target.halt()
        print("HALT: pc: 0x%X" % target.read_core_register('pc'))
        sleep(0.2)


        print("\n\n------ TEST STEP ------")

        print("reset and halt")
        target.reset_stop_on_reset()
        currentPC = target.read_core_register('pc')
        print("HALT: pc: 0x%X" % currentPC)
        sleep(0.2)

        for i in range(4):
            print("step")
            target.step()
            newPC = target.read_core_register('pc')
            print("STEP: pc: 0x%X" % newPC)
            currentPC = newPC
            sleep(0.2)


        print("\n\n------ TEST READ / WRITE MEMORY ------")
        target.halt()
        print("READ32/WRITE32")
        val = randrange(0, 0xffffffff)
        print("write32 0x%X at 0x%X" % (val, addr))
        target.write_memory(addr, val)
        res = target.read_memory(addr)
        print("read32 at 0x%X: 0x%X" % (addr, res))
        if res != val:
            print("ERROR in READ/WRITE 32")

        print("\nREAD16/WRITE16")
        val = randrange(0, 0xffff)
        print("write16 0x%X at 0x%X" % (val, addr + 2))
        target.write_memory(addr + 2, val, 16)
        res = target.read_memory(addr + 2, 16)
        print("read16 at 0x%X: 0x%X" % (addr + 2, res))
        if res != val:
            print("ERROR in READ/WRITE 16")

        print("\nREAD8/WRITE8")
        val = randrange(0, 0xff)
        print("write8 0x%X at 0x%X" % (val, addr + 1))
        target.write_memory(addr + 1, val, 8)
        res = target.read_memory(addr + 1, 8)
        print("read8 at 0x%X: 0x%X" % (addr + 1, res))
        if res != val:
            print("ERROR in READ/WRITE 8")


        print("\n\n------ TEST READ / WRITE MEMORY BLOCK ------")
        data = [randrange(1, 50) for x in range(size)]
        target.write_memory_block8(addr, data)
        block = target.read_memory_block8(addr, size)
        error = False
        for i in range(len(block)):
            if (block[i] != data[i]):
                error = True
                print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i]))
        if error:
            print("TEST FAILED")
        else:
            print("TEST PASSED")


        print("\n\n------ TEST RESET ------")
        target.reset()
        sleep(0.1)
        target.halt()

        for i in range(5):
            target.step()
            print("pc: 0x%X" % target.read_core_register('pc'))

        print("\n\n------ TEST PROGRAM/ERASE PAGE ------")
        # Fill 3 pages with 0x55
        page_size = flash.get_page_info(addr_flash).size
        fill = [0x55] * page_size
        for i in range(0, 3):
            address = addr_flash + page_size * i
            # Test only supports a location with 3 aligned
            # pages of the same size
            current_page_size = flash.get_page_info(addr_flash).size
            assert page_size == current_page_size
            assert address % current_page_size == 0

            flash.init(flash.Operation.ERASE)
            flash.erase_page(address)
            flash.uninit()

            flash.init(flash.Operation.PROGRAM)
            flash.program_page(address, fill)
            flash.uninit()
        # Erase the middle page
        flash.init(flash.Operation.ERASE)
        flash.erase_page(addr_flash + page_size)
        flash.cleanup()
        # Verify the 1st and 3rd page were not erased, and that the 2nd page is fully erased
        data = target.read_memory_block8(addr_flash, page_size * 3)
        expected = fill + [0xFF] * page_size + fill
        if data == expected:
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("\n\n----- FLASH NEW BINARY -----")
        FileProgrammer(session).program(binary_file, base_address=addr_bin)

        target.reset()
Example #33
0
def test_gdb(board_id=None, n=0):
    temp_test_elf_name = None
    result = GdbTestResult()
    with ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) as session:
        board = session.board
        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()
        target_type = board.target_type
        binary_file = os.path.join(parentdir, 'binaries',
                                   board.test_binary)
        if board_id is None:
            board_id = board.unique_id
        test_clock = 10000000
        test_port = 3333 + n
        telnet_port = 4444 + n
        error_on_invalid_access = True
        # Hardware breakpoints are not supported above 0x20000000 on
        # CortexM devices
        ignore_hw_bkpt_result = 1 if ram_region.start >= 0x20000000 else 0
        if target_type in ("nrf51", "nrf52", "nrf52840"):
            # Override clock since 10MHz is too fast
            test_clock = 1000000
            # Reading invalid ram returns 0 or nrf51
            error_on_invalid_access = False
        if target_type == "ncs36510":
            # Override clock since 10MHz is too fast
            test_clock = 1000000

        # Program with initial test image
        FileProgrammer(session).program(binary_file, base_address=rom_region.start)

    # Generate an elf from the binary test file.
    temp_test_elf_name = tempfile.mktemp('.elf')
    objcopyOutput = check_output([OBJCOPY,
        "-v", "-I", "binary", "-O", "elf32-littlearm", "-B", "arm", "-S",
        "--set-start", "0x%x" % rom_region.start,
        "--change-addresses", "0x%x" % rom_region.start,
        binary_file, temp_test_elf_name], stderr=STDOUT)
    print(to_str_safe(objcopyOutput))
    # Need to escape backslashes on Windows.
    if sys.platform.startswith('win'):
        temp_test_elf_name = temp_test_elf_name.replace('\\', '\\\\')

    # Write out the test configuration
    test_params = {
        "test_port" : test_port,
        "rom_start" : rom_region.start,
        "rom_length" : rom_region.length,
        "ram_start" : ram_region.start,
        "ram_length" : ram_region.length,
        "invalid_start" : 0x3E000000,
        "invalid_length" : 0x1000,
        "expect_error_on_invalid_access" : error_on_invalid_access,
        "ignore_hw_bkpt_result" : ignore_hw_bkpt_result,
        "test_elf" : temp_test_elf_name,
        }
    test_param_filename = "test_params%d.txt" % n
    with open(test_param_filename, "w") as f:
        f.write(json.dumps(test_params))

    # Run the test
    gdb = [PYTHON_GDB, "-ex", "set $testn=%d" % n, "--command=gdb_script.py"]
    output_filename = "output_%s_%d.txt" % (board.target_type, n)
    with open(output_filename, "w") as f:
        program = Popen(gdb, stdin=PIPE, stdout=f, stderr=STDOUT)
        args = ['gdbserver',
                '--port=%i' % test_port,
                "--telnet-port=%i" % telnet_port,
                "--frequency=%i" % test_clock,
                "--uid=%s" % board_id,
                '-Oboard_config_file=test_boards.json'
                ]
        server = PyOCDTool()
        server.run(args)
        program.wait()

    # Read back the result
    test_result_filename = "test_results%d.txt" % n
    with open(test_result_filename, "r") as f:
        test_result = json.loads(f.read())

    # Print results
    if set(TEST_RESULT_KEYS).issubset(test_result):
        print("----------------Test Results----------------")
        print("HW breakpoint count: %s" % test_result["breakpoint_count"])
        print("Watchpoint count: %s" % test_result["watchpoint_count"])
        print("Average instruction step time: %s" %
              test_result["step_time_si"])
        print("Average single step time: %s" % test_result["step_time_s"])
        print("Average over step time: %s" % test_result["step_time_n"])
        print("Failure count: %i" % test_result["fail_count"])
        result.passed = test_result["fail_count"] == 0
    else:
        result.passed = False

    # Cleanup
    if temp_test_elf_name and os.path.exists(temp_test_elf_name):
        os.remove(temp_test_elf_name)
    os.remove(test_result_filename)
    os.remove(test_param_filename)

    return result
Example #34
0
def main():
    parser = argparse.ArgumentParser(description='pyOCD automated testing')
    parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging')
    parser.add_argument('-q', '--quiet', action="store_true", help='Hide test progress for 1 job')
    parser.add_argument('-j', '--jobs', action="store", default=1, type=int, metavar="JOBS",
        help='Set number of concurrent board tests (default is 1)')
    parser.add_argument('-b', '--board', action="append", metavar="ID", help="Limit testing to boards with specified unique IDs. Multiple boards can be listed.")
    args = parser.parse_args()
    
    # Force jobs to 1 when running under CI until concurrency issues with enumerating boards are
    # solved. Specifically, the connect test has intermittently failed to open boards on Linux and
    # Win7. This is only done under CI, and in this script, to make testing concurrent runs easy.
    if 'CI_TEST' in os.environ:
        args.jobs = 1
    
    # Disable multiple jobs on macOS prior to Python 3.4. By default, multiprocessing uses
    # fork() on Unix, which doesn't work on the Mac because CoreFoundation requires exec()
    # to be used in order to init correctly (CoreFoundation is used in hidapi). Only on Python
    # version 3.4+ is the multiprocessing.set_start_method() API available that lets us
    # switch to the 'spawn' method, i.e. exec().
    if args.jobs > 1 and sys.platform.startswith('darwin') and sys.version_info[0:2] < (3, 4):
        print("WARNING: Cannot support multiple jobs on macOS prior to Python 3.4. Forcing 1 job.")
        args.jobs = 1

    # Setup logging based on concurrency and quiet option.
    level = logging.DEBUG if args.debug else logging.INFO
    if args.jobs == 1 and not args.quiet:
        # Create common log file.
        if os.path.exists(LOG_FILE):
            os.remove(LOG_FILE)
        logToConsole = True
        commonLogFile = open(LOG_FILE, "a")
    else:
        logToConsole = False
        commonLogFile = None

    board_list = []
    result_list = []

    # Put together list of boards to test
    board_list = ConnectHelper.get_all_connected_probes(blocking=False)
    board_id_list = sorted(b.unique_id for b in board_list)
    
    # Filter boards.
    if args.board:
        board_id_list = [b for b in board_id_list if any(c for c in args.board if c.lower() in b.lower())]

    # If only 1 job was requested, don't bother spawning processes.
    start = time()
    if args.jobs == 1:
        for n, board_id in enumerate(board_id_list):
            result_list += test_board(board_id, n, level, logToConsole, commonLogFile)
    else:
        # Create a pool of processes to run tests.
        try:
            pool = mp.Pool(args.jobs)
            
            # Issue board test job to process pool.
            async_results = [pool.apply_async(test_board, (board_id, n, level, logToConsole, commonLogFile))
                             for n, board_id in enumerate(board_id_list)]
            
            # Gather results.
            for r in async_results:
                result_list += r.get(timeout=JOB_TIMEOUT)
        finally:
            pool.close()
            pool.join()
    stop = time()
    test_time = (stop - start)

    print_summary(test_list, result_list, test_time)
    with open(SUMMARY_FILE, "w") as output_file:
        print_summary(test_list, result_list, test_time, output_file)
    generate_xml_results(result_list)
    
    exit_val = 0 if Test.all_tests_pass(result_list) else -1
    exit(exit_val)
Example #35
0
def test_mass_storage(workspace, parent_test):
    """Test the mass storage endpoint

    Requirements:
        None

    Positional arguments:
        filename - A string containing the name of the file to load

    Return:
        True if the test passed, False otherwise
    """
    test_info = parent_test.create_subtest('test_mass_storage')

    # Setup test
    board = workspace.board
    target = workspace.target
    bin_file = target.bin_path
    hex_file = target.hex_path
    with open(bin_file, 'rb') as test_file:
        bin_file_contents = bytearray(test_file.read())
    with open(hex_file, 'rb') as test_file:
        hex_file_contents = bytearray(test_file.read())
    blank_bin_contents = bytearray([0xff]) * 0x2000
    vectors_and_pad = bin_file_contents[0:32] + blank_bin_contents
    locked_when_erased = board.get_board_id() in info.BOARD_ID_LOCKED_WHEN_ERASED
    page_erase_supported = board.get_board_id() in info.BOARD_ID_SUPPORTING_PAGE_ERASE
    bad_vector_table = target.name in info.TARGET_WITH_BAD_VECTOR_TABLE_LIST

    intel_hex = intelhex.IntelHex(hex_file)
    addresses = intel_hex.addresses()
    addresses.sort()
    start = addresses[0]

    # Test loading a binary file with shutils
    if not bad_vector_table:
        test = MassStorageTester(board, test_info, "Shutil binary file load")
        test.set_shutils_copy(bin_file)
        test.set_expected_data(bin_file_contents, start)
        test.run()

    # Test loading a binary file with flushes
    if not bad_vector_table:
        test = MassStorageTester(board, test_info, "Load binary with flushes")
        test.set_programming_data(bin_file_contents, 'image.bin')
        test.set_expected_data(bin_file_contents, start)
        test.set_flush_size(0x1000)
        test.run()

    # Test loading a hex file with shutils
    test = MassStorageTester(board, test_info, "Shutil hex file load")
    test.set_shutils_copy(hex_file)
    test.set_expected_data(bin_file_contents, start)
    test.run()

    # Test loading a hex file with flushes
    test = MassStorageTester(board, test_info, "Load hex with flushes")
    test.set_programming_data(hex_file_contents, 'image.hex')
    test.set_expected_data(bin_file_contents, start)
    test.set_flush_size(0x1000)
    test.run()

    # Test loading a binary smaller than a sector
    if not bad_vector_table:
        test = MassStorageTester(board, test_info, "Load .bin smaller than sector")
        test_data_size = 0x789
        test_data = bin_file_contents[0:0 + test_data_size]
        test.set_programming_data(test_data, 'image.bin')
        test.set_expected_data(test_data, start)
        test.run()

    # Test loading a blank binary - this image should cause a timeout
    #    since it doesn't have a valid vector table
    test = MassStorageTester(board, test_info, "Load blank binary")
    test.set_programming_data(blank_bin_contents, 'image.bin')
    test.set_expected_failure_msg("The transfer timed out.", "transient, user")
    test.set_expected_data(None, start)
    test.run()

    # Test loading a blank binary with a vector table but padded with 0xFF.
    #    A blank image can lock some devices.
    if not bad_vector_table:
        test = MassStorageTester(board, test_info, "Load blank binary + vector table")
        test.set_programming_data(vectors_and_pad, 'image.bin')
        if locked_when_erased:
            test.set_expected_failure_msg("The interface firmware ABORTED programming. Image is trying to set security bits", "user")
            test.set_expected_data(None, start)
        else:
            test.set_expected_data(vectors_and_pad, start)
        test.run()

    # Test a normal load with dummy files created beforehand
    test = MassStorageTester(board, test_info, "Extra Files")
    test.set_programming_data(hex_file_contents, 'image.hex')
    test.add_mock_dirs(MOCK_DIR_LIST)
    test.add_mock_files(MOCK_FILE_LIST)
    test.add_mock_dirs_after_load(MOCK_DIR_LIST_AFTER)
    test.add_mock_files_after_load(MOCK_FILE_LIST_AFTER)
    test.set_expected_data(bin_file_contents, start)
    test.run()
    # Note - it is not unexpected for an "Extra Files" test to fail
    #        when a binary file is loaded, since there is no way to
    #        tell where the end of the file is.

    if page_erase_supported:
        # Test page erase, a.k.a. sector erase by generating iHex with discrete addresses,
        # programing the device then comparing device memory against expected content.
        test = MassStorageTester(board, test_info, "Sector Erase")
        with ConnectHelper.session_with_chosen_probe(unique_id=board.get_unique_id(), open_session=False) as session:
            memory_map = session.target.memory_map
        flash_regions = memory_map.get_regions_of_type(MemoryType.FLASH)

        max_address = intel_hex.maxaddr()
        # Create an object. We'll add the addresses of unused even blocks to it first, then unused odd blocks for each region
        ih = intelhex.IntelHex()
        # Add the content from test bin first
        expected_bin_contents = bin_file_contents
        for region_index, the_region in enumerate(flash_regions):
            if the_region.is_boot_memory is False:
                continue
            flash_start = the_region.start
            flash_length = the_region.length
            block_size = the_region.blocksize

            number_of_blocks = flash_length // block_size

            # Sanity check the regions are contiguous
            if region_index:
                assert flash_start == (flash_regions[region_index - 1].start + flash_regions[region_index - 1].length)

            if max_address >= (flash_start + flash_length):
                # This bin image crosses this region, don't modify the content, go to the next region
                continue
            elif max_address >= flash_start:
                # This bin image occupies partial region. Skip the used portion to avoid touching any security bits and pad the rest
                expected_bin_contents += bytearray([0xff]) * (flash_start + flash_length - max_address - 1)
                # Calculate the starting block after the image to avoid stumbling upon security bits
                block_start = (max_address - flash_start) // block_size + 1
            else:
                # This bin image doesn't reach this region
                expected_bin_contents += bytearray([0xff]) * flash_length
                block_start = 0
            # For all even blocks, overwrite all addresses with 0x55; for all odd blocks, overwrite all addresses with 0xAA
            for pass_number in range (2):
                if pass_number == 0:
                    modifier = 0x55
                else:
                    modifier = 0xAA
                    block_start += 1
                for block_idx in range(block_start, number_of_blocks, 2):
                    for address_to_modify in range (flash_start + block_idx * block_size, flash_start + (block_idx + 1) * block_size):
                        expected_bin_contents[address_to_modify] = modifier
                        ih[address_to_modify] = modifier
        if not os.path.exists("tmp"):
            os.makedirs("tmp")
        # Write out the modified iHex to file
        ih.tofile("tmp/interleave.hex", format='hex')
        # Load this hex file with shutils
        test.set_shutils_copy("tmp/interleave.hex")
        test.set_expected_data(expected_bin_contents, start)
        test.run()

    # Finally, load a good binary
    test = MassStorageTester(board, test_info, "Load good file to restore state")
    test.set_programming_data(hex_file_contents, 'image.hex')
    test.set_expected_data(bin_file_contents, start)
    test.run()
Example #36
0
def cortex_test(board_id):
    with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session:
        board = session.board
        target_type = board.target_type

        binary_file = os.path.join(parentdir, 'binaries', board.test_binary)

        test_params = get_target_test_params(session)
        test_clock = test_params['test_clock']
        addr_invalid = 0x3E000000 # Last 16MB of ARM SRAM region - typically empty
        expect_invalid_access_to_fail = test_params['error_on_invalid_access']

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()

        addr = ram_region.start
        size = 0x502
        addr_bin = rom_region.start

        target = board.target
        probe = session.probe

        probe.set_clock(test_clock)

        test_pass_count = 0
        test_count = 0
        result = CortexTestResult()

        debugContext = target.get_target_context()
        gdbFacade = GDBDebugContextFacade(debugContext)

        print("\n\n----- FLASH NEW BINARY BEFORE TEST -----")
        FileProgrammer(session).program(binary_file, base_address=addr_bin)
        # Let the target run for a bit so it
        # can initialize the watchdog if it needs to
        target.resume()
        sleep(0.2)
        target.halt()

        print("PROGRAMMING COMPLETE")


        print("\n\n----- TESTING CORTEX-M PERFORMANCE -----")
        test_time = test_function(session, gdbFacade.get_t_response)
        result.times["get_t_response"] = test_time
        print("Function get_t_response time: %f" % test_time)

        # Step
        test_time = test_function(session, target.step)
        result.times["step"] = test_time
        print("Function step time: %f" % test_time)

        # Breakpoint
        def set_remove_breakpoint():
            target.set_breakpoint(0)
            target.remove_breakpoint(0)
        test_time = test_function(session, set_remove_breakpoint)
        result.times["bp_add_remove"] = test_time
        print("Add and remove breakpoint: %f" % test_time)

        # get_register_context
        test_time = test_function(session, gdbFacade.get_register_context)
        result.times["get_reg_context"] = test_time
        print("Function get_register_context: %f" % test_time)

        # set_register_context
        context = gdbFacade.get_register_context()
        def set_register_context():
            gdbFacade.set_register_context(context)
        test_time = test_function(session, set_register_context)
        result.times["set_reg_context"] = test_time
        print("Function set_register_context: %f" % test_time)

        # Run / Halt
        def run_halt():
            target.resume()
            target.halt()
        test_time = test_function(session, run_halt)
        result.times["run_halt"] = test_time
        print("Resume and halt: %f" % test_time)

        # GDB stepping
        def simulate_step():
            target.step()
            gdbFacade.get_t_response()
            target.set_breakpoint(0)
            target.resume()
            target.halt()
            gdbFacade.get_t_response()
            target.remove_breakpoint(0)
        test_time = test_function(session, simulate_step)
        result.times["gdb_step"] = test_time
        print("Simulated GDB step: %f" % test_time)

        # Test passes if there are no exceptions
        test_pass_count += 1
        test_count += 1
        print("TEST PASSED")

        print("\n\n------ Testing Reset Types ------")
        def reset_methods(fnc):
            print("Hardware reset")
            fnc(reset_type=Target.ResetType.HW)
            print("Hardware reset (default=HW)")
            target.selected_core.default_reset_type = Target.ResetType.HW
            fnc(reset_type=None)
            print("Software reset (default=SYSRESETREQ)")
            target.selected_core.default_reset_type = Target.ResetType.SW_SYSRESETREQ
            fnc(reset_type=None)
            print("Software reset (default=VECTRESET)")
            target.selected_core.default_reset_type = Target.ResetType.SW_VECTRESET
            fnc(reset_type=None)
            print("Software reset (default=emulated)")
            target.selected_core.default_reset_type = Target.ResetType.SW_EMULATED
            fnc(reset_type=None)
            
            print("(Default) Software reset (SYSRESETREQ)")
            target.selected_core.default_software_reset_type = Target.ResetType.SW_SYSRESETREQ
            fnc(reset_type=Target.ResetType.SW)
            print("(Default) Software reset (VECTRESET)")
            target.selected_core.default_software_reset_type = Target.ResetType.SW_VECTRESET
            fnc(reset_type=Target.ResetType.SW)
            print("(Default) Software reset (emulated)")
            target.selected_core.default_software_reset_type = Target.ResetType.SW_EMULATED
            fnc(reset_type=Target.ResetType.SW)
            
            print("Software reset (option=default)")
            target.selected_core.default_reset_type = Target.ResetType.SW
            target.selected_core.default_software_reset_type = Target.ResetType.SW_SYSRESETREQ
            session.options['reset_type'] = 'default'
            fnc(reset_type=None)
            print("Software reset (option=hw)")
            session.options['reset_type'] = 'hw'
            fnc(reset_type=None)
            print("Software reset (option=sw)")
            session.options['reset_type'] = 'sw'
            fnc(reset_type=None)
            print("Software reset (option=sw_sysresetreq)")
            session.options['reset_type'] = 'sw_sysresetreq'
            fnc(reset_type=None)
            print("Software reset (option=sw_vectreset)")
            session.options['reset_type'] = 'sw_vectreset'
            fnc(reset_type=None)
            print("Software reset (option=sw_emulated)")
            session.options['reset_type'] = 'sw_emulated'
            fnc(reset_type=None)

        reset_methods(target.reset)
        
        # Test passes if there are no exceptions
        test_pass_count += 1
        test_count += 1
        print("TEST PASSED")


        print("\n\n------ Testing Reset Halt ------")
        reset_methods(target.reset_and_halt)

        # Test passes if there are no exceptions
        test_pass_count += 1
        test_count += 1
        print("TEST PASSED")


        print("\n\n------ Testing Register Read/Write ------")
        print("Reading r0")
        val = target.read_core_register('r0')
        origR0 = val
        rawVal = target.read_core_register_raw('r0')
        test_count += 1
        if val == rawVal:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("Writing r0")
        target.write_core_register('r0', 0x12345678)
        val = target.read_core_register('r0')
        rawVal = target.read_core_register_raw('r0')
        test_count += 1
        if val == 0x12345678 and rawVal == 0x12345678:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("Raw writing r0")
        target.write_core_register_raw('r0', 0x87654321)
        val = target.read_core_register('r0')
        rawVal = target.read_core_register_raw('r0')
        test_count += 1
        if val == 0x87654321 and rawVal == 0x87654321:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("Read/write r0, r1, r2, r3")
        origRegs = target.read_core_registers_raw(['r0', 'r1', 'r2', 'r3'])
        target.write_core_registers_raw(['r0', 'r1', 'r2', 'r3'], [1, 2, 3, 4])
        vals = target.read_core_registers_raw(['r0', 'r1', 'r2', 'r3'])
        passed = vals[0] == 1 and vals[1] == 2 and vals[2] == 3 and vals[3] == 4
        test_count += 1
        if passed:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")
            
        # Restore regs
        origRegs[0] = origR0
        target.write_core_registers_raw(['r0', 'r1', 'r2', 'r3'], origRegs)

        if target.selected_core.has_fpu:
            print("Reading s0")
            val = target.read_core_register('s0')
            rawVal = target.read_core_register_raw('s0')
            origRawS0 = rawVal
            passed = isinstance(val, float) and isinstance(rawVal, int) \
                        and float32_to_u32(val) == rawVal
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED")

            print("Writing s0")
            target.write_core_register('s0', math.pi)
            val = target.read_core_register('s0')
            rawVal = target.read_core_register_raw('s0')
            passed = float_compare(val, math.pi) and float_compare(u32_to_float32(rawVal), math.pi)
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED (%f==%f, 0x%08x->%f)" % (val, math.pi, rawVal, u32_to_float32(rawVal)))

            print("Raw writing s0")
            x = float32_to_u32(32.768)
            target.write_core_register_raw('s0', x)
            val = target.read_core_register('s0')
            passed = float_compare(val, 32.768)
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED (%f==%f)" % (val, 32.768))

            print("Read/write s0, s1")
            _1p1 = float32_to_u32(1.1)
            _2p2 = float32_to_u32(2.2)
            origRegs = target.read_core_registers_raw(['s0', 's1'])
            target.write_core_registers_raw(['s0', 's1'], [_1p1, _2p2])
            vals = target.read_core_registers_raw(['s0', 's1'])
            s0 = target.read_core_register('s0')
            s1 = target.read_core_register('s1')
            passed = vals[0] == _1p1 and float_compare(s0, 1.1) \
                        and vals[1] == _2p2 and float_compare(s1, 2.2)
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED (0x%08x==0x%08x, %f==%f, 0x%08x==0x%08x, %f==%f)" \
                    % (vals[0], _1p1, s0, 1.1, vals[1], _2p2, s1, 2.2))
            
            # Restore s0
            origRegs[0] = origRawS0
            target.write_core_registers_raw(['s0', 's1'], origRegs)
        

        print("\n\n------ Testing Invalid Memory Access Recovery ------")
        memory_access_pass = True
        try:
            print("reading 0x1000 bytes at invalid address 0x%08x" % addr_invalid)
            target.read_memory_block8(addr_invalid, 0x1000)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        try:
            print("reading 0x1000 bytes at invalid address 0x%08x" % (addr_invalid + 1))
            target.read_memory_block8(addr_invalid + 1, 0x1000)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        data = [0x00] * 0x1000
        try:
            print("writing 0x%08x bytes at invalid address 0x%08x" % (len(data), addr_invalid))
            target.write_memory_block8(addr_invalid, data)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault!")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        data = [0x00] * 0x1000
        try:
            print("writing 0x%08x bytes at invalid address 0x%08x" % (len(data), addr_invalid + 1))
            target.write_memory_block8(addr_invalid + 1, data)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault!")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        data = [randrange(0, 255) for x in range(size)]
        print("r/w 0x%08x bytes at 0x%08x" % (size, addr))
        target.write_memory_block8(addr, data)
        block = target.read_memory_block8(addr, size)
        if same(data, block):
            print("  Aligned access pass")
        else:
            print("  Memory read does not match memory written")
            memory_access_pass = False

        data = [randrange(0, 255) for x in range(size)]
        print("r/w 0x%08x bytes at 0x%08x" % (size, addr + 1))
        target.write_memory_block8(addr + 1, data)
        block = target.read_memory_block8(addr + 1, size)
        if same(data, block):
            print("  Unaligned access pass")
        else:
            print("  Unaligned memory read does not match memory written")
            memory_access_pass = False

        test_count += 1
        if memory_access_pass:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("\n\n------ Testing Software Breakpoints ------")
        test_passed = True
        orig8x2 = target.read_memory_block8(addr, 2)
        orig8 = target.read8(addr)
        orig16 = target.read16(addr & ~1)
        orig32 = target.read32(addr & ~3)
        origAligned32 = target.read_memory_block32(addr & ~3, 1)

        def test_filters():
            test_passed = True
            filtered = target.read_memory_block8(addr, 2)
            if same(orig8x2, filtered):
                print("2 byte unaligned passed")
            else:
                print("2 byte unaligned failed (read %x-%x, expected %x-%x)" % (filtered[0], filtered[1], orig8x2[0], orig8x2[1]))
                test_passed = False

            for now in (True, False):
                filtered = target.read8(addr, now)
                if not now:
                    filtered = filtered()
                if filtered == orig8:
                    print("8-bit passed [now=%s]" % now)
                else:
                    print("8-bit failed [now=%s] (read %x, expected %x)" % (now, filtered, orig8))
                    test_passed = False

                filtered = target.read16(addr & ~1, now)
                if not now:
                    filtered = filtered()
                if filtered == orig16:
                    print("16-bit passed [now=%s]" % now)
                else:
                    print("16-bit failed [now=%s] (read %x, expected %x)" % (now, filtered, orig16))
                    test_passed = False

                filtered = target.read32(addr & ~3, now)
                if not now:
                    filtered = filtered()
                if filtered == orig32:
                    print("32-bit passed [now=%s]" % now)
                else:
                    print("32-bit failed [now=%s] (read %x, expected %x)" % (now, filtered, orig32))
                    test_passed = False

            filtered = target.read_memory_block32(addr & ~3, 1)
            if same(filtered, origAligned32):
                print("32-bit aligned passed")
            else:
                print("32-bit aligned failed (read %x, expected %x)" % (filtered[0], origAligned32[0]))
                test_passed = False
            return test_passed

        print("Installed software breakpoint at 0x%08x" % addr)
        target.set_breakpoint(addr, Target.BREAKPOINT_SW)
        test_passed = test_filters() and test_passed

        print("Removed software breakpoint")
        target.remove_breakpoint(addr)
        test_passed = test_filters() and test_passed

        test_count += 1
        if test_passed:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Example #37
0
def test_gdb(board_id=None, n=0):
    temp_test_elf_name = None
    result = GdbTestResult()
    with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session:
        board = session.board
        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()
        target_type = board.target_type
        binary_file = os.path.join(parentdir, 'binaries',
                                   board.test_binary)
        if board_id is None:
            board_id = board.unique_id
        target_test_params = get_target_test_params(session)
        test_port = 3333 + n
        telnet_port = 4444 + n
        # Hardware breakpoints are not supported above 0x20000000 on
        # CortexM devices
        ignore_hw_bkpt_result = 1 if ram_region.start >= 0x20000000 else 0

        # Program with initial test image
        FileProgrammer(session).program(binary_file, base_address=rom_region.start)

    # Generate an elf from the binary test file.
    temp_test_elf_name = binary_to_elf_file(binary_file, rom_region.start)

    # Write out the test configuration
    test_params = {
        "test_port" : test_port,
        "rom_start" : rom_region.start,
        "rom_length" : rom_region.length,
        "ram_start" : ram_region.start,
        "ram_length" : ram_region.length,
        "invalid_start" : 0x3E000000,
        "invalid_length" : 0x1000,
        "expect_error_on_invalid_access" : target_test_params['error_on_invalid_access'],
        "ignore_hw_bkpt_result" : ignore_hw_bkpt_result,
        "test_elf" : temp_test_elf_name,
        }
    test_param_filename = "test_params%d.txt" % n
    with open(test_param_filename, "w") as f:
        f.write(json.dumps(test_params))

    # Run the test
    gdb = [PYTHON_GDB, "-ex", "set $testn=%d" % n, "--command=gdb_script.py"]
    output_filename = "output_%s_%d.txt" % (board.target_type, n)
    with open(output_filename, "w") as f:
        program = Popen(gdb, stdin=PIPE, stdout=f, stderr=STDOUT)
        args = ['gdbserver',
                '--port=%i' % test_port,
                "--telnet-port=%i" % telnet_port,
                "--frequency=%i" % target_test_params['test_clock'],
                "--uid=%s" % board_id,
                ]
        server = PyOCDTool()
        server.run(args)
        program.wait()

    # Read back the result
    test_result_filename = "test_results%d.txt" % n
    with open(test_result_filename, "r") as f:
        test_result = json.loads(f.read())

    # Print results
    if set(TEST_RESULT_KEYS).issubset(test_result):
        print("----------------Test Results----------------")
        print("HW breakpoint count: %s" % test_result["breakpoint_count"])
        print("Watchpoint count: %s" % test_result["watchpoint_count"])
        print("Average instruction step time: %s" %
              test_result["step_time_si"])
        print("Average single step time: %s" % test_result["step_time_s"])
        print("Average over step time: %s" % test_result["step_time_n"])
        print("Failure count: %i" % test_result["fail_count"])
        result.passed = test_result["fail_count"] == 0
    else:
        result.passed = False

    # Cleanup
    if temp_test_elf_name and os.path.exists(temp_test_elf_name):
        os.remove(temp_test_elf_name)
    os.remove(test_result_filename)
    os.remove(test_param_filename)

    return result
Example #38
0
    def validate_boards(data):
        did_pass = True

        print('boards', end=' ')
        p = 'boards' in data and type(data['boards']) is list
        if p:
            b = data['boards']
        if p:
            print("PASSED")
        else:
            did_pass = False
            print("FAILED")

        # Only if we're running this test standalone do we want to compare against the list
        # of boards returned by ConnectHelper.get_sessions_for_all_connected_probes(). When running in the full
        # automated test suite, there could be other test jobs running concurrently that have
        # exclusive access to the boards they are testing. Thus, those boards will not show up
        # in the return list and this test will fail.
        if testing_standalone:
            try:
                all_sessions = ConnectHelper.get_sessions_for_all_connected_probes(blocking=False)
                all_mbeds = [x.board for x in all_sessions]
                p = len(all_mbeds) == len(b)
                matching_boards = 0
                if p:
                    for mbed in all_mbeds:
                        for brd in b:
                            if mbed.unique_id == brd['unique_id']:
                                matching_boards += 1
                                p = 'info' in brd and 'target' in brd and 'board_name' in brd
                                if not p:
                                    break
                        if not p:
                            break
                    p = matching_boards == len(all_mbeds)
                if p:
                    print("PASSED")
                else:
                    did_pass = False
                    print("FAILED")
            except Exception as e:
                print("FAILED")
                traceback.print_exc(file=sys.stdout)
                did_pass = False
        else:
            # Check for required keys in all board info dicts.
            p = True
            for brd in b:
                p = ('unique_id' in brd and
                    'info' in brd and
                    'target' in brd and
                    'board_name' in brd)
                if not p:
                    break
            if p:
                print("PASSED")
            else:
                did_pass = False
                print("FAILED")

        return did_pass
Example #39
0
def main():
    parser = argparse.ArgumentParser(description='pyOCD automated testing')
    parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging')
    parser.add_argument('-q', '--quiet', action="store_true", help='Hide test progress for 1 job')
    parser.add_argument('-j', '--jobs', action="store", default=1, type=int, metavar="JOBS",
        help='Set number of concurrent board tests (default is 1)')
    parser.add_argument('-b', '--board', action="append", metavar="ID", help="Limit testing to boards with specified unique IDs. Multiple boards can be listed.")
    args = parser.parse_args()
    
    # Allow CI to override the number of concurrent jobs.
    if 'CI_JOBS' in os.environ:
        args.jobs = int(os.environ['CI_JOBS'])
    
    # Disable multiple jobs on macOS prior to Python 3.4. By default, multiprocessing uses
    # fork() on Unix, which doesn't work on the Mac because CoreFoundation requires exec()
    # to be used in order to init correctly (CoreFoundation is used in hidapi). Only on Python
    # version 3.4+ is the multiprocessing.set_start_method() API available that lets us
    # switch to the 'spawn' method, i.e. exec().
    if args.jobs > 1 and sys.platform.startswith('darwin') and sys.version_info[0:2] < (3, 4):
        print("WARNING: Cannot support multiple jobs on macOS prior to Python 3.4. Forcing 1 job.")
        args.jobs = 1

    # Setup logging based on concurrency and quiet option.
    level = logging.DEBUG if args.debug else logging.INFO
    if args.jobs == 1 and not args.quiet:
        log_file = LOG_FILE_TEMPLATE.format(get_env_file_name())
        # Create common log file.
        if os.path.exists(log_file):
            os.remove(log_file)
        logToConsole = True
        commonLogFile = open(log_file, "a")
    else:
        logToConsole = False
        commonLogFile = None

    board_list = []
    result_list = []

    # Put together list of boards to test
    board_list = ConnectHelper.get_all_connected_probes(blocking=False)
    board_id_list = sorted(b.unique_id for b in board_list)
    
    # Filter boards.
    if args.board:
        board_id_list = [b for b in board_id_list if any(c for c in args.board if c.lower() in b.lower())]

    # If only 1 job was requested, don't bother spawning processes.
    start = time()
    if args.jobs == 1:
        for n, board_id in enumerate(board_id_list):
            result_list += test_board(board_id, n, level, logToConsole, commonLogFile)
    else:
        # Create a pool of processes to run tests.
        try:
            pool = mp.Pool(args.jobs)
            
            # Issue board test job to process pool.
            async_results = [pool.apply_async(test_board, (board_id, n, level, logToConsole, commonLogFile))
                             for n, board_id in enumerate(board_id_list)]
            
            # Gather results.
            for r in async_results:
                result_list += r.get(timeout=JOB_TIMEOUT)
        finally:
            pool.close()
            pool.join()
    stop = time()
    test_time = (stop - start)

    print_summary(test_list, result_list, test_time)
    summary_file = SUMMARY_FILE_TEMPLATE.format(get_env_file_name())
    with open(summary_file, "w") as output_file:
        print_summary(test_list, result_list, test_time, output_file)
    generate_xml_results(result_list)
    
    exit_val = 0 if Test.all_tests_pass(result_list) else -1
    exit(exit_val)
Example #40
0
 def read_target_memory(self, addr, size, resume=True):
     assert self.get_mode() == self.MODE_IF
     with ConnectHelper.session_with_chosen_probe(unique_id=self.get_unique_id(),
                                                  resume_on_disconnect=resume) as session:
         data = session.target.read_memory_block8(addr, size)
     return bytearray(data)
Example #41
0
    print("\n{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format(
        "#", "Prev Exit", "Halt on Connect", "Expected", "Disconnect Resume", "Exit", "Passed"))
    for i, case in enumerate(test_cases):
        print("{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format(
            i,
            STATE_NAMES[case.prev_exit_state],
            repr(case.halt_on_connect),
            STATE_NAMES[case.expected_state],
            repr(case.disconnect_resume),
            STATE_NAMES[case.exit_state],
            "PASS" if case.passed else "FAIL"))
    print("\nPass count %i of %i tests" % (test_pass_count, test_count))
    if test_pass_count == test_count:
        print("CONNECT TEST SCRIPT PASSED")
    else:
        print("CONNECT TEST SCRIPT FAILED")

    result.passed = (test_count == test_pass_count)
    return result

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='pyOCD connect test')
    parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging')
    args = parser.parse_args()
    level = logging.DEBUG if args.debug else logging.INFO
    logging.basicConfig(level=level)
    session = ConnectHelper.session_with_chosen_probe(open_session=False, **get_session_options())
    test = ConnectTest()
    result = [test.run(session.board)]
    test.print_perf_info(result)
Example #42
0
def speed_test(board_id):
    with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session:
        board = session.board
        target_type = board.target_type

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()

        # Limit region sizes used for performance testing to 1 MB. We don't really need to
        # be reading all 32 MB of a QSPI!
        ram_start = ram_region.start
        ram_size = min(ram_region.length, _1MB)
        rom_start = rom_region.start
        rom_size = min(rom_region.length, _1MB)

        target = board.target

        test_pass_count = 0
        test_count = 0
        result = SpeedTestResult()

        test_params = get_target_test_params(session)
        session.probe.set_clock(test_params['test_clock'])
        
        test_config = "uncached 8-bit"

        def test_ram(record_speed=False, width=8):
            print("\n\n------ TEST RAM READ / WRITE SPEED [%s] ------" % test_config)
            test_addr = ram_start
            test_size = ram_size
            data = [randrange(1, 50) for x in range(test_size)]
            start = time()
            if width == 8:
                target.write_memory_block8(test_addr, data)
            elif width == 32:
                target.write_memory_block32(test_addr, conversion.byte_list_to_u32le_list(data))
            target.flush()
            stop = time()
            diff = stop - start
            if diff == 0:
                print("Unexpected ram write elapsed time of 0!")
                write_speed = 0
            else:
                write_speed = test_size / diff
            if record_speed:
                result.write_speed = write_speed
            print("Writing %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, write_speed))
            start = time()
            if width == 8:
                block = target.read_memory_block8(test_addr, test_size)
            elif width == 32:
                block = conversion.u32le_list_to_byte_list(target.read_memory_block32(test_addr, test_size // 4))
            target.flush()
            stop = time()
            diff = stop - start
            if diff == 0:
                print("Unexpected ram read elapsed time of 0!")
                read_speed = 0
            else:
                read_speed = test_size / diff
            if record_speed:
                result.read_speed = read_speed
            print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, read_speed))
            error = False
            if len(block) != len(data):
                error = True
                print("ERROR: read length (%d) != write length (%d)!" % (len(block), len(data)))
            if not error:
                for i in range(len(block)):
                    if (block[i] != data[i]):
                        error = True
                        print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i]))
            if error:
                print("TEST FAILED")
            else:
                print("TEST PASSED")
            return not error

        def test_rom(record_speed=False, width=8):
            print("\n\n------ TEST ROM READ SPEED [%s] ------" % test_config)
            test_addr = rom_start
            test_size = rom_size
            start = time()
            if width == 8:
                block = target.read_memory_block8(test_addr, test_size)
            elif width == 32:
                block = conversion.u32le_list_to_byte_list(target.read_memory_block32(test_addr, test_size // 4))
            target.flush()
            stop = time()
            diff = stop - start
            if diff == 0:
                print("Unexpected rom read elapsed time of 0!")
                read_speed = 0
            else:
                read_speed = test_size / diff
            if record_speed:
                result.rom_read_speed = read_speed
            print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, read_speed))
            print("TEST PASSED")
            return True
        
        # 8-bit without memcache
        passed = test_ram(True, 8)
        test_count += 1
        test_pass_count += int(passed)
        
        passed = test_rom(True, 8)
        test_count += 1
        test_pass_count += int(passed)
        
        # 32-bit without memcache
        test_config = "uncached 32-bit"
        passed = test_ram(False, 32)
        test_count += 1
        test_pass_count += int(passed)
        
        passed = test_rom(False, 32)
        test_count += 1
        test_pass_count += int(passed)
        
        # With memcache
        target = target.get_target_context()
        test_config = "cached 8-bit, pass 1"
        
        passed = test_ram()
        test_count += 1
        test_pass_count += int(passed)
        
        passed = test_rom()
        test_count += 1
        test_pass_count += int(passed)
        
        # Again with memcache
        test_config = "cached 8-bit, pass 2"
        passed = test_ram()
        test_count += 1
        test_pass_count += int(passed)
        
        passed = test_rom()
        test_count += 1
        test_pass_count += int(passed)

        board.target.reset()

        result.passed = test_count == test_pass_count
        return result
Example #43
0
def speed_test(board_id):
    with ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) as session:
        board = session.board
        target_type = board.target_type

        test_clock = 10000000
        if target_type == "nrf51":
            # Override clock since 10MHz is too fast
            test_clock = 1000000
        if target_type == "ncs36510":
            # Override clock since 10MHz is too fast
            test_clock = 1000000

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()

        ram_start = ram_region.start
        ram_size = ram_region.length
        rom_start = rom_region.start
        rom_size = rom_region.length

        target = board.target

        test_pass_count = 0
        test_count = 0
        result = SpeedTestResult()

        session.probe.set_clock(test_clock)

        print("\n\n------ TEST RAM READ / WRITE SPEED ------")
        test_addr = ram_start
        test_size = ram_size
        data = [randrange(1, 50) for x in range(test_size)]
        start = time()
        target.write_memory_block8(test_addr, data)
        target.flush()
        stop = time()
        diff = stop - start
        result.write_speed = test_size / diff
        print("Writing %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, result.write_speed))
        start = time()
        block = target.read_memory_block8(test_addr, test_size)
        target.flush()
        stop = time()
        diff = stop - start
        result.read_speed = test_size / diff
        print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, result.read_speed))
        error = False
        for i in range(len(block)):
            if (block[i] != data[i]):
                error = True
                print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i]))
        if error:
            print("TEST FAILED")
        else:
            print("TEST PASSED")
            test_pass_count += 1
        test_count += 1

        print("\n\n------ TEST ROM READ SPEED ------")
        test_addr = rom_start
        test_size = rom_size
        start = time()
        block = target.read_memory_block8(test_addr, test_size)
        target.flush()
        stop = time()
        diff = stop - start
        print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, test_size / diff))
        print("TEST PASSED")
        test_pass_count += 1
        test_count += 1

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Example #44
0
def connect_test(board):
    board_id = board.unique_id
    binary_file = os.path.join(parentdir, 'binaries', board.test_binary)
    print("binary file: %s" % binary_file)

    test_pass_count = 0
    test_count = 0
    result = ConnectTestResult()

    # Install binary.
    live_session = ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options())
    live_board = live_session.board
    memory_map = board.target.get_memory_map()
    rom_region = memory_map.get_boot_memory()
    rom_start = rom_region.start

    def test_connect(halt_on_connect, expected_state, resume):
        print("Connecting with halt_on_connect=%s" % halt_on_connect)
        live_session = ConnectHelper.session_with_chosen_probe(
                        board_id=board_id,
                        init_board=False,
                        halt_on_connect=halt_on_connect,
                        resume_on_disconnect=resume,
                        **get_session_options())
        live_session.open()
        live_board = live_session.board
        print("Verifying target is", STATE_NAMES.get(expected_state, "unknown"))
        actualState = live_board.target.get_state()
        # Accept sleeping for running, as a hack to work around nRF52840-DK test binary.
        # TODO remove sleeping hack.
        if (actualState == expected_state) \
                or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING):
            passed = 1
            print("TEST PASSED")
        else:
            passed = 0
            print("TEST FAILED (state={}, expected={})".format(
                STATE_NAMES.get(actualState, "unknown"),
                STATE_NAMES.get(expected_state, "unknown")))
        print("Disconnecting with resume=%s" % resume)
        live_session.close()
        live_session = None
        return passed

    # TEST CASE COMBINATIONS
    test_cases = [
    #                <prev_exit> <halt_on_connect> <expected_state> <disconnect_resume> <exit_state>
    ConnectTestCase( RUNNING,    False,            RUNNING,         False,              RUNNING  ),
    ConnectTestCase( RUNNING,    True,             HALTED,          False,              HALTED   ),
    ConnectTestCase( HALTED,     True,             HALTED,          True,               RUNNING  ),
    ConnectTestCase( RUNNING,    True,             HALTED,          True,               RUNNING  ),
    ConnectTestCase( RUNNING,    False,            RUNNING,         True,               RUNNING  ),
    ConnectTestCase( RUNNING,    True,             HALTED,          False,              HALTED   ),
    ConnectTestCase( HALTED,     False,            HALTED,          False,              HALTED   ),
    ConnectTestCase( HALTED,     True,             HALTED,          False,              HALTED   ),
    ConnectTestCase( HALTED,     False,            HALTED,          True,               RUNNING  ),
    ConnectTestCase( RUNNING,    False,            RUNNING,         False,              RUNNING  ),
    ]

    print("\n\n----- TESTING CONNECT/DISCONNECT -----")
    print("Flashing new binary")
    FileProgrammer(live_session).program(binary_file, base_address=rom_start)
    live_board.target.reset()
    test_count += 1
    print("Verifying target is running")
    if live_board.target.is_running():
        test_pass_count += 1
        print("TEST PASSED")
    else:
        print("TEST FAILED")
    print("Disconnecting with resume=True")
    live_session.options['resume_on_disconnect'] = True
    live_session.close()
    live_session = None
    # Leave running.

    # Run all the cases.
    for case in test_cases:
        test_count += 1
        did_pass = test_connect(
            halt_on_connect=case.halt_on_connect,
            expected_state=case.expected_state,
            resume=case.disconnect_resume
            )
        test_pass_count += did_pass
        case.passed=did_pass

    print("\n\nTest Summary:")
    print("\n{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format(
        "#", "Prev Exit", "Halt on Connect", "Expected", "Disconnect Resume", "Exit", "Passed"))
    for i, case in enumerate(test_cases):
        print("{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format(
            i,
            STATE_NAMES[case.prev_exit_state],
            repr(case.halt_on_connect),
            STATE_NAMES[case.expected_state],
            repr(case.disconnect_resume),
            STATE_NAMES[case.exit_state],
            "PASS" if case.passed else "FAIL"))
    print("\nPass count %i of %i tests" % (test_pass_count, test_count))
    if test_pass_count == test_count:
        print("CONNECT TEST SCRIPT PASSED")
    else:
        print("CONNECT TEST SCRIPT FAILED")

    result.passed = (test_count == test_pass_count)
    return result
Example #45
0
def debug_context_test(board_id):
    with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session:
        board = session.board
        target = session.target

        test_params = get_target_test_params(session)
        session.probe.set_clock(test_params['test_clock'])

        memory_map = target.get_memory_map()
        boot_region = memory_map.get_boot_memory()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        binary_file = os.path.join(parentdir, 'binaries', board.test_binary)
        gdb_test_binary_file = os.path.join(parentdir, GDB_TEST_BIN)
        gdb_test_elf_file = os.path.join(parentdir, GDB_TEST_ELF)

        # Read the gdb test binary file.
        with open(gdb_test_binary_file, "rb") as f:
            gdb_test_binary_data = list(bytearray(f.read()))
        gdb_test_binary_data_length = len(gdb_test_binary_data)
        
        # Set the elf on the target, which will add a context to read from the elf.
        target.elf = gdb_test_elf_file

        test_pass_count = 0
        test_count = 0
        result = DebugContextTestResult()
        
        ctx = target.get_target_context()
        
        target.reset_and_halt()
        
        # Reproduce a gdbserver failure.
        print("\n------ Test 1: Mem cache ------")
        print("Writing gdb test binary")
        ctx.write_memory_block8(0x20000000, gdb_test_binary_data)
        
        print("Reading first chunk")
        data = ctx.read_memory_block8(0x20000000, 64)
        if data == gdb_test_binary_data[:64]:
            test_pass_count += 1
        test_count += 1
            
        print("Reading N chunks")
        for n in range(8):
            offset = 0x7e + (4 * n)
            data = ctx.read_memory_block8(0x20000000 + offset, 4)
            if data == gdb_test_binary_data[offset:offset + 4]:
                test_pass_count += 1
            test_count += 1

        print("\nTest Summary:")
        print("Pass count %i of %i tests" % (test_pass_count, test_count))
        if test_pass_count == test_count:
            print("DEBUG CONTEXT TEST PASSED")
        else:
            print("DEBUG CONTEXT TEST FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Example #46
0
def cortex_test(board_id):
    with ConnectHelper.session_with_chosen_probe(
            board_id=board_id, **get_session_options()) as session:
        board = session.board
        target_type = board.target_type

        binary_file = os.path.join(parentdir, 'binaries', board.test_binary)

        test_params = get_target_test_params(session)
        test_clock = test_params['test_clock']
        addr_invalid = 0x3E000000  # Last 16MB of ARM SRAM region - typically empty
        expect_invalid_access_to_fail = test_params['error_on_invalid_access']

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()

        addr = ram_region.start
        size = 0x502
        addr_bin = rom_region.start

        target = board.target
        probe = session.probe

        probe.set_clock(test_clock)

        test_pass_count = 0
        test_count = 0
        result = CortexTestResult()

        debugContext = target.get_target_context()
        gdbFacade = GDBDebugContextFacade(debugContext)

        print("\n\n----- FLASH NEW BINARY BEFORE TEST -----")
        FileProgrammer(session).program(binary_file, base_address=addr_bin)
        # Let the target run for a bit so it
        # can initialize the watchdog if it needs to
        target.resume()
        sleep(0.2)
        target.halt()

        print("PROGRAMMING COMPLETE")

        print("\n\n----- TESTING CORTEX-M PERFORMANCE -----")
        test_time = test_function(session, gdbFacade.get_t_response)
        result.times["get_t_response"] = test_time
        print("Function get_t_response time: %f" % test_time)

        # Step
        test_time = test_function(session, target.step)
        result.times["step"] = test_time
        print("Function step time: %f" % test_time)

        # Breakpoint
        def set_remove_breakpoint():
            target.set_breakpoint(0)
            target.remove_breakpoint(0)

        test_time = test_function(session, set_remove_breakpoint)
        result.times["bp_add_remove"] = test_time
        print("Add and remove breakpoint: %f" % test_time)

        # get_register_context
        test_time = test_function(session, gdbFacade.get_register_context)
        result.times["get_reg_context"] = test_time
        print("Function get_register_context: %f" % test_time)

        # set_register_context
        context = gdbFacade.get_register_context()

        def set_register_context():
            gdbFacade.set_register_context(context)

        test_time = test_function(session, set_register_context)
        result.times["set_reg_context"] = test_time
        print("Function set_register_context: %f" % test_time)

        # Run / Halt
        def run_halt():
            target.resume()
            target.halt()

        test_time = test_function(session, run_halt)
        result.times["run_halt"] = test_time
        print("Resume and halt: %f" % test_time)

        # GDB stepping
        def simulate_step():
            target.step()
            gdbFacade.get_t_response()
            target.set_breakpoint(0)
            target.resume()
            target.halt()
            gdbFacade.get_t_response()
            target.remove_breakpoint(0)

        test_time = test_function(session, simulate_step)
        result.times["gdb_step"] = test_time
        print("Simulated GDB step: %f" % test_time)

        # Test passes if there are no exceptions
        test_pass_count += 1
        test_count += 1
        print("TEST PASSED")

        print("\n\n------ Testing Reset Types ------")

        def reset_methods(fnc):
            print("Hardware reset")
            fnc(reset_type=Target.ResetType.HW)
            print("Hardware reset (default=HW)")
            target.selected_core.default_reset_type = Target.ResetType.HW
            fnc(reset_type=None)
            print("Software reset (default=SYSRESETREQ)")
            target.selected_core.default_reset_type = Target.ResetType.SW_SYSRESETREQ
            fnc(reset_type=None)
            print("Software reset (default=VECTRESET)")
            target.selected_core.default_reset_type = Target.ResetType.SW_VECTRESET
            fnc(reset_type=None)
            print("Software reset (default=emulated)")
            target.selected_core.default_reset_type = Target.ResetType.SW_EMULATED
            fnc(reset_type=None)

            print("(Default) Software reset (SYSRESETREQ)")
            target.selected_core.default_software_reset_type = Target.ResetType.SW_SYSRESETREQ
            fnc(reset_type=Target.ResetType.SW)
            print("(Default) Software reset (VECTRESET)")
            target.selected_core.default_software_reset_type = Target.ResetType.SW_VECTRESET
            fnc(reset_type=Target.ResetType.SW)
            print("(Default) Software reset (emulated)")
            target.selected_core.default_software_reset_type = Target.ResetType.SW_EMULATED
            fnc(reset_type=Target.ResetType.SW)

            print("Software reset (option=default)")
            target.selected_core.default_reset_type = Target.ResetType.SW
            target.selected_core.default_software_reset_type = Target.ResetType.SW_SYSRESETREQ
            session.options['reset_type'] = 'default'
            fnc(reset_type=None)
            print("Software reset (option=hw)")
            session.options['reset_type'] = 'hw'
            fnc(reset_type=None)
            print("Software reset (option=sw)")
            session.options['reset_type'] = 'sw'
            fnc(reset_type=None)
            print("Software reset (option=sw_sysresetreq)")
            session.options['reset_type'] = 'sw_sysresetreq'
            fnc(reset_type=None)
            print("Software reset (option=sw_vectreset)")
            session.options['reset_type'] = 'sw_vectreset'
            fnc(reset_type=None)
            print("Software reset (option=sw_emulated)")
            session.options['reset_type'] = 'sw_emulated'
            fnc(reset_type=None)

        reset_methods(target.reset)

        # Test passes if there are no exceptions
        test_pass_count += 1
        test_count += 1
        print("TEST PASSED")

        print("\n\n------ Testing Reset Halt ------")
        reset_methods(target.reset_and_halt)

        # Test passes if there are no exceptions
        test_pass_count += 1
        test_count += 1
        print("TEST PASSED")

        print("\n\n------ Testing Register Read/Write ------")
        print("Reading r0")
        val = target.read_core_register('r0')
        origR0 = val
        rawVal = target.read_core_register_raw('r0')
        test_count += 1
        if val == rawVal:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("Writing r0")
        target.write_core_register('r0', 0x12345678)
        val = target.read_core_register('r0')
        rawVal = target.read_core_register_raw('r0')
        test_count += 1
        if val == 0x12345678 and rawVal == 0x12345678:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("Raw writing r0")
        target.write_core_register_raw('r0', 0x87654321)
        val = target.read_core_register('r0')
        rawVal = target.read_core_register_raw('r0')
        test_count += 1
        if val == 0x87654321 and rawVal == 0x87654321:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("Read/write r0, r1, r2, r3")
        origRegs = target.read_core_registers_raw(['r0', 'r1', 'r2', 'r3'])
        target.write_core_registers_raw(['r0', 'r1', 'r2', 'r3'], [1, 2, 3, 4])
        vals = target.read_core_registers_raw(['r0', 'r1', 'r2', 'r3'])
        passed = vals[0] == 1 and vals[1] == 2 and vals[2] == 3 and vals[3] == 4
        test_count += 1
        if passed:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        # Restore regs
        origRegs[0] = origR0
        target.write_core_registers_raw(['r0', 'r1', 'r2', 'r3'], origRegs)

        if target.selected_core.has_fpu:
            print("Reading s0")
            val = target.read_core_register('s0')
            rawVal = target.read_core_register_raw('s0')
            origRawS0 = rawVal
            passed = isinstance(val, float) and isinstance(rawVal, int) \
                        and float32_to_u32(val) == rawVal
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED")

            print("Writing s0")
            target.write_core_register('s0', math.pi)
            val = target.read_core_register('s0')
            rawVal = target.read_core_register_raw('s0')
            passed = float_compare(val, math.pi) and float_compare(
                u32_to_float32(rawVal), math.pi)
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED (%f==%f, 0x%08x->%f)" %
                      (val, math.pi, rawVal, u32_to_float32(rawVal)))

            print("Raw writing s0")
            x = float32_to_u32(32.768)
            target.write_core_register_raw('s0', x)
            val = target.read_core_register('s0')
            passed = float_compare(val, 32.768)
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED (%f==%f)" % (val, 32.768))

            print("Read/write s0, s1")
            _1p1 = float32_to_u32(1.1)
            _2p2 = float32_to_u32(2.2)
            origRegs = target.read_core_registers_raw(['s0', 's1'])
            target.write_core_registers_raw(['s0', 's1'], [_1p1, _2p2])
            vals = target.read_core_registers_raw(['s0', 's1'])
            s0 = target.read_core_register('s0')
            s1 = target.read_core_register('s1')
            passed = vals[0] == _1p1 and float_compare(s0, 1.1) \
                        and vals[1] == _2p2 and float_compare(s1, 2.2)
            test_count += 1
            if passed:
                test_pass_count += 1
                print("TEST PASSED")
            else:
                print("TEST FAILED (0x%08x==0x%08x, %f==%f, 0x%08x==0x%08x, %f==%f)" \
                    % (vals[0], _1p1, s0, 1.1, vals[1], _2p2, s1, 2.2))

            # Restore s0
            origRegs[0] = origRawS0
            target.write_core_registers_raw(['s0', 's1'], origRegs)

        print("\n\n------ Testing Invalid Memory Access Recovery ------")
        memory_access_pass = True
        try:
            print("reading 0x1000 bytes at invalid address 0x%08x" %
                  addr_invalid)
            target.read_memory_block8(addr_invalid, 0x1000)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        try:
            print("reading 0x1000 bytes at invalid address 0x%08x" %
                  (addr_invalid + 1))
            target.read_memory_block8(addr_invalid + 1, 0x1000)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        data = [0x00] * 0x1000
        try:
            print("writing 0x%08x bytes at invalid address 0x%08x" %
                  (len(data), addr_invalid))
            target.write_memory_block8(addr_invalid, data)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault!")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        data = [0x00] * 0x1000
        try:
            print("writing 0x%08x bytes at invalid address 0x%08x" %
                  (len(data), addr_invalid + 1))
            target.write_memory_block8(addr_invalid + 1, data)
            target.flush()
            # If no exception is thrown the tests fails except on nrf51 where invalid addresses read as 0
            if expect_invalid_access_to_fail:
                print("  failed to get expected fault!")
                memory_access_pass = False
            else:
                print("  no fault as expected")
        except exceptions.TransferFaultError as exc:
            print("  got expected error: " + str(exc))

        data = [randrange(0, 255) for x in range(size)]
        print("r/w 0x%08x bytes at 0x%08x" % (size, addr))
        target.write_memory_block8(addr, data)
        block = target.read_memory_block8(addr, size)
        if same(data, block):
            print("  Aligned access pass")
        else:
            print("  Memory read does not match memory written")
            memory_access_pass = False

        data = [randrange(0, 255) for x in range(size)]
        print("r/w 0x%08x bytes at 0x%08x" % (size, addr + 1))
        target.write_memory_block8(addr + 1, data)
        block = target.read_memory_block8(addr + 1, size)
        if same(data, block):
            print("  Unaligned access pass")
        else:
            print("  Unaligned memory read does not match memory written")
            memory_access_pass = False

        test_count += 1
        if memory_access_pass:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("\n\n------ Testing Software Breakpoints ------")
        test_passed = True
        orig8x2 = target.read_memory_block8(addr, 2)
        orig8 = target.read8(addr)
        orig16 = target.read16(addr & ~1)
        orig32 = target.read32(addr & ~3)
        origAligned32 = target.read_memory_block32(addr & ~3, 1)

        def test_filters():
            test_passed = True
            filtered = target.read_memory_block8(addr, 2)
            if same(orig8x2, filtered):
                print("2 byte unaligned passed")
            else:
                print("2 byte unaligned failed (read %x-%x, expected %x-%x)" %
                      (filtered[0], filtered[1], orig8x2[0], orig8x2[1]))
                test_passed = False

            for now in (True, False):
                filtered = target.read8(addr, now)
                if not now:
                    filtered = filtered()
                if filtered == orig8:
                    print("8-bit passed [now=%s]" % now)
                else:
                    print("8-bit failed [now=%s] (read %x, expected %x)" %
                          (now, filtered, orig8))
                    test_passed = False

                filtered = target.read16(addr & ~1, now)
                if not now:
                    filtered = filtered()
                if filtered == orig16:
                    print("16-bit passed [now=%s]" % now)
                else:
                    print("16-bit failed [now=%s] (read %x, expected %x)" %
                          (now, filtered, orig16))
                    test_passed = False

                filtered = target.read32(addr & ~3, now)
                if not now:
                    filtered = filtered()
                if filtered == orig32:
                    print("32-bit passed [now=%s]" % now)
                else:
                    print("32-bit failed [now=%s] (read %x, expected %x)" %
                          (now, filtered, orig32))
                    test_passed = False

            filtered = target.read_memory_block32(addr & ~3, 1)
            if same(filtered, origAligned32):
                print("32-bit aligned passed")
            else:
                print("32-bit aligned failed (read %x, expected %x)" %
                      (filtered[0], origAligned32[0]))
                test_passed = False
            return test_passed

        print("Installed software breakpoint at 0x%08x" % addr)
        target.set_breakpoint(addr, Target.BREAKPOINT_SW)
        test_passed = test_filters() and test_passed

        print("Removed software breakpoint")
        target.remove_breakpoint(addr)
        test_passed = test_filters() and test_passed

        test_count += 1
        if test_passed:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Example #47
0
from random import randrange
import math
import logging

parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)

from pyocd.core.helpers import ConnectHelper
from pyocd.flash.loader import FileProgrammer
from test_util import get_session_options

logging.basicConfig(level=logging.INFO)

print("\n\n------ Test attaching to locked board ------")
for i in range(0, 10):
    with ConnectHelper.session_with_chosen_probe(**get_session_options()) as session:
        board = session.board
        # Erase and then reset - This locks Kinetis devices
        board.flash.init(board.flash.Operation.ERASE)
        board.flash.erase_all()
        board.flash.cleanup()
        board.target.reset()

print("\n\n------ Testing Attaching to board ------")
for i in range(0, 100):
    with ConnectHelper.session_with_chosen_probe(**get_session_options()) as session:
        board = session.board
        board.target.halt()
        sleep(0.01)
        board.target.resume()
        sleep(0.01)
Example #48
0
def commands_test(board_id):
    with ConnectHelper.session_with_chosen_probe(
            unique_id=board_id, **get_session_options()) as session:
        board = session.board
        target = session.target
        target_type = board.target_type

        test_params = get_target_test_params(session)
        session.probe.set_clock(test_params['test_clock'])

        memory_map = board.target.get_memory_map()
        boot_region = memory_map.get_boot_memory()
        ram_region = memory_map.get_default_region_of_type(MemoryType.RAM)
        ram_base = ram_region.start
        boot_start_addr = boot_region.start
        boot_end_addr = boot_region.end
        boot_blocksize = boot_region.blocksize
        binary_file = get_test_binary_path(board.test_binary)

        # Generate an Intel hex file from the binary test file.
        temp_test_hex_name = binary_to_hex_file(binary_file, boot_region.start)

        temp_bin_file = tempfile.mktemp('.bin')

        with open(binary_file, "rb") as f:
            test_data = list(bytearray(f.read()))
        test_data_length = len(test_data)
        test_file_sectors = round_up_div(test_data_length, boot_blocksize)
        boot_first_free_block_addr = boot_start_addr + test_file_sectors * boot_blocksize
        reset_handler_addr = conversion.byte_list_to_u32le_list(
            test_data[4:8])[0]

        test_pass_count = 0
        test_count = 0
        failed_commands = []
        result = CommandsTestResult()

        context = CommandExecutionContext()
        context.attach_session(session)

        COMMANDS_TO_TEST = [
            "status",
            "reset",
            "reset halt",
            "reg",
            "reg general",
            "reg all",
            "reg r0",
            "wreg r0 0x12345678",
            "d pc",
            "d --center pc 32",
            "read64 0x%08x" % ((boot_start_addr + boot_blocksize) & ~7),
            "read32 0x%08x" % ((boot_start_addr + boot_blocksize) & ~3),
            "read16 0x%08x" % ((boot_start_addr + boot_blocksize) & ~1),
            "read8 0x%08x" % (boot_start_addr + boot_blocksize),
            "rd 0x%08x 16" % ram_base,
            "rw 0x%08x 16" % ram_base,
            "rh 0x%08x 16" % ram_base,
            "rb 0x%08x 16" % ram_base,
            "write64 0x%08x 0x1122334455667788 0xaabbccddeeff0011" % ram_base,
            "write32 0x%08x 0x11223344 0x55667788" % ram_base,
            "write16 0x%08x 0xabcd" % (ram_base + 8),
            "write8 0x%08x 0 1 2 3 4 5 6" % (ram_base + 10),
            "savemem 0x%08x 128 '%s'" %
            (boot_start_addr, fix_windows_path(temp_bin_file)),
            "loadmem 0x%08x '%s'" %
            (ram_base, fix_windows_path(temp_bin_file)),
            "loadmem 0x%08x '%s'" %
            (boot_start_addr, fix_windows_path(binary_file)),
            "load '%s'" % fix_windows_path(temp_test_hex_name),
            "load '%s' 0x%08x" %
            (fix_windows_path(binary_file), boot_start_addr),
            "compare 0x%08x '%s'" %
            (ram_base, fix_windows_path(temp_bin_file)),
            "compare 0x%08x 32 '%s'" %
            (ram_base, fix_windows_path(temp_bin_file)),
            "fill 0x%08x 128 0xa5" % ram_base,
            "fill 16 0x%08x 64 0x55aa" % (ram_base + 64),
            "find 0x%08x 128 0xaa 0x55" % ram_base,  # find that will pass
            "find 0x%08x 128 0xff" % ram_base,  # find that will fail
            "erase 0x%08x" % (boot_first_free_block_addr),
            "erase 0x%08x 1" % (boot_first_free_block_addr + boot_blocksize),
            "go",
            "halt",
            "step",
            "s 4",
            "continue",
            "h",
            "break 0x%08x" % reset_handler_addr,
            "lsbreak",
            "rmbreak 0x%08x" % reset_handler_addr,
            "watch 0x%08x" % ram_base,
            "lswatch",
            "rmwatch 0x%08x" % ram_base,
            "watch 0x%08x rw 2" % ram_base,
            "rmwatch 0x%08x" % ram_base,
            "core",
            "core 0",
            "readdp 0",  # read DPIDR
            "writedp 0 0x1e",  # write ABORT to clear error flags
            "readap 0xfc",  # read IDR
            "readap 0 0xfc",  # read IDR of AP#0
            "writeap 0x4 0",  # set TAR to 0
            "writeap 0 0x4 0",  # set TAR to 0 on AP#0
            "gdbserver start",
            "gdbserver status",
            "gdbserver stop",
            "probeserver start",
            "probeserver status",
            "probeserver stop",
            "show probe-uid",
            "show target",
            "show cores",
            "show map",
            "show peripherals",
            "show fault",
            "show nreset",
            "set nreset 1",
            "show option reset_type",
            "set option reset_type=sw",
            "show mem-ap",
            "set mem-ap 0",
            "show hnonsec",
            "set hnonsec 0",
            "show hprot",
            "set hprot 0x3",  # set default hprot: data, priv
            "show graph",
            "show locked",
            "show register-groups",
            "show vector-catch",
            "set vector-catch all",
            "show step-into-interrupts",
            "set step-into-interrupts 1",
            "set log info",
            "set frequency %d" % test_params['test_clock'],

            # Semicolon-separated commands.
            'rw 0x%08x ; rw 0x%08x' % (ram_base, ram_base + 4),
            'rb 0x%08x;rb 0x%08x' % (ram_base, ram_base + 1),
            'rb 0x%08x; rb 0x%08x' % (ram_base, ram_base + 1),

            # Python and system commands.
            '$2+ 2',
            '$ target',
            '!echo hello',
            '!echo hi ; echo there',  # semicolon in a sytem command (because semicolon separation is not supported for Python/system command lines)
            ' $ " ".join(["hello", "there"])',
            '  !   echo "yo dude" ',

            # Commands not tested:
            #                 "list",
            #                 "erase", # chip erase
            #                 "unlock",
            #                 "exit",
            #                 "initdp",
            #                 "makeap",
            #                 "reinit",
            #                 "where",
            #                 "symbol",
        ]

        # For now we just verify that the commands run without raising an exception.
        print("\n------ Testing commands ------")

        def test_command(cmd):
            try:
                print("\nTEST: %s" % cmd)
                context.process_command_line(cmd)
            except:
                print("TEST FAILED")
                failed_commands.append(cmd)
                traceback.print_exc(file=sys.stdout)
                return False
            else:
                print("TEST PASSED")
                return True

        for cmd in COMMANDS_TO_TEST:
            if test_command(cmd):
                test_pass_count += 1
            test_count += 1

        print("\n\nTest Summary:")
        print("Pass count %i of %i tests" % (test_pass_count, test_count))
        if failed_commands:
            for c in failed_commands:
                print(" - '" + c + "'")
        if test_pass_count == test_count:
            print("COMMANDS TEST SCRIPT PASSED")
        else:
            print("COMMANDS TEST SCRIPT FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Example #49
0
def flash_test(board_id):
    with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session:
        board = session.board
        target_type = board.target_type

        memory_map = board.target.get_memory_map()
        ram_region = memory_map.get_first_region_of_type(MemoryType.RAM)

        ram_start = ram_region.start
        ram_size = ram_region.length

        target = board.target

        test_params = get_target_test_params(session)
        session.probe.set_clock(test_params['test_clock'])

        test_pass_count = 0
        test_count = 0
        result = FlashTestResult()
        
        # Test each flash region separately.
        for rom_region in memory_map.get_regions_of_type(MemoryType.FLASH):
            if not rom_region.is_testable:
                continue
            rom_start = rom_region.start
            rom_size = rom_region.length

            flash = rom_region.flash
            flash_info = flash.get_flash_info()
            
            # This can be any value, as long as it's not the erased byte value. We take the
            # inverse of the erased value so that for most flash, the unerased value is 0x00.
            unerasedValue = invert32(flash.region.erased_byte_value) & 0xff

            print("\n\n===== Testing flash region '%s' from 0x%08x to 0x%08x ====" % (rom_region.name, rom_region.start, rom_region.end))

            binary_file = os.path.join(parentdir, 'binaries', board.test_binary)
            with open(binary_file, "rb") as f:
                data = f.read()
            data = struct.unpack("%iB" % len(data), data)
            unused = rom_size - len(data)
            
            # Make sure data doesn't overflow this region.
            if unused < 0:
                data = data[:rom_size]
                unused = 0

            addr = rom_start
            size = len(data)

            # Turn on extra checks for the next 4 tests
            flash.set_flash_algo_debug(True)
            
            print("\n------ Test Erased Value Check ------")
            d = [flash.region.erased_byte_value] * 128
            if flash.region.is_erased(d):
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            d = [unerasedValue] + [flash.region.erased_byte_value] * 127
            if not flash.region.is_erased(d):
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Basic Page Erase ------")
            info = flash.flash_block(addr, data, False, "sector", progress_cb=print_progress())
            data_flashed = target.read_memory_block8(addr, size)
            if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_SECTOR_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Basic Chip Erase ------")
            info = flash.flash_block(addr, data, False, "chip", progress_cb=print_progress())
            data_flashed = target.read_memory_block8(addr, size)
            if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_CHIP_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Smart Page Erase ------")
            info = flash.flash_block(addr, data, True, "sector", progress_cb=print_progress())
            data_flashed = target.read_memory_block8(addr, size)
            if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_SECTOR_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Smart Chip Erase ------")
            info = flash.flash_block(addr, data, True, "chip", progress_cb=print_progress())
            data_flashed = target.read_memory_block8(addr, size)
            if same(data_flashed, data) and info.program_type is FlashBuilder.FLASH_CHIP_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            flash.set_flash_algo_debug(False)

            print("\n------ Test Basic Page Erase (Entire region) ------")
            new_data = list(data)
            new_data.extend(unused * [0x77])
            info = flash.flash_block(addr, new_data, False, "sector", progress_cb=print_progress())
            if info.program_type == FlashBuilder.FLASH_SECTOR_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
                result.page_erase_rate = float(len(new_data)) / float(info.program_time)
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Fast Verify ------")
            info = flash.flash_block(addr, new_data, progress_cb=print_progress(), fast_verify=True)
            if info.program_type == FlashBuilder.FLASH_SECTOR_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Offset Write ------")
            addr = rom_start + rom_size // 2
            page_size = flash.get_page_info(addr).size
            new_data = [0x55] * page_size * 2
            info = flash.flash_block(addr, new_data, progress_cb=print_progress())
            data_flashed = target.read_memory_block8(addr, len(new_data))
            if same(data_flashed, new_data) and info.program_type is FlashBuilder.FLASH_SECTOR_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Multiple Block Writes ------")
            addr = rom_start + rom_size // 2
            page_size = flash.get_page_info(addr).size
            more_data = [0x33] * page_size * 2
            addr = (rom_start + rom_size // 2) + 1 #cover multiple pages
            fb = flash.get_flash_builder()
            fb.add_data(rom_start, data)
            fb.add_data(addr, more_data)
            fb.program(progress_cb=print_progress())
            data_flashed = target.read_memory_block8(rom_start, len(data))
            data_flashed_more = target.read_memory_block8(addr, len(more_data))
            if same(data_flashed, data) and same(data_flashed_more, more_data):
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Overlapping Blocks ------")
            test_pass = False
            addr = (rom_start + rom_size // 2) #cover multiple pages
            page_size = flash.get_page_info(addr).size
            new_data = [0x33] * page_size
            fb = flash.get_flash_builder()
            fb.add_data(addr, new_data)
            try:
                fb.add_data(addr + 1, new_data)
            except ValueError as e:
                print("Exception: %s" % e)
                test_pass = True
            if test_pass:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Empty Block Write ------")
            # Freebee if nothing asserts
            fb = flash.get_flash_builder()
            fb.program()
            print("TEST PASSED")
            test_pass_count += 1
            test_count += 1

            print("\n------ Test Missing Progress Callback ------")
            # Freebee if nothing asserts
            addr = rom_start
            flash.flash_block(rom_start, data, True)
            print("TEST PASSED")
            test_pass_count += 1
            test_count += 1

            # Only run test if the reset handler can be programmed (rom start at address 0)
            if rom_start == 0:
                print("\n------ Test Non-Thumb reset handler ------")
                non_thumb_data = list(data)
                # Clear bit 0 of 2nd word - reset handler
                non_thumb_data[4] = non_thumb_data[4] & ~1
                flash.flash_block(rom_start, non_thumb_data)
                flash.flash_block(rom_start, data)
                print("TEST PASSED")
                test_pass_count += 1
                test_count += 1

            # Note - The decision based tests below are order dependent since they
            # depend on the previous state of the flash

            if rom_start == flash_info.rom_start:
                print("\n------ Test Chip Erase Decision ------")
                new_data = list(data)
                new_data.extend([flash.region.erased_byte_value] * unused) # Pad with erased value
                info = flash.flash_block(addr, new_data, progress_cb=print_progress())
                if info.program_type == FlashBuilder.FLASH_CHIP_ERASE:
                    print("TEST PASSED")
                    test_pass_count += 1
                    result.chip_erase_rate_erased = float(len(new_data)) / float(info.program_time)
                else:
                    print("TEST FAILED")
                test_count += 1

                print("\n------ Test Chip Erase Decision 2 ------")
                new_data = list(data)
                new_data.extend([unerasedValue] * unused) # Pad with unerased value
                info = flash.flash_block(addr, new_data, progress_cb=print_progress())
                if info.program_type == FlashBuilder.FLASH_CHIP_ERASE:
                    print("TEST PASSED")
                    test_pass_count += 1
                    result.chip_erase_rate = float(len(new_data)) / float(info.program_time)
                else:
                    print("TEST FAILED")
                test_count += 1

            print("\n------ Test Page Erase Decision ------")
            new_data = list(data)
            new_data.extend([unerasedValue] * unused) # Pad with unerased value
            info = flash.flash_block(addr, new_data, progress_cb=print_progress())
            if info.program_type == FlashBuilder.FLASH_SECTOR_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
                result.page_erase_rate_same = float(len(new_data)) / float(info.program_time)
                result.analyze = info.analyze_type
                result.analyze_time = info.analyze_time
                result.analyze_rate = float(len(new_data)) / float(info.analyze_time)
            else:
                print("TEST FAILED")
            test_count += 1

            print("\n------ Test Page Erase Decision 2 ------")
            new_data = list(data)
            size_same = unused * 5 // 6
            size_differ = unused - size_same
            new_data.extend([unerasedValue] * size_same) # Pad 5/6 with unerased value and 1/6 with 0x55
            new_data.extend([0x55] * size_differ)
            info = flash.flash_block(addr, new_data, progress_cb=print_progress())
            if info.program_type == FlashBuilder.FLASH_SECTOR_ERASE:
                print("TEST PASSED")
                test_pass_count += 1
            else:
                print("TEST FAILED")
            test_count += 1

        print("\n\nTest Summary:")
        print("Pass count %i of %i tests" % (test_pass_count, test_count))
        if test_pass_count == test_count:
            print("FLASH TEST SCRIPT PASSED")
        else:
            print("FLASH TEST SCRIPT FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result