Ejemplo n.º 1
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
Ejemplo n.º 2
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
Ejemplo n.º 3
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_default_region_of_type(MemoryType.RAM)
        ram_base = ram_region.start
        binary_file = get_test_binary_path(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
Ejemplo n.º 4
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_default_region_of_type(MemoryType.RAM)
        rom_region = memory_map.get_boot_memory()
        target_type = board.target_type
        binary_file = get_test_binary_path(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
        # Cortex-M devices with FPB revision 1.
        fpb = session.target.selected_core.fpb
        assert fpb is not None
        ignore_hw_bkpt_result = int(fpb.revision == 1
                                    and ram_region.start >= 0x20000000)

        # 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 = os.path.join(
        TEST_OUTPUT_DIR, "gdb_test_params%s_%d.txt" % (get_env_file_name(), n))
    with open(test_param_filename, "w") as f:
        f.write(json.dumps(test_params))

    # Remove result from previous run.
    test_result_filename = os.path.join(
        TEST_OUTPUT_DIR,
        "gdb_test_results%s_%d.txt" % (get_env_file_name(), n))
    if os.path.exists(test_result_filename):
        os.remove(test_result_filename)

    # Run the test
    gdb_args = [
        PYTHON_GDB, "--nh", "-ex",
        "set $testn=%d" % n,
        "--command=%s" % GDB_SCRIPT_PATH
    ]
    gdb_output_filename = os.path.join(
        TEST_OUTPUT_DIR,
        "gdb_output%s_%s_%d.txt" % (get_env_file_name(), board.target_type, n))
    with open(gdb_output_filename, "w") as f:
        LOG.info('Starting gdb (stdout -> %s): %s', gdb_output_filename,
                 ' '.join(gdb_args))
        gdb_program = Popen(gdb_args, stdin=PIPE, stdout=f, stderr=STDOUT)
        server_args = [
            'gdbserver',
            '--port=%i' % test_port,
            "--telnet-port=%i" % telnet_port,
            "--frequency=%i" % target_test_params['test_clock'],
            "--uid=%s" % board_id,
        ]
        server = PyOCDTool()
        LOG.info('Starting gdbserver: %s', ' '.join(server_args))
        server_thread = threading.Thread(target=server.run, args=[server_args])
        server_thread.daemon = True
        server_thread.start()
        LOG.info('Waiting for gdb to finish...')
        did_complete = wait_with_deadline(gdb_program, TEST_TIMEOUT_SECONDS)
        LOG.info('Waiting for server to finish...')
        server_thread.join(timeout=TEST_TIMEOUT_SECONDS)
        if not did_complete:
            LOG.error("Test timed out!")
        if server_thread.is_alive():
            LOG.error('Server is still running!')

    try:
        with open(gdb_output_filename, 'r') as f:
            LOG.debug('Gdb output:\n%s', f.read())
    except IOError:
        pass

    # Read back the result
    result.passed = False
    if did_complete:
        try:
            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
        except IOError as err:
            LOG.error("Error reading test results: %s", err, exc_info=True)

    if result.passed:
        print("GDB TEST PASSED")
    else:
        print("GDB TEST FAILED")

    # Cleanup
    try:
        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)
    except IOError as err:
        pass

    return result
Ejemplo n.º 5
0
def concurrency_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_default_region_of_type(MemoryType.RAM)

        test_pass_count = 0
        test_count = 0
        result = ConcurrencyTestResult()

        target.reset_and_halt()

        # Prepare TEST_THREAD_COUNT regions of RAM with patterns
        data_len = min(TEST_MAX_LENGTH, ram_region.length)
        chunk_len = data_len // TEST_THREAD_COUNT
        subchunk_len = chunk_len // TEST_SUBCHUNK_COUNT

        chunk_data = []
        for i in range(TEST_THREAD_COUNT):
            chunk_data.append([(i + j) % 256 for j in range(chunk_len)])

        def write_chunk_data(core, i):
            start = ram_region.start + chunk_len * i
            for j in range(TEST_SUBCHUNK_COUNT):
                offset = subchunk_len * j
                addr = start + offset
                end = addr + subchunk_len - 1
                print("Writing region %i:%i from %#010x to %#010x via %s" %
                      (i, j, addr, end, core.ap))
                core.write_memory_block8(
                    addr, chunk_data[i][offset:offset + subchunk_len])
                print("Finished writing region %i:%i" % (i, j))

        def read_chunk_data(core, i):
            start = ram_region.start + chunk_len * i
            for j in range(TEST_SUBCHUNK_COUNT):
                offset = subchunk_len * j
                addr = start + offset
                end = addr + subchunk_len - 1
                print("Reading region %i:%i from %#010x to %#010x via %s" %
                      (i, j, addr, end, core.ap))
                data = core.read_memory_block8(addr, subchunk_len)
                chunk_read_data[i].extend(data)
                print("Finished reading region %i:%i" % (i, j))

        # Test with a single core/AP.
        print(
            "\n------ Test 1: Concurrent memory accesses, single core ------")

        core = target.cores[0]

        # Write chunk patterns concurrently.
        print("Writing %i regions to RAM" % TEST_THREAD_COUNT)
        run_in_parallel(write_chunk_data,
                        [[core, i] for i in range(TEST_THREAD_COUNT)])

        print("Reading %i regions to RAM" % TEST_THREAD_COUNT)
        chunk_read_data = [list() for i in range(TEST_THREAD_COUNT)]
        run_in_parallel(read_chunk_data,
                        [[core, i] for i in range(TEST_THREAD_COUNT)])

        print("Comparing data")

        for i in range(TEST_THREAD_COUNT):
            test_count += 1
            if same(chunk_read_data[i], chunk_data[i]):
                test_pass_count += 1
                print("Region %i PASSED" % i)
            else:
                print("Region %i FAILED" % i)

        # Test with a multiple cores/APs.
        # Disabled until cores each have their own memory map, the regions accessible to each
        # core can be identified.
        if False:  # len(target.cores) > 1:
            print(
                "\n------ Test 2: Concurrent memory accesses, multiple cores ------"
            )

            cycle_count = ((len(target.cores) + TEST_THREAD_COUNT - 1) //
                           TEST_THREAD_COUNT * TEST_THREAD_COUNT)
            repeat_cores = ncycles(iter(target.cores), cycle_count)
            thread_args = []
            for i in range(TEST_THREAD_COUNT):
                thread_args.append((target.cores[next(repeat_cores)], i))

            # Write chunk patterns concurrently.
            print("Writing %i regions to RAM" % TEST_THREAD_COUNT)
            run_in_parallel(write_chunk_data, thread_args)

            print("Reading %i regions to RAM" % TEST_THREAD_COUNT)
            chunk_read_data = [list() for i in range(TEST_THREAD_COUNT)]
            run_in_parallel(read_chunk_data, thread_args)

            print("Comparing data")

            for i in range(TEST_THREAD_COUNT):
                test_count += 1
                if same(chunk_read_data[i], chunk_data[i]):
                    test_pass_count += 1
                    print("Region %i PASSED" % i)
                else:
                    print("Region %i FAILED" % i)

        # --- end ---
        print("\nTest Summary:")
        print("Pass count %i of %i tests" % (test_pass_count, test_count))
        if test_pass_count == test_count:
            print("CONCURRENCY TEST PASSED")
        else:
            print("CONCURRENCY TEST FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Ejemplo n.º 6
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
Ejemplo n.º 7
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 = get_test_binary_path(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_default_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)

        print("Verify exception is raised while core is running")
        target.resume()
        try:
            val = target.read_core_register('r0')
        except exceptions.CoreRegisterAccessError:
            passed = True
        else:
            passed = False
        test_count += 1
        if passed:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        print("Verify failure to write core register while running raises exception")
        try:
            target.write_core_register('r0', 0x1234)
        except exceptions.CoreRegisterAccessError:
            passed = True
        else:
            passed = False
        test_count += 1
        if passed:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        # Resume execution.
        target.halt()

        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("Verify that all listed core registers can be accessed")

        def test_reg_rw(r, new_value: int, test_write: bool) -> bool:
            did_pass = True
            try:
                # Read original value.
                original_val = target.read_core_register_raw(r.name)

                if not test_write:
                    return did_pass

                # Make sure the new value changes.
                if new_value == original_val:
                    new_value = 0

                # Change the value.
                target.write_core_register_raw(r.name, new_value)
                read_val = target.read_core_register_raw(r.name)
                if read_val != new_value:
                    print(f"Failed to change value of register {r.name} to {new_value:#x}; read {read_val:#x}")
                    did_pass = False

                target.write_core_register_raw(r.name, original_val)
                read_val = target.read_core_register_raw(r.name)
                if read_val != original_val:
                    print(f"Failed to restore value of register {r.name} back to original {original_val:#x}; read {read_val:#x}")
                    did_pass = False
            except exceptions.CoreRegisterAccessError:
                did_pass = False
            return did_pass

        reg_count = 0
        passed_reg_count = 0
        for r in target.selected_core.core_registers.as_set:
            test_write = True

            # Decide on a new value, ensuring it changes and taking into account register specifics.
            r_mask = (1 << r.bitsize) - 1
            if 'sp' in r.name:
                r_mask &= ~0x3
            elif r.name == 'pc':
                r_mask &= ~0x1
            elif 'xpsr' in r.name:
                r_mask = 0xd0000000
            elif 'control' == r.name:
                # SPSEL is available on all cores.
                r_mask = 0x2
            elif r.name in ('primask', 'faultmask'):
                r_mask = 0x1
            elif r.name == 'basepri':
                r_mask = 0x80
            elif r.name == 'fpscr':
                # v7-M bits
                r_mask = 0xf7c0009f
            new_value = 0xdeadbeef & r_mask

            # Skip write tests on some regs:
            # - combined CFBP
            # - PSR variants not including XPSR
            # - all _NS and _S variants
            if ((r.name in ('cfbp',))
                    or (('psr' in r.name) and (r.name != 'xpsr'))
                    or ('_ns' in r.name) or ('_s' in r.name)
                    ):
                test_write = False

            reg_count += 1
            if test_reg_rw(r, new_value, test_write):
                passed_reg_count += 1

        test_count += 1
        if passed_reg_count == reg_count:
            test_pass_count += 1
            print("TEST PASSED (%i registers)" % reg_count)
        else:
            print("TEST FAILED (%i registers, %i failed)" % (reg_count, reg_count - passed_reg_count))

        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.BreakpointType.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")

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

        target.reset()

        result.passed = test_count == test_pass_count
        return result
Ejemplo n.º 8
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
Ejemplo n.º 9
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_default_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
Ejemplo n.º 10
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
Ejemplo n.º 11
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
Ejemplo n.º 12
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
Ejemplo n.º 13
0
def test_probeserver(board_id=None, n=0):
    test_port = 5555 + n
    temp_test_elf_name = None
    result = ProbeserverTestResult()
    print("Connecting to identify target")
    with ConnectHelper.session_with_chosen_probe(
            unique_id=board_id, **get_session_options()) as session:
        board = session.board
        target_test_params = get_target_test_params(session)
        binary_file = get_test_binary_path(board.test_binary)
        if board_id is None:
            board_id = board.unique_id
        target_type = board.target_type

    # Run the test. We can't kill the server thread, so
    LOG.info('Starting server on port %d', test_port)
    server_args = [
        'pyocd',
        'server',
        '-v',
        '--port=%i' % test_port,
        "--uid=%s" % board_id,
    ]
    server_program = Popen(server_args, stdout=PIPE, stderr=STDOUT)

    try:
        # Read server output waiting for it to report that the server is running.
        with Timeout(TEST_TIMEOUT_SECONDS) as time_out:
            while time_out.check():
                ln = server_program.stdout.readline().decode('ascii')
                print("Server:", ln, end='')
                if "Serving debug probe" in ln:
                    break
                if ln == '':
                    raise TestError("no more output from server")
            else:
                raise TestError("server failed to start")

        server_thread = threading.Thread(
            target=wait_with_deadline,
            args=[server_program, TEST_TIMEOUT_SECONDS])
        server_thread.daemon = True
        server_thread.start()

        # Start client in a thread.
        client_args = [
            'flash',
            "--frequency=%i" % target_test_params['test_clock'],
            "--uid=remote:localhost:%d" % test_port,
            "--target=%s" % target_type, binary_file
        ]
        client = PyOCDTool()
        client._setup_logging = lambda: None  # Disable logging setup so we don't have duplicate log output.
        LOG.info('Starting client: %s', ' '.join(client_args))
        client_thread = threading.Thread(target=client.run, args=[client_args])
        client_thread.daemon = True
        client_thread.start()

        LOG.info('Waiting for client to finish...')
        client_thread.join(timeout=TEST_TIMEOUT_SECONDS)
        did_complete = not client_thread.is_alive()
        if not did_complete:
            LOG.error("Test timed out!")
        LOG.info("killing probe server process")
        server_program.kill()
    except TestError as err:
        LOG.info("test failed: %s", err)
        did_complete = False
        if server_program.returncode is None:
            server_program.kill()

    # Read back the result
    result.passed = did_complete

    if result.passed:
        print("PROBESERVER TEST PASSED")
    else:
        print("PROBESERVER TEST FAILED")

    return result
Ejemplo n.º 14
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

        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()

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

        def test_ram(record_speed=False):
            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()
            target.write_memory_block8(test_addr, 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()
            block = target.read_memory_block8(test_addr, test_size)
            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):
            print("\n\n------ TEST ROM READ SPEED [%s] ------" % test_config)
            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
            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
        
        # Without memcache
        passed = test_ram(True)
        test_count += 1
        test_pass_count += int(passed)
        
        passed = test_rom(True)
        test_count += 1
        test_pass_count += int(passed)
        
        # With memcache
        target = target.get_target_context()
        test_config = "cached, 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, 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
Ejemplo n.º 15
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_default_region_of_type(MemoryType.RAM)
        ram_base = ram_region.start
        binary_file = get_test_binary_path(board.test_binary)
        gdb_test_binary_file = os.path.join(PYOCD_DIR, GDB_TEST_BIN)

        # Read the gdb test binary file.
        with open(gdb_test_binary_file, "rb") as f:
            gdb_test_binary_data = list(bytearray(f.read()))

        # Read the test binary file.
        with open(binary_file, "rb") as f:
            test_binary_data = bytearray(f.read())
        test_binary_data_length = len(test_binary_data)

        # Generate ELF file from the binary test file.
        temp_test_elf_name = binary_to_elf_file(binary_file, boot_region.start)

        test_pass_count = 0
        test_count = 0
        result = DebugContextTestResult()

        target.reset_and_halt()

        # Reproduce a gdbserver failure.
        print("\n------ Test 1: Mem cache ------")

        ctx = target.get_target_context()

        print("Writing gdb test binary")
        ctx.write_memory_block8(ram_base, gdb_test_binary_data)

        print("Reading first chunk")
        data = ctx.read_memory_block8(ram_base, 64)
        if data == gdb_test_binary_data[:64]:
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")
        test_count += 1

        print("Reading N chunks")
        did_pass = True
        for n in range(8):
            offset = 0x7e + (4 * n)
            data = ctx.read_memory_block8(ram_base + offset, 4)
            if data == gdb_test_binary_data[offset:offset + 4]:
                test_pass_count += 1
            else:
                did_pass = False
            test_count += 1
        if did_pass:
            print("TEST PASSED")
        else:
            print("TEST FAILED")

        # Force a memory cache clear.
        target.step()

        # ELF reader test goals:
        # 1. Verify correct data is read without accessing the target memory.
        # 2. Test null interval failure.
        #
        print("\n------ Test 2: ELF reader ------")

        # Set the elf on the target, which will add a context to read from the elf.
        target.elf = temp_test_elf_name
        ctx = target.get_target_context()

        print("Check that ElfReaderContext was created")
        if isinstance(ctx, ElfReaderContext):
            test_pass_count += 1
            print("TEST PASSED")
        else:
            print("TEST FAILED")
        test_count += 1

        # Program the test binary.
        print("Programming test binary to boot memory")
        FileProgrammer(session).program(binary_file, base_address=boot_region.start)

        with mock.patch.object(target.selected_core, 'read_memory_block32') as read_block32_mock:
            test_len = min(4096, test_binary_data_length)
            print("Reading %d bytes of test binary from context." % test_len)
            data = ctx.read_memory_block32(boot_region.start, test_len // 4)
            data = conversion.u32le_list_to_byte_list(data)
            if same(data, test_binary_data[:test_len]):
                print("PASSED: expected data returned")
                test_pass_count += 1
            else:
                print("FAILED: unexpected data")
            test_count += 1

            # Verify the target memory wasn't accessed.
            try:
                read_block32_mock.assert_not_called()
            except AssertionError:
                print("FAILED: target memory was accessed")
            else:
                print("PASSED: target memory was not accessed")
                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")

        # Clean up.
        target.reset()

        result.passed = test_count == test_pass_count
        return result
Ejemplo n.º 16
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
        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
Ejemplo n.º 17
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_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()
        boot_start_addr = boot_region.start
        boot_end_addr = boot_region.end
        boot_blocksize = boot_region.blocksize
        binary_file = os.path.join(parentdir, 'binaries', 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)

        test_pass_count = 0
        test_count = 0
        result = FlashLoaderTestResult()
        
        with open(binary_file, "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, file_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------ Test Intel Hex File Load ------")
        programmer = FileProgrammer(session)
        programmer.program(temp_test_hex_name, file_format='hex')
        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
Ejemplo n.º 18
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_default_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.iter_matching_regions(
                type=MemoryType.FLASH, is_testable=True):
            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 = get_test_binary_path(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_data_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_data_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
Ejemplo n.º 19
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
Ejemplo n.º 20
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()

        # TEST basic functionality
        print("\n------ Testing delegates ------")

        # TODO verify user script delegates were called
        target.reset_and_halt()
        target.resume()
        target.halt()
        target.step()

        test_count += 1
        test_pass_count += 1
        print("TEST PASSED")

        # TEST user defined commands
        print("\n------ Testing user defined commands ------")
        context = CommandExecutionContext()
        context.attach_session(session)

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

        # Verify command with float, int, str args.
        if test_command("testcmd 3.14 0xbeef foobar"):
            test_pass_count += 1
        test_count += 1

        # Verify varargs: all should be strings in the cmd's args
        if test_command("anothertestcmd a b 1 2 fee fie foe"):
            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("USER SCRIPT TEST PASSED")
        else:
            print("USER SCRIPT TEST FAILED")

        target.reset()

        result.passed = test_count == test_pass_count
        return result