def validate_boards(data): did_pass = True print('boards', end=' ') p = 'boards' in data and type(data['boards']) is list if p: b = data['boards'] if p: print("PASSED") else: did_pass = False print("FAILED") # Only if we're running this test standalone do we want to compare against the list # of boards returned by ConnectHelper.get_sessions_for_all_connected_probes(). When running in the full # automated test suite, there could be other test jobs running concurrently that have # exclusive access to the boards they are testing. Thus, those boards will not show up # in the return list and this test will fail. if testing_standalone: try: all_sessions = ConnectHelper.get_sessions_for_all_connected_probes( blocking=False) all_mbeds = [x.board for x in all_sessions] p = len(all_mbeds) == len(b) matching_boards = 0 if p: for mbed in all_mbeds: for brd in b: if mbed.unique_id == brd['unique_id']: matching_boards += 1 p = 'info' in brd and 'target' in brd and 'board_name' in brd if not p: break if not p: break p = matching_boards == len(all_mbeds) if p: print("PASSED") else: did_pass = False print("FAILED") except Exception as e: print("FAILED") traceback.print_exc(file=sys.stdout) did_pass = False else: # Check for required keys in all board info dicts. p = True for brd in b: p = ('unique_id' in brd and 'info' in brd and 'target' in brd and 'board_name' in brd) if not p: break if p: print("PASSED") else: did_pass = False print("FAILED") return did_pass
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.getState() # 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 search_and_lock(board_id): """Repeatedly lock a board with the given ID""" for _ in range(0, 20): device = DAPAccess.get_device(board_id) device.open() device.close() with ConnectHelper.session_with_chosen_probe(board_id=board_id): pass
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
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_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.getMemoryMap() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] rom_region = memory_map.getBootMemory() 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.flashBinary(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 main(): parser = argparse.ArgumentParser(description='pyOCD automated testing') parser.add_argument('-d', '--debug', action="store_true", help='Enable debug logging') parser.add_argument('-q', '--quiet', action="store_true", help='Hide test progress for 1 job') parser.add_argument( '-j', '--jobs', action="store", default=1, type=int, metavar="JOBS", help='Set number of concurrent board tests (default is 1)') parser.add_argument( '-b', '--board', action="append", metavar="ID", help= "Limit testing to boards with specified unique IDs. Multiple boards can be listed." ) args = parser.parse_args() # Force jobs to 1 when running under CI until concurrency issues with enumerating boards are # solved. Specifically, the connect test has intermittently failed to open boards on Linux and # Win7. This is only done under CI, and in this script, to make testing concurrent runs easy. if 'CI_TEST' in os.environ: args.jobs = 1 # Disable multiple jobs on macOS prior to Python 3.4. By default, multiprocessing uses # fork() on Unix, which doesn't work on the Mac because CoreFoundation requires exec() # to be used in order to init correctly (CoreFoundation is used in hidapi). Only on Python # version 3.4+ is the multiprocessing.set_start_method() API available that lets us # switch to the 'spawn' method, i.e. exec(). if args.jobs > 1 and sys.platform.startswith( 'darwin') and sys.version_info[0:2] < (3, 4): print( "WARNING: Cannot support multiple jobs on macOS prior to Python 3.4. Forcing 1 job." ) args.jobs = 1 # Setup logging based on concurrency and quiet option. level = logging.DEBUG if args.debug else logging.INFO if args.jobs == 1 and not args.quiet: # Create common log file. if os.path.exists(LOG_FILE): os.remove(LOG_FILE) logToConsole = True commonLogFile = open(LOG_FILE, "a") else: logToConsole = False commonLogFile = None board_list = [] result_list = [] # Put together list of boards to test board_list = ConnectHelper.get_all_connected_probes(blocking=False) board_id_list = sorted(b.unique_id for b in board_list) # Filter boards. if args.board: board_id_list = [ b for b in board_id_list if any(c for c in args.board if c.lower() in b.lower()) ] # If only 1 job was requested, don't bother spawning processes. start = time() if args.jobs == 1: for n, board_id in enumerate(board_id_list): result_list += test_board(board_id, n, level, logToConsole, commonLogFile) else: # Create a pool of processes to run tests. try: pool = mp.Pool(args.jobs) # Issue board test job to process pool. async_results = [ pool.apply_async( test_board, (board_id, n, level, logToConsole, commonLogFile)) for n, board_id in enumerate(board_id_list) ] # Gather results. for r in async_results: result_list += r.get(timeout=JOB_TIMEOUT) finally: pool.close() pool.join() stop = time() test_time = (stop - start) print_summary(test_list, result_list, test_time) with open(SUMMARY_FILE, "w") as output_file: print_summary(test_list, result_list, test_time, output_file) generate_xml_results(result_list) exit_val = 0 if Test.all_tests_pass(result_list) else -1 exit(exit_val)
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
from random import randrange import math parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parentdir) import pyOCD from pyOCD.core.helpers import ConnectHelper import logging 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.eraseAll() 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 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.getMemoryMap() rom_region = memory_map.getBootMemory() 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.getState() # 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") live_board.flash.flashBinary(binary_file, rom_start) live_board.target.reset() test_count += 1 print("Verifying target is running") if live_board.target.isRunning(): 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 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.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 size = 0x502 addr_bin = rom_region.start addr_flash = rom_region.start + rom_region.length // 2 target = board.target flash = board.flash print("\n\n------ GET Unique ID ------") print("Unique ID: %s" % board.unique_id) print("\n\n------ TEST READ / WRITE CORE REGISTER ------") pc = target.readCoreRegister('pc') print("initial pc: 0x%X" % target.readCoreRegister('pc')) # write in pc dummy value target.writeCoreRegister('pc', 0x3D82) print("now pc: 0x%X" % target.readCoreRegister('pc')) # write initial pc value target.writeCoreRegister('pc', pc) print("initial pc value rewritten: 0x%X" % target.readCoreRegister('pc')) msp = target.readCoreRegister('msp') psp = target.readCoreRegister('psp') print("MSP = 0x%08x; PSP = 0x%08x" % (msp, psp)) control = target.readCoreRegister('control') faultmask = target.readCoreRegister('faultmask') basepri = target.readCoreRegister('basepri') primask = target.readCoreRegister('primask') print( "CONTROL = 0x%02x; FAULTMASK = 0x%02x; BASEPRI = 0x%02x; PRIMASK = 0x%02x" % (control, faultmask, basepri, primask)) target.writeCoreRegister('primask', 1) newPrimask = target.readCoreRegister('primask') print("New PRIMASK = 0x%02x" % newPrimask) target.writeCoreRegister('primask', primask) newPrimask = target.readCoreRegister('primask') print("Restored PRIMASK = 0x%02x" % newPrimask) if target.has_fpu: s0 = target.readCoreRegister('s0') print("S0 = %g (0x%08x)" % (s0, float32beToU32be(s0))) target.writeCoreRegister('s0', math.pi) newS0 = target.readCoreRegister('s0') print("New S0 = %g (0x%08x)" % (newS0, float32beToU32be(newS0))) target.writeCoreRegister('s0', s0) newS0 = target.readCoreRegister('s0') print("Restored S0 = %g (0x%08x)" % (newS0, float32beToU32be(newS0))) print("\n\n------ TEST HALT / RESUME ------") print("resume") target.resume() sleep(0.2) print("halt") target.halt() print("HALT: pc: 0x%X" % target.readCoreRegister('pc')) sleep(0.2) print("\n\n------ TEST STEP ------") print("reset and halt") target.resetStopOnReset() currentPC = target.readCoreRegister('pc') print("HALT: pc: 0x%X" % currentPC) sleep(0.2) for i in range(4): print("step") target.step() newPC = target.readCoreRegister('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.writeMemory(addr, val) res = target.readMemory(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.writeMemory(addr + 2, val, 16) res = target.readMemory(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.writeMemory(addr + 1, val, 8) res = target.readMemory(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.writeBlockMemoryUnaligned8(addr, data) block = target.readBlockMemoryUnaligned8(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.readCoreRegister('pc')) print("\n\n------ TEST PROGRAM/ERASE PAGE ------") # Fill 3 pages with 0x55 page_size = flash.getPageInfo(addr_flash).size fill = [0x55] * page_size flash.init() 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.getPageInfo(addr_flash).size assert page_size == current_page_size assert address % current_page_size == 0 flash.erasePage(address) flash.programPage(address, fill) # Erase the middle page flash.erasePage(addr_flash + page_size) # Verify the 1st and 3rd page were not erased, and that the 2nd page is fully erased data = target.readBlockMemoryUnaligned8(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 -----") flash.flashBinary(binary_file, 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 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] rom_region = memory_map.getBootMemory() 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.writeBlockMemoryUnaligned8(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.readBlockMemoryUnaligned8(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.readBlockMemoryUnaligned8(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