def test_connect(halt_on_connect, expected_state, resume): print("Connecting with halt_on_connect=%s" % halt_on_connect) live_session = ConnectHelper.session_with_chosen_probe( board_id=board_id, init_board=False, halt_on_connect=halt_on_connect, resume_on_disconnect=resume, **get_session_options()) live_session.open() live_board = live_session.board print("Verifying target is", STATE_NAMES.get(expected_state, "unknown")) actualState = live_board.target.get_state() # Accept sleeping for running, as a hack to work around nRF52840-DK test binary. # TODO remove sleeping hack. if (actualState == expected_state) \ or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING): passed = 1 print("TEST PASSED") else: passed = 0 print("TEST FAILED (state={}, expected={})".format( STATE_NAMES.get(actualState, "unknown"), STATE_NAMES.get(expected_state, "unknown"))) print("Disconnecting with resume=%s" % resume) live_session.close() live_session = None return passed
def test_connect(connect_mode, expected_state, resume): print("Connecting with connect_mode=%s" % connect_mode) live_session = ConnectHelper.session_with_chosen_probe( unique_id=board_id, init_board=False, connect_mode=connect_mode, resume_on_disconnect=resume, **get_session_options()) live_session.open() live_board = live_session.board print("Verifying target is", STATE_NAMES.get(expected_state, "unknown")) actualState = live_board.target.get_state() # Accept sleeping for running, as a hack to work around nRF52840-DK test binary. # TODO remove sleeping hack. if (actualState == expected_state) \ or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING): passed = 1 print("TEST PASSED") else: passed = 0 print("TEST FAILED (state={}, expected={})".format( STATE_NAMES.get(actualState, "unknown"), STATE_NAMES.get(expected_state, "unknown"))) print("Disconnecting with resume=%s" % resume) live_session.close() live_session = None return passed
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 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
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 if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyOCD flash loader test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') parser.add_argument("-da", "--daparg", dest="daparg", nargs='+', help="Send setting to DAPAccess layer.") args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) DAPAccess.set_args(args.daparg) # Set to debug to print some of the decisions made while flashing session = ConnectHelper.session_with_chosen_probe(open_session=False, **get_session_options()) test = FlashLoaderTest() result = [test.run(session.board)]
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 basic_test(board_id, file): with ConnectHelper.session_with_chosen_probe( unique_id=board_id, **get_session_options()) as session: board = session.board addr = 0 size = 0 f = None binary_file = "l1_" if file is None: binary_file = os.path.join(parentdir, 'binaries', board.test_binary) else: binary_file = file print("binary file: %s" % binary_file) memory_map = board.target.get_memory_map() ram_region = memory_map.get_first_region_of_type(MemoryType.RAM) rom_region = memory_map.get_boot_memory() addr = ram_region.start size = 0x502 addr_bin = rom_region.start addr_flash = rom_region.start + rom_region.length // 2 target = board.target flash = rom_region.flash print("\n\n------ GET Unique ID ------") print("Unique ID: %s" % board.unique_id) print("\n\n------ TEST READ / WRITE CORE REGISTER ------") pc = target.read_core_register('pc') print("initial pc: 0x%X" % target.read_core_register('pc')) # write in pc dummy value target.write_core_register('pc', 0x3D82) print("now pc: 0x%X" % target.read_core_register('pc')) # write initial pc value target.write_core_register('pc', pc) print("initial pc value rewritten: 0x%X" % target.read_core_register('pc')) msp = target.read_core_register('msp') psp = target.read_core_register('psp') print("MSP = 0x%08x; PSP = 0x%08x" % (msp, psp)) control = target.read_core_register('control') faultmask = target.read_core_register('faultmask') basepri = target.read_core_register('basepri') primask = target.read_core_register('primask') print( "CONTROL = 0x%02x; FAULTMASK = 0x%02x; BASEPRI = 0x%02x; PRIMASK = 0x%02x" % (control, faultmask, basepri, primask)) target.write_core_register('primask', 1) newPrimask = target.read_core_register('primask') print("New PRIMASK = 0x%02x" % newPrimask) target.write_core_register('primask', primask) newPrimask = target.read_core_register('primask') print("Restored PRIMASK = 0x%02x" % newPrimask) if target.has_fpu: s0 = target.read_core_register('s0') print("S0 = %g (0x%08x)" % (s0, float32_to_u32(s0))) target.write_core_register('s0', math.pi) newS0 = target.read_core_register('s0') print("New S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) target.write_core_register('s0', s0) newS0 = target.read_core_register('s0') print("Restored S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) print("\n\n------ TEST HALT / RESUME ------") print("resume") target.resume() sleep(0.2) print("halt") target.halt() print("HALT: pc: 0x%X" % target.read_core_register('pc')) sleep(0.2) print("\n\n------ TEST STEP ------") print("reset and halt") target.reset_and_halt() currentPC = target.read_core_register('pc') print("HALT: pc: 0x%X" % currentPC) sleep(0.2) for i in range(4): print("step") target.step() newPC = target.read_core_register('pc') print("STEP: pc: 0x%X" % newPC) currentPC = newPC sleep(0.2) print("\n\n------ TEST READ / WRITE MEMORY ------") target.halt() print("READ32/WRITE32") val = randrange(0, 0xffffffff) print("write32 0x%X at 0x%X" % (val, addr)) target.write_memory(addr, val) res = target.read_memory(addr) print("read32 at 0x%X: 0x%X" % (addr, res)) if res != val: print("ERROR in READ/WRITE 32") print("\nREAD16/WRITE16") val = randrange(0, 0xffff) print("write16 0x%X at 0x%X" % (val, addr + 2)) target.write_memory(addr + 2, val, 16) res = target.read_memory(addr + 2, 16) print("read16 at 0x%X: 0x%X" % (addr + 2, res)) if res != val: print("ERROR in READ/WRITE 16") print("\nREAD8/WRITE8") val = randrange(0, 0xff) print("write8 0x%X at 0x%X" % (val, addr + 1)) target.write_memory(addr + 1, val, 8) res = target.read_memory(addr + 1, 8) print("read8 at 0x%X: 0x%X" % (addr + 1, res)) if res != val: print("ERROR in READ/WRITE 8") print("\n\n------ TEST READ / WRITE MEMORY BLOCK ------") data = [randrange(1, 50) for x in range(size)] target.write_memory_block8(addr, data) block = target.read_memory_block8(addr, size) error = False for i in range(len(block)): if (block[i] != data[i]): error = True print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i])) if error: print("TEST FAILED") else: print("TEST PASSED") print("\n\n------ TEST RESET ------") target.reset() sleep(0.1) target.halt() for i in range(5): target.step() print("pc: 0x%X" % target.read_core_register('pc')) print("\n\n------ TEST PROGRAM/ERASE PAGE ------") # Fill 3 pages with 0x55 page_size = flash.get_page_info(addr_flash).size fill = [0x55] * page_size for i in range(0, 3): address = addr_flash + page_size * i # Test only supports a location with 3 aligned # pages of the same size current_page_size = flash.get_page_info(addr_flash).size assert page_size == current_page_size assert address % current_page_size == 0 flash.init(flash.Operation.ERASE) flash.erase_page(address) flash.uninit() flash.init(flash.Operation.PROGRAM) flash.program_page(address, fill) flash.uninit() # Erase the middle page flash.init(flash.Operation.ERASE) flash.erase_page(addr_flash + page_size) flash.cleanup() # Verify the 1st and 3rd page were not erased, and that the 2nd page is fully erased data = target.read_memory_block8(addr_flash, page_size * 3) expected = fill + [0xFF] * page_size + fill if data == expected: print("TEST PASSED") else: print("TEST FAILED") print("\n\n----- FLASH NEW BINARY -----") FileProgrammer(session).program(binary_file, base_address=addr_bin) target.reset()
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 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 test_board(board_id, n, loglevel, logToConsole, commonLogFile): probe = DebugProbeAggregator.get_probe_with_id(board_id) assert probe is not None session = Session(probe, **get_session_options()) board = session.board originalStdout = sys.stdout originalStderr = sys.stderr # Open board-specific output file. log_filename = "automated_test_results_%s_%d.txt" % (board.name, n) if os.path.exists(log_filename): os.remove(log_filename) log_file = open(log_filename, "a", buffering=1) # 1=Unbuffered # Setup logging. log_handler = RecordingLogHandler(None) log_handler.setFormatter(logging.Formatter(LOG_FORMAT)) root_logger = logging.getLogger() root_logger.setLevel(loglevel) root_logger.addHandler(log_handler) result_list = [] try: # Write board header to board log file, common log file, and console. print_board_header(log_file, board, n) if commonLogFile: print_board_header(commonLogFile, board, n, includeLeadingNewline=(n != 0)) print_board_header(originalStdout, board, n, logToConsole, includeLeadingNewline=(n != 0)) # Skip this board if we don't have a test binary. if board.test_binary is None: print("Skipping board %s due to missing test binary" % board.unique_id) return result_list # Run all tests on this board. for test in test_list: print("{} #{}: starting {}...".format(board.name, n, test.name), file=originalStdout) # Set a unique port for the GdbTest. if isinstance(test, GdbTest): test.n = n # Create a StringIO object to record the test's output, an IOTee to copy # output to both the log file and StringIO, then set the log handler and # stdio to write to the tee. testOutput = io.StringIO() tee = IOTee(log_file, testOutput) if logToConsole: tee.add(originalStdout) if commonLogFile is not None: tee.add(commonLogFile) log_handler.stream = tee sys.stdout = tee sys.stderr = tee test_start = time() result = test.run(board) test_stop = time() result.time = test_stop - test_start tee.flush() result.output = testOutput.getvalue() result_list.append(result) passFail = "PASSED" if result.passed else "FAILED" print("{} #{}: finished {}... {} ({:.3f} s)".format( board.name, n, test.name, passFail, result.time), file=originalStdout) finally: # Restore stdout/stderr in case we're running in the parent process (1 job). sys.stdout = originalStdout sys.stderr = originalStderr root_logger.removeHandler(log_handler) log_handler.flush() log_handler.close() return result_list
def basic_test(board_id, file): with ConnectHelper.session_with_chosen_probe( unique_id=board_id, **get_session_options()) as session: board = session.board addr = 0 size = 0 f = None binary_file = "l1_" if file is None: binary_file = get_test_binary_path(board.test_binary) else: binary_file = file print("binary file: %s" % binary_file) memory_map = board.target.get_memory_map() ram_region = memory_map.get_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 flash = rom_region.flash print("\n\n------ GET Unique ID ------") print("Unique ID: %s" % board.unique_id) print("\n\n------ TEST READ / WRITE CORE REGISTER ------") pc = target.read_core_register('pc') print("initial pc: 0x%X" % target.read_core_register('pc')) # write in pc dummy value target.write_core_register('pc', 0x3D82) print("now pc: 0x%X" % target.read_core_register('pc')) # write initial pc value target.write_core_register('pc', pc) print("initial pc value rewritten: 0x%X" % target.read_core_register('pc')) msp = target.read_core_register('msp') psp = target.read_core_register('psp') print("MSP = 0x%08x; PSP = 0x%08x" % (msp, psp)) if 'faultmask' in target.core_registers.by_name: control = target.read_core_register('control') faultmask = target.read_core_register('faultmask') basepri = target.read_core_register('basepri') primask = target.read_core_register('primask') print( "CONTROL = 0x%02x; FAULTMASK = 0x%02x; BASEPRI = 0x%02x; PRIMASK = 0x%02x" % (control, faultmask, basepri, primask)) else: control = target.read_core_register('control') primask = target.read_core_register('primask') print("CONTROL = 0x%02x; PRIMASK = 0x%02x" % (control, primask)) target.write_core_register('primask', 1) newPrimask = target.read_core_register('primask') print("New PRIMASK = 0x%02x" % newPrimask) target.write_core_register('primask', primask) newPrimask = target.read_core_register('primask') print("Restored PRIMASK = 0x%02x" % newPrimask) if target.selected_core.has_fpu: s0 = target.read_core_register('s0') print("S0 = %g (0x%08x)" % (s0, float32_to_u32(s0))) target.write_core_register('s0', math.pi) newS0 = target.read_core_register('s0') print("New S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) target.write_core_register('s0', s0) newS0 = target.read_core_register('s0') print("Restored S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) print("\n\n------ TEST HALT / RESUME ------") print("resume") target.resume() sleep(0.2) print("halt") target.halt() print("HALT: pc: 0x%X" % target.read_core_register('pc')) sleep(0.2) print("\n\n------ TEST STEP ------") print("reset and halt") target.reset_and_halt() currentPC = target.read_core_register('pc') print("HALT: pc: 0x%X" % currentPC) sleep(0.2) for i in range(4): print("step") target.step() newPC = target.read_core_register('pc') print("STEP: pc: 0x%X" % newPC) sleep(0.2) print("\n\n------ TEST RANGE STEP ------") # Add some extra room before end of memory, and a second copy so there are instructions # after the final bkpt. Add 1 because region end is always odd. test_addr = ram_region.end + 1 - len(RANGE_STEP_CODE) * 2 - 32 # Since the end address is inclusive, we need to exclude the last instruction. test_end_addr = test_addr + len(RANGE_STEP_CODE) - 2 print("range start = %#010x; range_end = %#010x" % (test_addr, test_end_addr)) # Load up some code into ram to test range step. target.write_memory_block8(test_addr, RANGE_STEP_CODE * 2) check_data = target.read_memory_block8(test_addr, len(RANGE_STEP_CODE) * 2) if not same(check_data, RANGE_STEP_CODE * 2): print("Failed to write range step test code to RAM") else: print("wrote range test step code to RAM successfully") target.write_core_register('pc', test_addr) currentPC = target.read_core_register('pc') print("start PC: 0x%X" % currentPC) target.step(start=test_addr, end=test_end_addr) newPC = target.read_core_register('pc') print("end PC: 0x%X" % newPC) # Now test again to ensure the bkpt stops it. target.write_core_register('pc', test_addr) currentPC = target.read_core_register('pc') print("start PC: 0x%X" % currentPC) target.step(start=test_addr, end=test_end_addr + 4) # include bkpt newPC = target.read_core_register('pc') print("end PC: 0x%X" % newPC) halt_reason = target.get_halt_reason() print("halt reason: %s (should be BREAKPOINT)" % halt_reason.name) print("\n\n------ TEST READ / WRITE MEMORY ------") target.halt() print("READ32/WRITE32") val = randrange(0, 0xffffffff) print("write32 0x%X at 0x%X" % (val, addr)) target.write_memory(addr, val) res = target.read_memory(addr) print("read32 at 0x%X: 0x%X" % (addr, res)) if res != val: print("ERROR in READ/WRITE 32") print("\nREAD16/WRITE16") val = randrange(0, 0xffff) print("write16 0x%X at 0x%X" % (val, addr + 2)) target.write_memory(addr + 2, val, 16) res = target.read_memory(addr + 2, 16) print("read16 at 0x%X: 0x%X" % (addr + 2, res)) if res != val: print("ERROR in READ/WRITE 16") print("\nREAD8/WRITE8") val = randrange(0, 0xff) print("write8 0x%X at 0x%X" % (val, addr + 1)) target.write_memory(addr + 1, val, 8) res = target.read_memory(addr + 1, 8) print("read8 at 0x%X: 0x%X" % (addr + 1, res)) if res != val: print("ERROR in READ/WRITE 8") print("\n\n------ TEST READ / WRITE MEMORY BLOCK ------") data = [randrange(1, 50) for x in range(size)] target.write_memory_block8(addr, data) block = target.read_memory_block8(addr, size) error = False for i in range(len(block)): if (block[i] != data[i]): error = True print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i])) if error: print("TEST FAILED") else: print("TEST PASSED") print("\n\n------ TEST RESET ------") target.reset() sleep(0.1) target.halt() for i in range(5): target.step() print("pc: 0x%X" % target.read_core_register('pc')) print("\n\n------ TEST PROGRAM/ERASE PAGE ------") # Fill 3 pages with 0x55 sector_size = rom_region.sector_size page_size = rom_region.page_size sectors_to_test = min(rom_region.length // sector_size, 3) addr_flash = rom_region.start + rom_region.length - sector_size * sectors_to_test fill = [0x55] * page_size for i in range(0, sectors_to_test): address = addr_flash + sector_size * i # Test only supports a location with 3 aligned # pages of the same size current_page_size = flash.get_page_info(addr_flash).size assert page_size == current_page_size assert address % current_page_size == 0 print("Erasing sector @ 0x%x (%d bytes)" % (address, sector_size)) flash.init(flash.Operation.ERASE) flash.erase_sector(address) print("Verifying erased sector @ 0x%x (%d bytes)" % (address, sector_size)) data = target.read_memory_block8(address, sector_size) if data != [flash.region.erased_byte_value] * sector_size: print("FAILED to erase sector @ 0x%x (%d bytes)" % (address, sector_size)) else: print("Programming page @ 0x%x (%d bytes)" % (address, page_size)) flash.init(flash.Operation.PROGRAM) flash.program_page(address, fill) print("Verifying programmed page @ 0x%x (%d bytes)" % (address, page_size)) data = target.read_memory_block8(address, page_size) if data != fill: print("FAILED to program page @ 0x%x (%d bytes)" % (address, page_size)) # Erase the middle sector if sectors_to_test > 1: address = addr_flash + sector_size print("Erasing sector @ 0x%x (%d bytes)" % (address, sector_size)) flash.init(flash.Operation.ERASE) flash.erase_sector(address) flash.cleanup() print("Verifying erased sector @ 0x%x (%d bytes)" % (address, sector_size)) data = target.read_memory_block8(address, sector_size) if data != [flash.region.erased_byte_value] * sector_size: print("FAILED to erase sector @ 0x%x (%d bytes)" % (address, sector_size)) # Re-verify the 1st and 3rd page were not erased, and that the 2nd page is fully erased did_pass = False for i in range(0, sectors_to_test): address = addr_flash + sector_size * i print("Verifying page @ 0x%x (%d bytes)" % (address, page_size)) data = target.read_memory_block8(address, page_size) expected = ([flash.region.erased_byte_value] * page_size) if (i == 1) else fill did_pass = (data == expected) if not did_pass: print("FAILED verify for page @ 0x%x (%d bytes)" % (address, page_size)) break if did_pass: print("TEST PASSED") else: print("TEST FAILED") print("\n\n----- FLASH NEW BINARY -----") FileProgrammer(session).program(binary_file, base_address=addr_bin) target.reset()
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_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 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_clock = 10000000 addr_invalid = 0x3E000000 # Last 16MB of ARM SRAM region - typically empty expect_invalid_access_to_fail = True if target_type in ("nrf51", "nrf52", "nrf52840"): # Override clock since 10MHz is too fast test_clock = 1000000 expect_invalid_access_to_fail = False elif target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 memory_map = board.target.getMemoryMap() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] rom_region = memory_map.getBootMemory() addr = ram_region.start + 1 size = 0x502 addr_bin = rom_region.start target = board.target probe = session.probe flash = board.flash probe.set_clock(test_clock) test_pass_count = 0 test_count = 0 result = CortexTestResult() debugContext = target.getTargetContext() gdbFacade = pyOCD.gdbserver.context_facade.GDBDebugContextFacade( debugContext) print("\n\n----- FLASH NEW BINARY BEFORE TEST -----") flash.flashBinary(binary_file, 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.getTResponse) print("Function getTResponse time: %f" % test_time) # Step test_time = test_function(session, target.step) print("Function step time: %f" % test_time) # Breakpoint def set_remove_breakpoint(): target.setBreakpoint(0) target.removeBreakpoint(0) test_time = test_function(session, set_remove_breakpoint) print("Add and remove breakpoint: %f" % test_time) # getRegisterContext test_time = test_function(session, gdbFacade.getRegisterContext) print("Function getRegisterContext: %f" % test_time) # setRegisterContext context = gdbFacade.getRegisterContext() def set_register_context(): gdbFacade.setRegisterContext(context) test_time = test_function(session, set_register_context) print("Function setRegisterContext: %f" % test_time) # Run / Halt def run_halt(): target.resume() target.halt() test_time = test_function(session, run_halt) print("Resume and halt: %f" % test_time) # GDB stepping def simulate_step(): target.step() gdbFacade.getTResponse() target.setBreakpoint(0) target.resume() target.halt() gdbFacade.getTResponse() target.removeBreakpoint(0) test_time = test_function(session, simulate_step) 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 Invalid Memory Access Recovery ------") memory_access_pass = True try: target.readBlockMemoryUnaligned8(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: memory_access_pass = False except exceptions.TransferFaultError: pass try: target.readBlockMemoryUnaligned8(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: memory_access_pass = False except exceptions.TransferFaultError: pass data = [0x00] * 0x1000 try: target.writeBlockMemoryUnaligned8(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: memory_access_pass = False except exceptions.TransferFaultError: pass data = [0x00] * 0x1000 try: target.writeBlockMemoryUnaligned8(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: memory_access_pass = False except exceptions.TransferFaultError: pass data = [randrange(0, 255) for x in range(size)] target.writeBlockMemoryUnaligned8(addr, data) block = target.readBlockMemoryUnaligned8(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)] target.writeBlockMemoryUnaligned8(addr + 1, data) block = target.readBlockMemoryUnaligned8(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.readBlockMemoryUnaligned8(addr, 2) orig8 = target.read8(addr) orig16 = target.read16(addr & ~1) orig32 = target.read32(addr & ~3) origAligned32 = target.readBlockMemoryAligned32(addr & ~3, 1) def test_filters(): test_passed = True filtered = target.readBlockMemoryUnaligned8(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.readBlockMemoryAligned32(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.setBreakpoint(addr, pyOCD.core.target.Target.BREAKPOINT_SW) test_passed = test_filters() and test_passed print("Removed software breakpoint") target.removeBreakpoint(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 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 test_gdb(board_id=None, n=0): temp_test_elf_name = None result = GdbTestResult() with ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) as session: board = session.board memory_map = board.target.get_memory_map() ram_region = memory_map.get_first_region_of_type(MemoryType.RAM) rom_region = memory_map.get_boot_memory() target_type = board.target_type binary_file = os.path.join(parentdir, 'binaries', board.test_binary) if board_id is None: board_id = board.unique_id test_clock = 10000000 test_port = 3333 + n telnet_port = 4444 + n error_on_invalid_access = True # Hardware breakpoints are not supported above 0x20000000 on # CortexM devices ignore_hw_bkpt_result = 1 if ram_region.start >= 0x20000000 else 0 if target_type in ("nrf51", "nrf52", "nrf52840"): # Override clock since 10MHz is too fast test_clock = 1000000 # Reading invalid ram returns 0 or nrf51 error_on_invalid_access = False if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 # Program with initial test image FileProgrammer(session).program(binary_file, base_address=rom_region.start) # Generate an elf from the binary test file. temp_test_elf_name = tempfile.mktemp('.elf') objcopyOutput = check_output([OBJCOPY, "-v", "-I", "binary", "-O", "elf32-littlearm", "-B", "arm", "-S", "--set-start", "0x%x" % rom_region.start, "--change-addresses", "0x%x" % rom_region.start, binary_file, temp_test_elf_name], stderr=STDOUT) print(to_str_safe(objcopyOutput)) # Need to escape backslashes on Windows. if sys.platform.startswith('win'): temp_test_elf_name = temp_test_elf_name.replace('\\', '\\\\') # Write out the test configuration test_params = { "test_port" : test_port, "rom_start" : rom_region.start, "rom_length" : rom_region.length, "ram_start" : ram_region.start, "ram_length" : ram_region.length, "invalid_start" : 0x3E000000, "invalid_length" : 0x1000, "expect_error_on_invalid_access" : error_on_invalid_access, "ignore_hw_bkpt_result" : ignore_hw_bkpt_result, "test_elf" : temp_test_elf_name, } test_param_filename = "test_params%d.txt" % n with open(test_param_filename, "w") as f: f.write(json.dumps(test_params)) # Run the test gdb = [PYTHON_GDB, "-ex", "set $testn=%d" % n, "--command=gdb_script.py"] output_filename = "output_%s_%d.txt" % (board.target_type, n) with open(output_filename, "w") as f: program = Popen(gdb, stdin=PIPE, stdout=f, stderr=STDOUT) args = ['gdbserver', '--port=%i' % test_port, "--telnet-port=%i" % telnet_port, "--frequency=%i" % test_clock, "--uid=%s" % board_id, '-Oboard_config_file=test_boards.json' ] server = PyOCDTool() server.run(args) program.wait() # Read back the result test_result_filename = "test_results%d.txt" % n with open(test_result_filename, "r") as f: test_result = json.loads(f.read()) # Print results if set(TEST_RESULT_KEYS).issubset(test_result): print("----------------Test Results----------------") print("HW breakpoint count: %s" % test_result["breakpoint_count"]) print("Watchpoint count: %s" % test_result["watchpoint_count"]) print("Average instruction step time: %s" % test_result["step_time_si"]) print("Average single step time: %s" % test_result["step_time_s"]) print("Average over step time: %s" % test_result["step_time_n"]) print("Failure count: %i" % test_result["fail_count"]) result.passed = test_result["fail_count"] == 0 else: result.passed = False # Cleanup if temp_test_elf_name and os.path.exists(temp_test_elf_name): os.remove(temp_test_elf_name) os.remove(test_result_filename) os.remove(test_param_filename) return result
else: print("FLASH TEST SCRIPT FAILED") target.reset() result.passed = test_count == test_pass_count return result if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyOCD flash test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') parser.add_argument("-da", "--daparg", dest="daparg", nargs='+', help="Send setting to DAPAccess layer.") args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) DAPAccess.set_args(args.daparg) # Set to debug to print some of the decisions made while flashing session = ConnectHelper.session_with_chosen_probe(open_session=False, **get_session_options()) test = FlashTest() result = [test.run(session.board)] test.print_perf_info(result)
def test_board(board_id, n, loglevel, logToConsole, commonLogFile): """! @brief Run all tests on a given board. When multiple test jobs are being used, this function is the entry point executed in child processes. Always writes both stdout and log messages of tests to a board-specific log file, and saves the output for each test to a string that is stored in the TestResult object. Depending on the logToConsole and commonLogFile parameters, output may also be copied to the console (sys.stdout) and/or a common log file for all boards. @param board_id Unique ID of the board to test. @param n Unique index of the test run. @param loglevel Log level passed to logger instance. Usually INFO or DEBUG. @param logToConsole Boolean indicating whether output should be copied to sys.stdout. @param commonLogFile If not None, an open file object to which output should be copied. """ probe = DebugProbeAggregator.get_probe_with_id(board_id) assert probe is not None session = Session(probe, **get_session_options()) board = session.board originalStdout = sys.stdout originalStderr = sys.stderr # Open board-specific output file. env_name = (("_" + os.environ['TOX_ENV_NAME']) if ('TOX_ENV_NAME' in os.environ) else '') name_info = "{}_{}_{}".format(env_name, board.name, n) log_filename = LOG_FILE_TEMPLATE.format(name_info) if os.path.exists(log_filename): os.remove(log_filename) log_file = open(log_filename, "a", buffering=1) # 1=Unbuffered # Setup logging. log_handler = RecordingLogHandler(None) log_handler.setFormatter(logging.Formatter(LOG_FORMAT)) root_logger = logging.getLogger() root_logger.setLevel(loglevel) root_logger.addHandler(log_handler) result_list = [] try: # Write board header to board log file, common log file, and console. print_board_header(log_file, board, n) if commonLogFile: print_board_header(commonLogFile, board, n, includeLeadingNewline=(n != 0)) print_board_header(originalStdout, board, n, logToConsole, includeLeadingNewline=(n != 0)) # Skip this board if we don't have a test binary. if board.test_binary is None: print("Skipping board %s due to missing test binary" % board.unique_id) return result_list # Run all tests on this board. for test in test_list: print("{} #{}: starting {}...".format(board.name, n, test.name), file=originalStdout) # Set a unique port for the GdbTest. if isinstance(test, GdbTest): test.n = n # Create a StringIO object to record the test's output, an IOTee to copy # output to both the log file and StringIO, then set the log handler and # stdio to write to the tee. testOutput = io.StringIO() tee = IOTee(log_file, testOutput) if logToConsole: tee.add(originalStdout) if commonLogFile is not None: tee.add(commonLogFile) log_handler.stream = tee sys.stdout = tee sys.stderr = tee test_start = time() result = test.run(board) test_stop = time() result.time = test_stop - test_start tee.flush() result.output = testOutput.getvalue() result_list.append(result) passFail = "PASSED" if result.passed else "FAILED" print("{} #{}: finished {}... {} ({:.3f} s)".format( board.name, n, test.name, passFail, result.time), file=originalStdout) finally: # Restore stdout/stderr in case we're running in the parent process (1 job). sys.stdout = originalStdout sys.stderr = originalStderr root_logger.removeHandler(log_handler) log_handler.flush() log_handler.close() return result_list
print("\n{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( "#", "Prev Exit", "Halt on Connect", "Expected", "Disconnect Resume", "Exit", "Passed")) for i, case in enumerate(test_cases): print("{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( i, STATE_NAMES[case.prev_exit_state], repr(case.halt_on_connect), STATE_NAMES[case.expected_state], repr(case.disconnect_resume), STATE_NAMES[case.exit_state], "PASS" if case.passed else "FAIL")) print("\nPass count %i of %i tests" % (test_pass_count, test_count)) if test_pass_count == test_count: print("CONNECT TEST SCRIPT PASSED") else: print("CONNECT TEST SCRIPT FAILED") result.passed = (test_count == test_pass_count) return result if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyOCD connect test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) session = ConnectHelper.session_with_chosen_probe(open_session=False, **get_session_options()) test = ConnectTest() result = [test.run(session.board)] test.print_perf_info(result)
from random import randrange import math import logging parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parentdir) from pyocd.core.helpers import ConnectHelper from pyocd.flash.loader import FileProgrammer from test_util import get_session_options logging.basicConfig(level=logging.INFO) print("\n\n------ Test attaching to locked board ------") for i in range(0, 10): with ConnectHelper.session_with_chosen_probe(**get_session_options()) as session: board = session.board # Erase and then reset - This locks Kinetis devices board.flash.init(board.flash.Operation.ERASE) board.flash.erase_all() board.flash.cleanup() board.target.reset() print("\n\n------ Testing Attaching to board ------") for i in range(0, 100): with ConnectHelper.session_with_chosen_probe(**get_session_options()) as session: board = session.board board.target.halt() sleep(0.01) board.target.resume() sleep(0.01)
def test_board(board_id, n, loglevel, logToConsole, commonLogFile): """! @brief Run all tests on a given board. When multiple test jobs are being used, this function is the entry point executed in child processes. Always writes both stdout and log messages of tests to a board-specific log file, and saves the output for each test to a string that is stored in the TestResult object. Depending on the logToConsole and commonLogFile parameters, output may also be copied to the console (sys.stdout) and/or a common log file for all boards. @param board_id Unique ID of the board to test. @param n Unique index of the test run. @param loglevel Log level passed to logger instance. Usually INFO or DEBUG. @param logToConsole Boolean indicating whether output should be copied to sys.stdout. @param commonLogFile If not None, an open file object to which output should be copied. """ probe = DebugProbeAggregator.get_probe_with_id(board_id) assert probe is not None session = Session(probe, **get_session_options()) board = session.board originalStdout = sys.stdout originalStderr = sys.stderr # Open board-specific output file. env_name = (("_" + os.environ['TOX_ENV_NAME']) if ('TOX_ENV_NAME' in os.environ) else '') name_info = "{}_{}_{}".format(env_name, board.name, n) log_filename = LOG_FILE_TEMPLATE.format(name_info) if os.path.exists(log_filename): os.remove(log_filename) log_file = open(log_filename, "a", buffering=1) # 1=Unbuffered # Setup logging. log_handler = RecordingLogHandler(None) log_handler.setFormatter(logging.Formatter(LOG_FORMAT)) root_logger = logging.getLogger() root_logger.setLevel(loglevel) root_logger.addHandler(log_handler) result_list = [] try: # Write board header to board log file, common log file, and console. print_board_header(log_file, board, n) if commonLogFile: print_board_header(commonLogFile, board, n, includeLeadingNewline=(n != 0)) print_board_header(originalStdout, board, n, logToConsole, includeLeadingNewline=(n != 0)) # Skip this board if we don't have a test binary. if board.test_binary is None: print("Skipping board %s due to missing test binary" % board.unique_id) return result_list # Run all tests on this board. for test in test_list: print("{} #{}: starting {}...".format(board.name, n, test.name), file=originalStdout) # Set a unique port for the GdbTest. if isinstance(test, GdbTest): test.n = n # Create a StringIO object to record the test's output, an IOTee to copy # output to both the log file and StringIO, then set the log handler and # stdio to write to the tee. testOutput = io.StringIO() tee = IOTee(log_file, testOutput) if logToConsole: tee.add(originalStdout) if commonLogFile is not None: tee.add(commonLogFile) log_handler.stream = tee sys.stdout = tee sys.stderr = tee test_start = time() result = test.run(board) test_stop = time() result.time = test_stop - test_start tee.flush() result.output = testOutput.getvalue() result_list.append(result) passFail = "PASSED" if result.passed else "FAILED" print("{} #{}: finished {}... {} ({:.3f} s)".format( board.name, n, test.name, passFail, result.time), file=originalStdout) finally: # Restore stdout/stderr in case we're running in the parent process (1 job). sys.stdout = originalStdout sys.stderr = originalStderr root_logger.removeHandler(log_handler) log_handler.flush() log_handler.close() return result_list
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 speed_test(board_id): with ConnectHelper.session_with_chosen_probe( board_id=board_id, **get_session_options()) as session: board = session.board target_type = board.target_type test_clock = 10000000 if target_type == "nrf51": # Override clock since 10MHz is too fast test_clock = 1000000 if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 memory_map = board.target.get_memory_map() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] rom_region = memory_map.get_boot_memory() ram_start = ram_region.start ram_size = ram_region.length rom_start = rom_region.start rom_size = rom_region.length target = board.target test_pass_count = 0 test_count = 0 result = SpeedTestResult() session.probe.set_clock(test_clock) print("\n\n------ TEST RAM READ / WRITE SPEED ------") test_addr = ram_start test_size = ram_size data = [randrange(1, 50) for x in range(test_size)] start = time() target.write_memory_block8(test_addr, data) target.flush() stop = time() diff = stop - start result.write_speed = test_size / diff print("Writing %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, result.write_speed)) start = time() block = target.read_memory_block8(test_addr, test_size) target.flush() stop = time() diff = stop - start result.read_speed = test_size / diff print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, result.read_speed)) error = False for i in range(len(block)): if (block[i] != data[i]): error = True print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i])) if error: print("TEST FAILED") else: print("TEST PASSED") test_pass_count += 1 test_count += 1 print("\n\n------ TEST ROM READ SPEED ------") test_addr = rom_start test_size = rom_size start = time() block = target.read_memory_block8(test_addr, test_size) target.flush() stop = time() diff = stop - start print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, test_size / diff)) print("TEST PASSED") test_pass_count += 1 test_count += 1 target.reset() result.passed = test_count == test_pass_count return result
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
from random import randrange import math import logging from pyocd.core.helpers import ConnectHelper from pyocd.flash.file_programmer import FileProgrammer from test_util import get_session_options parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) logging.basicConfig(level=logging.WARNING) print("\n\n------ Test attaching to locked board ------") for i in range(0, 10): with ConnectHelper.session_with_chosen_probe( **get_session_options()) as session: board = session.board flash = session.target.memory_map.get_boot_memory().flash # Erase and then reset - This locks Kinetis devices flash.init(flash.Operation.ERASE) flash.erase_all() flash.cleanup() board.target.reset() print("\n\n------ Testing Attaching to board ------") for i in range(0, 100): with ConnectHelper.session_with_chosen_probe( **get_session_options()) as session: board = session.board board.target.halt() sleep(0.01)
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 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 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 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 connect_test(board): board_id = board.unique_id binary_file = os.path.join(parentdir, 'binaries', board.test_binary) print("binary file: %s" % binary_file) test_pass_count = 0 test_count = 0 result = ConnectTestResult() # Install binary. live_session = ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) live_session.open() live_board = live_session.board memory_map = board.target.get_memory_map() rom_region = memory_map.get_boot_memory() rom_start = rom_region.start def test_connect(connect_mode, expected_state, resume): print("Connecting with connect_mode=%s" % connect_mode) live_session = ConnectHelper.session_with_chosen_probe( unique_id=board_id, init_board=False, connect_mode=connect_mode, resume_on_disconnect=resume, **get_session_options()) live_session.open() live_board = live_session.board print("Verifying target is", STATE_NAMES.get(expected_state, "unknown")) actualState = live_board.target.get_state() # Accept sleeping for running, as a hack to work around nRF52840-DK test binary. # TODO remove sleeping hack. if (actualState == expected_state) \ or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING): passed = 1 print("TEST PASSED") else: passed = 0 print("TEST FAILED (state={}, expected={})".format( STATE_NAMES.get(actualState, "unknown"), STATE_NAMES.get(expected_state, "unknown"))) print("Disconnecting with resume=%s" % resume) live_session.close() live_session = None return passed # TEST CASE COMBINATIONS test_cases = [ # <prev_exit> <connect_mode> <expected_state> <disconnect_resume> <exit_state> ConnectTestCase( RUNNING, 'attach', RUNNING, False, RUNNING ), ConnectTestCase( RUNNING, 'halt', HALTED, False, HALTED ), ConnectTestCase( HALTED, 'halt', HALTED, True, RUNNING ), ConnectTestCase( RUNNING, 'halt', HALTED, True, RUNNING ), ConnectTestCase( RUNNING, 'attach', RUNNING, True, RUNNING ), ConnectTestCase( RUNNING, 'halt', HALTED, False, HALTED ), ConnectTestCase( HALTED, 'attach', HALTED, False, HALTED ), ConnectTestCase( HALTED, 'halt', HALTED, False, HALTED ), ConnectTestCase( HALTED, 'attach', HALTED, True, RUNNING ), ConnectTestCase( RUNNING, 'attach', RUNNING, False, RUNNING ), ] print("\n\n----- TESTING CONNECT/DISCONNECT -----") print("Flashing new binary") FileProgrammer(live_session).program(binary_file, base_address=rom_start) live_board.target.reset() test_count += 1 print("Verifying target is running") if live_board.target.is_running() or live_board.target.get_state() == Target.TARGET_SLEEPING: test_pass_count += 1 print("TEST PASSED") else: print("TEST FAILED") print("Disconnecting with resume=True") live_session.options['resume_on_disconnect'] = True live_session.close() live_session = None # Leave running. # Run all the cases. for case in test_cases: test_count += 1 did_pass = test_connect( connect_mode=case.connect_mode, expected_state=case.expected_state, resume=case.disconnect_resume ) test_pass_count += did_pass case.passed=did_pass print("\n\nTest Summary:") print("\n{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( "#", "Prev Exit", "Connect Mode", "Expected", "Disconnect Resume", "Exit", "Passed")) for i, case in enumerate(test_cases): print("{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( i, STATE_NAMES[case.prev_exit_state], case.connect_mode, STATE_NAMES[case.expected_state], repr(case.disconnect_resume), STATE_NAMES[case.exit_state], "PASS" if case.passed else "FAIL")) print("\nPass count %i of %i tests" % (test_pass_count, test_count)) if test_pass_count == test_count: print("CONNECT TEST SCRIPT PASSED") else: print("CONNECT TEST SCRIPT FAILED") result.passed = (test_count == test_pass_count) return result
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 if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyOCD debug context test') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') parser.add_argument("-da", "--daparg", dest="daparg", nargs='+', help="Send setting to DAPAccess layer.") args = parser.parse_args() level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=level) DAPAccess.set_args(args.daparg) # Set to debug to print some of the decisions made while flashing session = ConnectHelper.session_with_chosen_probe(**get_session_options()) test = DebugContextTest() result = [test.run(session.board)]
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_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] rom_region = memory_map.get_boot_memory() target_type = board.target_type binary_file = os.path.join(parentdir, 'binaries', board.test_binary) if board_id is None: board_id = board.unique_id test_clock = 10000000 test_port = 3333 + n telnet_port = 4444 + n error_on_invalid_access = True # Hardware breakpoints are not supported above 0x20000000 on # CortexM devices ignore_hw_bkpt_result = 1 if ram_region.start >= 0x20000000 else 0 if target_type in ("nrf51", "nrf52", "nrf52840"): # Override clock since 10MHz is too fast test_clock = 1000000 # Reading invalid ram returns 0 or nrf51 error_on_invalid_access = False if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 # Program with initial test image board.flash.flash_binary(binary_file, rom_region.start) # Generate an elf from the binary test file. temp_test_elf_name = tempfile.mktemp('.elf') objcopyOutput = check_output([ OBJCOPY, "-v", "-I", "binary", "-O", "elf32-littlearm", "-B", "arm", "-S", "--set-start", "0x%x" % rom_region.start, "--change-addresses", "0x%x" % rom_region.start, binary_file, temp_test_elf_name ], stderr=STDOUT) print(to_str_safe(objcopyOutput)) # Need to escape backslashes on Windows. if sys.platform.startswith('win'): temp_test_elf_name = temp_test_elf_name.replace('\\', '\\\\') # Write out the test configuration test_params = { "test_port": test_port, "rom_start": rom_region.start, "rom_length": rom_region.length, "ram_start": ram_region.start, "ram_length": ram_region.length, "invalid_start": 0x3E000000, "invalid_length": 0x1000, "expect_error_on_invalid_access": error_on_invalid_access, "ignore_hw_bkpt_result": ignore_hw_bkpt_result, "test_elf": temp_test_elf_name, } test_param_filename = "test_params%d.txt" % n with open(test_param_filename, "w") as f: f.write(json.dumps(test_params)) # Run the test gdb = [PYTHON_GDB, "-ex", "set $testn=%d" % n, "--command=gdb_script.py"] output_filename = "output_%s_%d.txt" % (board.target_type, n) with open(output_filename, "w") as f: program = Popen(gdb, stdin=PIPE, stdout=f, stderr=STDOUT) args = [ '-p=%i' % test_port, "-f=%i" % test_clock, "-b=%s" % board_id, "-T=%i" % telnet_port, '-Oboard_config_file=test_boards.json' ] server = GDBServerTool() 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_clock = 10000000 if target_type == "nrf51": # Override clock since 10MHz is too fast test_clock = 1000000 if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 session.probe.set_clock(test_clock) memory_map = board.target.get_memory_map() boot_region = memory_map.get_boot_memory() boot_start_addr = boot_region.start boot_end_addr = boot_region.end boot_blocksize = boot_region.blocksize test_pass_count = 0 test_count = 0 result = FlashLoaderTestResult() binary_file_path = os.path.join(parentdir, 'binaries', board.test_binary) with open(binary_file_path, "rb") as f: data = list(bytearray(f.read())) data_length = len(data) print("\n------ Test Basic Load ------") loader = FlashLoader(session, chip_erase=False) loader.add_data(boot_start_addr, data) loader.commit() verify_data = target.read_memory_block8(boot_start_addr, data_length) if same(verify_data, data): print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Load Sector Erase ------") test_data = [0x55] * boot_blocksize addr = (boot_end_addr + 1) - (boot_blocksize * 2) loader = FlashLoader(session, chip_erase=False) loader.add_data(addr, test_data) loader.add_data(addr + boot_blocksize, test_data) loader.commit() verify_data = target.read_memory_block8(addr, boot_blocksize * 2) verify_data2 = target.read_memory_block8(boot_start_addr, data_length) if same(verify_data, test_data * 2) and same(verify_data2, data): print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Basic Sector Erase ------") eraser = FlashEraser(session, FlashEraser.Mode.SECTOR) eraser.erase(["0x%x+0x%x" % (addr, boot_blocksize)]) verify_data = target.read_memory_block8(addr, boot_blocksize) if target.memory_map.get_region_for_address(addr).is_erased(verify_data): print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Load Chip Erase ------") loader = FlashLoader(session, chip_erase=True) loader.add_data(boot_start_addr, data) loader.commit() verify_data = target.read_memory_block8(boot_start_addr, data_length) verify_data2 = target.read_memory_block8(addr, boot_blocksize * 2) if same(verify_data, data) and target.memory_map.get_region_for_address(addr).is_erased(verify_data2): print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Binary File Load ------") programmer = FileProgrammer(session) programmer.program(binary_file_path, format='bin', base_address=boot_start_addr) verify_data = target.read_memory_block8(boot_start_addr, data_length) if same(verify_data, data): print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n\nTest Summary:") print("Pass count %i of %i tests" % (test_pass_count, test_count)) if test_pass_count == test_count: print("FLASH TEST SCRIPT PASSED") else: print("FLASH TEST SCRIPT FAILED") target.reset() result.passed = test_count == test_pass_count return result
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 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 speed_test(board_id): with ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) as session: board = session.board target_type = board.target_type test_clock = 10000000 if target_type == "nrf51": # Override clock since 10MHz is too fast test_clock = 1000000 if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 memory_map = board.target.get_memory_map() ram_region = memory_map.get_first_region_of_type(MemoryType.RAM) rom_region = memory_map.get_boot_memory() ram_start = ram_region.start ram_size = ram_region.length rom_start = rom_region.start rom_size = rom_region.length target = board.target test_pass_count = 0 test_count = 0 result = SpeedTestResult() session.probe.set_clock(test_clock) print("\n\n------ TEST RAM READ / WRITE SPEED ------") test_addr = ram_start test_size = ram_size data = [randrange(1, 50) for x in range(test_size)] start = time() target.write_memory_block8(test_addr, data) target.flush() stop = time() diff = stop - start result.write_speed = test_size / diff print("Writing %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, result.write_speed)) start = time() block = target.read_memory_block8(test_addr, test_size) target.flush() stop = time() diff = stop - start result.read_speed = test_size / diff print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, result.read_speed)) error = False for i in range(len(block)): if (block[i] != data[i]): error = True print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i])) if error: print("TEST FAILED") else: print("TEST PASSED") test_pass_count += 1 test_count += 1 print("\n\n------ TEST ROM READ SPEED ------") test_addr = rom_start test_size = rom_size start = time() block = target.read_memory_block8(test_addr, test_size) target.flush() stop = time() diff = stop - start print("Reading %i byte took %.3f seconds: %.3f B/s" % (test_size, diff, test_size / diff)) print("TEST PASSED") test_pass_count += 1 test_count += 1 target.reset() result.passed = test_count == test_pass_count return result
def flash_test(board_id): with ConnectHelper.session_with_chosen_probe( board_id=board_id, **get_session_options()) as session: board = session.board target_type = board.target_type test_clock = 10000000 if target_type == "nrf51": # Override clock since 10MHz is too fast test_clock = 1000000 if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 memory_map = board.target.getMemoryMap() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] ram_start = ram_region.start ram_size = ram_region.length target = board.target flash = board.flash flash_info = flash.getFlashInfo() session.probe.set_clock(test_clock) test_pass_count = 0 test_count = 0 result = FlashTestResult() # Test each flash region separately. for rom_region in memory_map.getRegionsOfType('flash'): if not rom_region.isTestable: continue rom_start = rom_region.start rom_size = rom_region.length 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.setFlashAlgoDebug(True) print("\n------ Test Basic Page Erase ------") info = flash.flashBlock(addr, data, False, False, progress_cb=print_progress()) data_flashed = target.readBlockMemoryUnaligned8(addr, size) if same(data_flashed, data ) and info.program_type is FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Basic Chip Erase ------") info = flash.flashBlock(addr, data, False, True, progress_cb=print_progress()) data_flashed = target.readBlockMemoryUnaligned8(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.flashBlock(addr, data, True, False, progress_cb=print_progress()) data_flashed = target.readBlockMemoryUnaligned8(addr, size) if same(data_flashed, data ) and info.program_type is FlashBuilder.FLASH_PAGE_ERASE: print("TEST PASSED") test_pass_count += 1 else: print("TEST FAILED") test_count += 1 print("\n------ Test Smart Chip Erase ------") info = flash.flashBlock(addr, data, True, True, progress_cb=print_progress()) data_flashed = target.readBlockMemoryUnaligned8(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.setFlashAlgoDebug(False) print("\n------ Test Basic Page Erase (Entire region) ------") new_data = list(data) new_data.extend(unused * [0x77]) info = flash.flashBlock(addr, new_data, False, False, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_PAGE_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.flashBlock(addr, new_data, progress_cb=print_progress(), fast_verify=True) if info.program_type == FlashBuilder.FLASH_PAGE_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.getPageInfo(addr).size new_data = [0x55] * page_size * 2 info = flash.flashBlock(addr, new_data, progress_cb=print_progress()) data_flashed = target.readBlockMemoryUnaligned8( addr, len(new_data)) if same(data_flashed, new_data ) and info.program_type is FlashBuilder.FLASH_PAGE_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.getPageInfo(addr).size more_data = [0x33] * page_size * 2 addr = (rom_start + rom_size // 2) + 1 #cover multiple pages fb = flash.getFlashBuilder() fb.addData(rom_start, data) fb.addData(addr, more_data) fb.program(progress_cb=print_progress()) data_flashed = target.readBlockMemoryUnaligned8( rom_start, len(data)) data_flashed_more = target.readBlockMemoryUnaligned8( 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.getPageInfo(addr).size new_data = [0x33] * page_size fb = flash.getFlashBuilder() fb.addData(addr, new_data) try: fb.addData(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.getFlashBuilder() 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.flashBlock(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.flashBlock(rom_start, non_thumb_data) flash.flashBlock(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([0xff] * unused) # Pad with 0xFF info = flash.flashBlock(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([0x00] * unused) # Pad with 0x00 info = flash.flashBlock(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([0x00] * unused) # Pad with 0x00 info = flash.flashBlock(addr, new_data, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_PAGE_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([0x00] * size_same) # Pad 5/6 with 0x00 and 1/6 with 0xFF new_data.extend([0x55] * size_differ) info = flash.flashBlock(addr, new_data, progress_cb=print_progress()) if info.program_type == FlashBuilder.FLASH_PAGE_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_board(board_id, n, loglevel, logToConsole, commonLogFile): probe = DebugProbeAggregator.get_probe_with_id(board_id) assert probe is not None session = Session(probe, **get_session_options()) board = session.board originalStdout = sys.stdout originalStderr = sys.stderr # Open board-specific output file. env_name = (("_" + os.environ['TOX_ENV_NAME']) if ('TOX_ENV_NAME' in os.environ) else '') name_info = "{}_{}_{}".format(env_name, board.name, n) log_filename = LOG_FILE_TEMPLATE.format(name_info) if os.path.exists(log_filename): os.remove(log_filename) log_file = open(log_filename, "a", buffering=1) # 1=Unbuffered # Setup logging. log_handler = RecordingLogHandler(None) log_handler.setFormatter(logging.Formatter(LOG_FORMAT)) root_logger = logging.getLogger() root_logger.setLevel(loglevel) root_logger.addHandler(log_handler) result_list = [] try: # Write board header to board log file, common log file, and console. print_board_header(log_file, board, n) if commonLogFile: print_board_header(commonLogFile, board, n, includeLeadingNewline=(n != 0)) print_board_header(originalStdout, board, n, logToConsole, includeLeadingNewline=(n != 0)) # Skip this board if we don't have a test binary. if board.test_binary is None: print("Skipping board %s due to missing test binary" % board.unique_id) return result_list # Run all tests on this board. for test in test_list: print("{} #{}: starting {}...".format(board.name, n, test.name), file=originalStdout) # Set a unique port for the GdbTest. if isinstance(test, GdbTest): test.n = n # Create a StringIO object to record the test's output, an IOTee to copy # output to both the log file and StringIO, then set the log handler and # stdio to write to the tee. testOutput = io.StringIO() tee = IOTee(log_file, testOutput) if logToConsole: tee.add(originalStdout) if commonLogFile is not None: tee.add(commonLogFile) log_handler.stream = tee sys.stdout = tee sys.stderr = tee test_start = time() result = test.run(board) test_stop = time() result.time = test_stop - test_start tee.flush() result.output = testOutput.getvalue() result_list.append(result) passFail = "PASSED" if result.passed else "FAILED" print("{} #{}: finished {}... {} ({:.3f} s)".format( board.name, n, test.name, passFail, result.time), file=originalStdout) finally: # Restore stdout/stderr in case we're running in the parent process (1 job). sys.stdout = originalStdout sys.stderr = originalStderr root_logger.removeHandler(log_handler) log_handler.flush() log_handler.close() return result_list
def connect_test(board): board_id = board.unique_id binary_file = os.path.join(parentdir, 'binaries', board.test_binary) print("binary file: %s" % binary_file) test_pass_count = 0 test_count = 0 result = ConnectTestResult() # Install binary. live_session = ConnectHelper.session_with_chosen_probe(board_id=board_id, **get_session_options()) live_board = live_session.board memory_map = board.target.get_memory_map() rom_region = memory_map.get_boot_memory() rom_start = rom_region.start def test_connect(halt_on_connect, expected_state, resume): print("Connecting with halt_on_connect=%s" % halt_on_connect) live_session = ConnectHelper.session_with_chosen_probe( board_id=board_id, init_board=False, halt_on_connect=halt_on_connect, resume_on_disconnect=resume, **get_session_options()) live_session.open() live_board = live_session.board print("Verifying target is", STATE_NAMES.get(expected_state, "unknown")) actualState = live_board.target.get_state() # Accept sleeping for running, as a hack to work around nRF52840-DK test binary. # TODO remove sleeping hack. if (actualState == expected_state) \ or (expected_state == RUNNING and actualState == Target.TARGET_SLEEPING): passed = 1 print("TEST PASSED") else: passed = 0 print("TEST FAILED (state={}, expected={})".format( STATE_NAMES.get(actualState, "unknown"), STATE_NAMES.get(expected_state, "unknown"))) print("Disconnecting with resume=%s" % resume) live_session.close() live_session = None return passed # TEST CASE COMBINATIONS test_cases = [ # <prev_exit> <halt_on_connect> <expected_state> <disconnect_resume> <exit_state> ConnectTestCase( RUNNING, False, RUNNING, False, RUNNING ), ConnectTestCase( RUNNING, True, HALTED, False, HALTED ), ConnectTestCase( HALTED, True, HALTED, True, RUNNING ), ConnectTestCase( RUNNING, True, HALTED, True, RUNNING ), ConnectTestCase( RUNNING, False, RUNNING, True, RUNNING ), ConnectTestCase( RUNNING, True, HALTED, False, HALTED ), ConnectTestCase( HALTED, False, HALTED, False, HALTED ), ConnectTestCase( HALTED, True, HALTED, False, HALTED ), ConnectTestCase( HALTED, False, HALTED, True, RUNNING ), ConnectTestCase( RUNNING, False, RUNNING, False, RUNNING ), ] print("\n\n----- TESTING CONNECT/DISCONNECT -----") print("Flashing new binary") FileProgrammer(live_session).program(binary_file, base_address=rom_start) live_board.target.reset() test_count += 1 print("Verifying target is running") if live_board.target.is_running(): test_pass_count += 1 print("TEST PASSED") else: print("TEST FAILED") print("Disconnecting with resume=True") live_session.options['resume_on_disconnect'] = True live_session.close() live_session = None # Leave running. # Run all the cases. for case in test_cases: test_count += 1 did_pass = test_connect( halt_on_connect=case.halt_on_connect, expected_state=case.expected_state, resume=case.disconnect_resume ) test_pass_count += did_pass case.passed=did_pass print("\n\nTest Summary:") print("\n{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( "#", "Prev Exit", "Halt on Connect", "Expected", "Disconnect Resume", "Exit", "Passed")) for i, case in enumerate(test_cases): print("{:<4}{:<12}{:<19}{:<12}{:<21}{:<11}{:<10}".format( i, STATE_NAMES[case.prev_exit_state], repr(case.halt_on_connect), STATE_NAMES[case.expected_state], repr(case.disconnect_resume), STATE_NAMES[case.exit_state], "PASS" if case.passed else "FAIL")) print("\nPass count %i of %i tests" % (test_pass_count, test_count)) if test_pass_count == test_count: print("CONNECT TEST SCRIPT PASSED") else: print("CONNECT TEST SCRIPT FAILED") result.passed = (test_count == test_pass_count) return result
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( 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 basic_test(board_id, file): with ConnectHelper.session_with_chosen_probe(unique_id=board_id, **get_session_options()) as session: board = session.board addr = 0 size = 0 f = None binary_file = "l1_" if file is None: binary_file = os.path.join(parentdir, 'binaries', board.test_binary) else: binary_file = file print("binary file: %s" % binary_file) memory_map = board.target.get_memory_map() ram_region = memory_map.get_first_region_of_type(MemoryType.RAM) rom_region = memory_map.get_boot_memory() addr = ram_region.start size = 0x502 addr_bin = rom_region.start addr_flash = rom_region.start + rom_region.length // 2 target = board.target flash = rom_region.flash print("\n\n------ GET Unique ID ------") print("Unique ID: %s" % board.unique_id) print("\n\n------ TEST READ / WRITE CORE REGISTER ------") pc = target.read_core_register('pc') print("initial pc: 0x%X" % target.read_core_register('pc')) # write in pc dummy value target.write_core_register('pc', 0x3D82) print("now pc: 0x%X" % target.read_core_register('pc')) # write initial pc value target.write_core_register('pc', pc) print("initial pc value rewritten: 0x%X" % target.read_core_register('pc')) msp = target.read_core_register('msp') psp = target.read_core_register('psp') print("MSP = 0x%08x; PSP = 0x%08x" % (msp, psp)) control = target.read_core_register('control') faultmask = target.read_core_register('faultmask') basepri = target.read_core_register('basepri') primask = target.read_core_register('primask') print("CONTROL = 0x%02x; FAULTMASK = 0x%02x; BASEPRI = 0x%02x; PRIMASK = 0x%02x" % (control, faultmask, basepri, primask)) target.write_core_register('primask', 1) newPrimask = target.read_core_register('primask') print("New PRIMASK = 0x%02x" % newPrimask) target.write_core_register('primask', primask) newPrimask = target.read_core_register('primask') print("Restored PRIMASK = 0x%02x" % newPrimask) if target.has_fpu: s0 = target.read_core_register('s0') print("S0 = %g (0x%08x)" % (s0, float32_to_u32(s0))) target.write_core_register('s0', math.pi) newS0 = target.read_core_register('s0') print("New S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) target.write_core_register('s0', s0) newS0 = target.read_core_register('s0') print("Restored S0 = %g (0x%08x)" % (newS0, float32_to_u32(newS0))) print("\n\n------ TEST HALT / RESUME ------") print("resume") target.resume() sleep(0.2) print("halt") target.halt() print("HALT: pc: 0x%X" % target.read_core_register('pc')) sleep(0.2) print("\n\n------ TEST STEP ------") print("reset and halt") target.reset_stop_on_reset() currentPC = target.read_core_register('pc') print("HALT: pc: 0x%X" % currentPC) sleep(0.2) for i in range(4): print("step") target.step() newPC = target.read_core_register('pc') print("STEP: pc: 0x%X" % newPC) currentPC = newPC sleep(0.2) print("\n\n------ TEST READ / WRITE MEMORY ------") target.halt() print("READ32/WRITE32") val = randrange(0, 0xffffffff) print("write32 0x%X at 0x%X" % (val, addr)) target.write_memory(addr, val) res = target.read_memory(addr) print("read32 at 0x%X: 0x%X" % (addr, res)) if res != val: print("ERROR in READ/WRITE 32") print("\nREAD16/WRITE16") val = randrange(0, 0xffff) print("write16 0x%X at 0x%X" % (val, addr + 2)) target.write_memory(addr + 2, val, 16) res = target.read_memory(addr + 2, 16) print("read16 at 0x%X: 0x%X" % (addr + 2, res)) if res != val: print("ERROR in READ/WRITE 16") print("\nREAD8/WRITE8") val = randrange(0, 0xff) print("write8 0x%X at 0x%X" % (val, addr + 1)) target.write_memory(addr + 1, val, 8) res = target.read_memory(addr + 1, 8) print("read8 at 0x%X: 0x%X" % (addr + 1, res)) if res != val: print("ERROR in READ/WRITE 8") print("\n\n------ TEST READ / WRITE MEMORY BLOCK ------") data = [randrange(1, 50) for x in range(size)] target.write_memory_block8(addr, data) block = target.read_memory_block8(addr, size) error = False for i in range(len(block)): if (block[i] != data[i]): error = True print("ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i])) if error: print("TEST FAILED") else: print("TEST PASSED") print("\n\n------ TEST RESET ------") target.reset() sleep(0.1) target.halt() for i in range(5): target.step() print("pc: 0x%X" % target.read_core_register('pc')) print("\n\n------ TEST PROGRAM/ERASE PAGE ------") # Fill 3 pages with 0x55 page_size = flash.get_page_info(addr_flash).size fill = [0x55] * page_size for i in range(0, 3): address = addr_flash + page_size * i # Test only supports a location with 3 aligned # pages of the same size current_page_size = flash.get_page_info(addr_flash).size assert page_size == current_page_size assert address % current_page_size == 0 flash.init(flash.Operation.ERASE) flash.erase_page(address) flash.uninit() flash.init(flash.Operation.PROGRAM) flash.program_page(address, fill) flash.uninit() # Erase the middle page flash.init(flash.Operation.ERASE) flash.erase_page(addr_flash + page_size) flash.cleanup() # Verify the 1st and 3rd page were not erased, and that the 2nd page is fully erased data = target.read_memory_block8(addr_flash, page_size * 3) expected = fill + [0xFF] * page_size + fill if data == expected: print("TEST PASSED") else: print("TEST FAILED") print("\n\n----- FLASH NEW BINARY -----") FileProgrammer(session).program(binary_file, base_address=addr_bin) target.reset()
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