def test_str(self): # Ignore with no value assert convert_session_options(['test_binary']) == {} # Ignore with no- prefix assert convert_session_options(['no-test_binary']) == {} # Valid assert convert_session_options(['test_binary=abc']) == {'test_binary': 'abc'}
def test_noncasesense(self): # Test separate paths for with and without a value. assert convert_session_options(['AUTO_Unlock']) == { 'auto_unlock': True } assert convert_session_options(['AUTO_Unlock=0']) == { 'auto_unlock': False }
def test_bool(self): assert convert_session_options(['auto_unlock']) == { 'auto_unlock': True } assert convert_session_options(['no-auto_unlock']) == { 'auto_unlock': False } assert convert_session_options(['auto_unlock=1']) == { 'auto_unlock': True } assert convert_session_options(['auto_unlock=true']) == { 'auto_unlock': True } assert convert_session_options(['auto_unlock=yes']) == { 'auto_unlock': True } assert convert_session_options(['auto_unlock=on']) == { 'auto_unlock': True } assert convert_session_options(['auto_unlock=0']) == { 'auto_unlock': False } assert convert_session_options(['auto_unlock=false']) == { 'auto_unlock': False } assert convert_session_options(['auto_unlock=anything-goes-here']) == { 'auto_unlock': False }
def test_int(self): # Non-bool with no value is ignored (and logged). assert convert_session_options(['frequency']) == {} # Invalid int value is ignored and logged assert convert_session_options(['frequency=abc']) == {} # Ignore with no- prefix assert convert_session_options(['no-frequency']) == {} # Valid int assert convert_session_options(['frequency=1000']) == {'frequency': 1000} # Valid hex int assert convert_session_options(['frequency=0x40']) == {'frequency': 64}
def test_unknown_option(self): assert convert_session_options(['dumkopf']) == {}
def test_empty(self): assert convert_session_options([]) == {}
def invoke(self) -> int: session = None kb = None try: session = ConnectHelper.session_with_chosen_probe( project_dir=self._args.project_dir, config_file=self._args.config, user_script=self._args.script, no_config=self._args.no_config, pack=self._args.pack, unique_id=self._args.unique_id, target_override=self._args.target_override, frequency=self._args.frequency, blocking=(not self._args.no_wait), connect_mode=self._args.connect_mode, options=convert_session_options(self._args.options)) if session is None: LOG.error("No target device available") return 1 with session: target: SoCTarget = session.board.target memory_map: MemoryMap = target.get_memory_map() ram_region: MemoryRegion = memory_map.get_default_region_of_type(MemoryType.RAM) if self._args.address is None or self._args.size is None: rtt_range_start = ram_region.start rtt_range_size = ram_region.length elif ram_region.start <= self._args.address and self._args.size <= ram_region.length: rtt_range_start = self._args.address rtt_range_size = self._args.size LOG.info(f"RTT control block search range [{rtt_range_start:#08x}, {rtt_range_size:#08x}]") data = target.read_memory_block8(rtt_range_start, rtt_range_size) pos = bytes(data).find(b"SEGGER RTT") if pos == -1: LOG.error("No RTT control block available") return 1 rtt_cb_addr = rtt_range_start + pos rtt_cb = SEGGER_RTT_CB.from_buffer(bytearray(data[pos:])) up_addr = rtt_cb_addr + SEGGER_RTT_CB.aUp.offset down_addr = up_addr + sizeof(SEGGER_RTT_BUFFER_UP) * rtt_cb.MaxNumUpBuffers LOG.info(f"_SEGGER_RTT @ {rtt_cb_addr:#08x} with {rtt_cb.MaxNumUpBuffers} aUp and {rtt_cb.MaxNumDownBuffers} aDown") # some targets might need this here #target.reset_and_halt() target.resume() # set up terminal input kb = KBHit() # byte array to send via RTT cmd = bytes() while True: # read data from up buffers (target -> host) data = target.read_memory_block8(up_addr, sizeof(SEGGER_RTT_BUFFER_UP)) up = SEGGER_RTT_BUFFER_UP.from_buffer(bytearray(data)) if up.WrOff > up.RdOff: """ |oooooo|xxxxxxxxxxxx|oooooo| 0 rdOff WrOff SizeOfBuffer """ data = target.read_memory_block8(up.pBuffer + up.RdOff, up.WrOff - up.RdOff) target.write_memory(up_addr + SEGGER_RTT_BUFFER_UP.RdOff.offset, up.WrOff) print(bytes(data).decode(), end="", flush=True) elif up.WrOff < up.RdOff: """ |xxxxxx|oooooooooooo|xxxxxx| 0 WrOff RdOff SizeOfBuffer """ data = target.read_memory_block8(up.pBuffer + up.RdOff, up.SizeOfBuffer - up.RdOff) data += target.read_memory_block8(up.pBuffer, up.WrOff) target.write_memory(up_addr + SEGGER_RTT_BUFFER_UP.RdOff.offset, up.WrOff) print(bytes(data).decode(), end="", flush=True) else: # up buffer is empty # try and fetch character if not kb.kbhit(): continue c = kb.getch() if ord(c) == 8 or ord(c) == 127: # process backspace print("\b \b", end="", flush=True) cmd = cmd[:-1] continue elif ord(c) == 27: # process ESC break else: print(c, end="", flush=True) cmd += c.encode() # keep accumulating until we see CR or LF if not c in "\r\n": continue # SEND TO TARGET data = target.read_memory_block8(down_addr, sizeof(SEGGER_RTT_BUFFER_DOWN)) down = SEGGER_RTT_BUFFER_DOWN.from_buffer(bytearray(data)) # compute free space in down buffer if down.WrOff >= down.RdOff: num_avail = down.SizeOfBuffer - (down.WrOff - down.RdOff) else: num_avail = down.RdOff - down.WrOff - 1 # wait until there's space for the entire string in the RTT down buffer if (num_avail < len(cmd)): continue # write data to down buffer (host -> target), char by char for i in range(len(cmd)): target.write_memory_block8(down.pBuffer + down.WrOff, cmd[i:i+1]) down.WrOff += 1 if down.WrOff == down.SizeOfBuffer: down.WrOff = 0; target.write_memory(down_addr + SEGGER_RTT_BUFFER_DOWN.WrOff.offset, down.WrOff) # clear it and start anew cmd = bytes() except KeyboardInterrupt: pass finally: if session: session.close() if kb: kb.set_normal_term() return 0