Esempio n. 1
0
 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'}
Esempio n. 2
0
 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
     }
Esempio n. 3
0
 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
     }
Esempio n. 4
0
 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}
Esempio n. 5
0
 def test_unknown_option(self):
     assert convert_session_options(['dumkopf']) == {}
Esempio n. 6
0
 def test_empty(self):
     assert convert_session_options([]) == {}
Esempio n. 7
0
    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