def user_script_test(board_id): with ConnectHelper.session_with_chosen_probe( unique_id=board_id, user_script=TEST_USER_SCRIPT, **get_session_options()) as session: board = session.board target = session.target test_params = get_target_test_params(session) session.probe.set_clock(test_params['test_clock']) memory_map = target.get_memory_map() boot_region = memory_map.get_boot_memory() ram_region = memory_map.get_default_region_of_type(MemoryType.RAM) binary_file = get_test_binary_path(board.test_binary) test_pass_count = 0 test_count = 0 result = UserScriptTestResult() target.reset_and_halt() target.resume() target.halt() target.step() test_count += 1 test_pass_count += 1 print("\nTest Summary:") print("Pass count %i of %i tests" % (test_pass_count, test_count)) if test_pass_count == test_count: print("USER SCRIPT TEST PASSED") else: print("USER SCRIPT TEST FAILED") target.reset() result.passed = test_count == test_pass_count return result
def 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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