Skip to content

Pytest embedded jtag

pytest_embedded_jtag.gdb

Gdb

Bases: DuplicateStdoutPopen

Source code in pytest_embedded_jtag/gdb.py
class Gdb(DuplicateStdoutPopen):
    GDB_PROG_PATH = 'xtensa-esp32-elf-gdb'
    GDB_DEFAULT_ARGS = '--nx --quiet --interpreter=mi2'

    def __init__(self, gdb_prog_path: Optional[str] = None, gdb_cli_args: Optional[str] = None, **kwargs):
        """
        Args:
            gdb_prog_path: gdb program path
            gdb_cli_args: gdb cli arguments
        """
        gdb_prog_path = gdb_prog_path or self.GDB_PROG_PATH
        gdb_cli_args = gdb_cli_args or self.GDB_DEFAULT_ARGS

        cmd = f'{gdb_prog_path} {gdb_cli_args}'

        super().__init__(cmd, shell=True, **kwargs)

    def interpreter_exec_console(self, cmd):
        """
        GDB/MI commands -interpreter-exec console [cmd]
        """
        self.send(f'-interpreter-exec console "{cmd}"')

    def gdb_set(self, *args):
        """
        GDB/MI commands `-gdb-set ...`
        """
        self.send(f'-gdb-set {" ".join(args)}')

    def gdb_exit(self):
        """
        GDB/MI commands `-gdb-exit`
        """
        self.send('-gdb-exit')

    def file_exec_and_symbols(self, filepath: str):
        """
        GDB/MI commands `-file-exec-and-symbols [filepath]`
        """
        self.send(f'-file-exec-and-symbols "{filepath}"')

    def break_insert(self, location):
        """
        GDB/MI commands `-break-insert [location]`
        """
        self.send(f'-break-insert {location}')

    def exec_continue_all(self):
        """
        GDB/MI commands `-exec-continue --all`
        """
        self.send('-exec-continue --all')

__init__(gdb_prog_path=None, gdb_cli_args=None, **kwargs)

Parameters:

Name Type Description Default
gdb_prog_path Optional[str]

gdb program path

None
gdb_cli_args Optional[str]

gdb cli arguments

None
Source code in pytest_embedded_jtag/gdb.py
def __init__(self, gdb_prog_path: Optional[str] = None, gdb_cli_args: Optional[str] = None, **kwargs):
    """
    Args:
        gdb_prog_path: gdb program path
        gdb_cli_args: gdb cli arguments
    """
    gdb_prog_path = gdb_prog_path or self.GDB_PROG_PATH
    gdb_cli_args = gdb_cli_args or self.GDB_DEFAULT_ARGS

    cmd = f'{gdb_prog_path} {gdb_cli_args}'

    super().__init__(cmd, shell=True, **kwargs)

interpreter_exec_console(cmd)

GDB/MI commands -interpreter-exec console [cmd]

Source code in pytest_embedded_jtag/gdb.py
def interpreter_exec_console(self, cmd):
    """
    GDB/MI commands -interpreter-exec console [cmd]
    """
    self.send(f'-interpreter-exec console "{cmd}"')

gdb_set(*args)

GDB/MI commands -gdb-set ...

Source code in pytest_embedded_jtag/gdb.py
def gdb_set(self, *args):
    """
    GDB/MI commands `-gdb-set ...`
    """
    self.send(f'-gdb-set {" ".join(args)}')

gdb_exit()

GDB/MI commands -gdb-exit

Source code in pytest_embedded_jtag/gdb.py
def gdb_exit(self):
    """
    GDB/MI commands `-gdb-exit`
    """
    self.send('-gdb-exit')

file_exec_and_symbols(filepath)

GDB/MI commands -file-exec-and-symbols [filepath]

Source code in pytest_embedded_jtag/gdb.py
def file_exec_and_symbols(self, filepath: str):
    """
    GDB/MI commands `-file-exec-and-symbols [filepath]`
    """
    self.send(f'-file-exec-and-symbols "{filepath}"')

break_insert(location)

GDB/MI commands -break-insert [location]

Source code in pytest_embedded_jtag/gdb.py
def break_insert(self, location):
    """
    GDB/MI commands `-break-insert [location]`
    """
    self.send(f'-break-insert {location}')

exec_continue_all()

GDB/MI commands -exec-continue --all

Source code in pytest_embedded_jtag/gdb.py
def exec_continue_all(self):
    """
    GDB/MI commands `-exec-continue --all`
    """
    self.send('-exec-continue --all')

pytest_embedded_jtag.openocd

OpenOcd

Bases: DuplicateStdoutPopen

Class to communicate to OpenOCD

Source code in pytest_embedded_jtag/openocd.py
class OpenOcd(DuplicateStdoutPopen):
    """
    Class to communicate to OpenOCD
    """

    OPENOCD_PROG_PATH = 'openocd'
    OPENOCD_DEFAULT_ARGS = '-f board/esp32-wrover-kit-3.3v.cfg -d2'

    TELNET_HOST = '127.0.0.1'
    TELNET_PORT = 4444

    def __init__(self, openocd_prog_path: Optional[str] = None, openocd_cli_args: Optional[str] = None, **kwargs):
        """
        Args:
            openocd_prog_path: openocd program path
            openocd_cli_args: openocd cli arguments
        """
        openocd_prog_path = openocd_prog_path or os.getenv('OPENOCD_BIN', self.OPENOCD_PROG_PATH)
        openocd_cli_args = openocd_cli_args or self.OPENOCD_DEFAULT_ARGS

        openocd_scripts_path = os.getenv('OPENOCD_SCRIPTS')
        if openocd_scripts_path:
            openocd_cli_args += f' -s {openocd_scripts_path}'

        cmd = f'{openocd_prog_path} {openocd_cli_args}'
        logging.info(cmd)

        super().__init__(cmd, shell=True, **kwargs)

__init__(openocd_prog_path=None, openocd_cli_args=None, **kwargs)

Parameters:

Name Type Description Default
openocd_prog_path Optional[str]

openocd program path

None
openocd_cli_args Optional[str]

openocd cli arguments

None
Source code in pytest_embedded_jtag/openocd.py
def __init__(self, openocd_prog_path: Optional[str] = None, openocd_cli_args: Optional[str] = None, **kwargs):
    """
    Args:
        openocd_prog_path: openocd program path
        openocd_cli_args: openocd cli arguments
    """
    openocd_prog_path = openocd_prog_path or os.getenv('OPENOCD_BIN', self.OPENOCD_PROG_PATH)
    openocd_cli_args = openocd_cli_args or self.OPENOCD_DEFAULT_ARGS

    openocd_scripts_path = os.getenv('OPENOCD_SCRIPTS')
    if openocd_scripts_path:
        openocd_cli_args += f' -s {openocd_scripts_path}'

    cmd = f'{openocd_prog_path} {openocd_cli_args}'
    logging.info(cmd)

    super().__init__(cmd, shell=True, **kwargs)

pytest_embedded_jtag.dut

JtagDut

Bases: SerialDut

JTAG DUT class

Attributes:

Name Type Description
telnet telnetlib.Telnet

telnet server instance

Source code in pytest_embedded_jtag/dut.py
class JtagDut(SerialDut):
    """
    JTAG DUT class

    Attributes:
        telnet (telnetlib.Telnet): telnet server instance
    """

    def __init__(
        self,
        pexpect_proc: PexpectProcess,
        app: App,
        serial: Serial,
        openocd: OpenOcd,
        gdb: Gdb,
        **kwargs,
    ) -> None:
        """
        Args:
            pexpect_proc: `PexpectProcess` instance
            app: `App` instance
            serial: `Serial` instance
            openocd: `OpenOcd` instance
            gdb: `Gdb` instance
        """
        super().__init__(pexpect_proc, app, serial, **kwargs)
        self.openocd = openocd
        self.gdb = gdb

        self.openocd.create_forward_io_thread(self.pexpect_proc)
        self.gdb.create_forward_io_thread(self.pexpect_proc)

        sleep(1)  # make sure openocd already opened telnet port
        self.telnet = telnetlib.Telnet(self.openocd.TELNET_HOST, self.openocd.TELNET_PORT, 5)
        self.telnet.send = self.telnet_send  # bind send method

    def telnet_send(self, s: AnyStr) -> None:
        """
        Send commands through telnet port, could also be called by `self.telnet.send()`

        Args:
            s: `bytes` or `str`
        """
        self.telnet.write(to_bytes(s, '\n'))

    def close(self) -> None:
        self.telnet.close()

        super(JtagDut, self).close()

__init__(pexpect_proc, app, serial, openocd, gdb, **kwargs)

Parameters:

Name Type Description Default
pexpect_proc PexpectProcess

PexpectProcess instance

required
app App

App instance

required
serial Serial

Serial instance

required
openocd OpenOcd

OpenOcd instance

required
gdb Gdb

Gdb instance

required
Source code in pytest_embedded_jtag/dut.py
def __init__(
    self,
    pexpect_proc: PexpectProcess,
    app: App,
    serial: Serial,
    openocd: OpenOcd,
    gdb: Gdb,
    **kwargs,
) -> None:
    """
    Args:
        pexpect_proc: `PexpectProcess` instance
        app: `App` instance
        serial: `Serial` instance
        openocd: `OpenOcd` instance
        gdb: `Gdb` instance
    """
    super().__init__(pexpect_proc, app, serial, **kwargs)
    self.openocd = openocd
    self.gdb = gdb

    self.openocd.create_forward_io_thread(self.pexpect_proc)
    self.gdb.create_forward_io_thread(self.pexpect_proc)

    sleep(1)  # make sure openocd already opened telnet port
    self.telnet = telnetlib.Telnet(self.openocd.TELNET_HOST, self.openocd.TELNET_PORT, 5)
    self.telnet.send = self.telnet_send  # bind send method

telnet_send(s)

Send commands through telnet port, could also be called by self.telnet.send()

Parameters:

Name Type Description Default
s AnyStr

bytes or str

required
Source code in pytest_embedded_jtag/dut.py
def telnet_send(self, s: AnyStr) -> None:
    """
    Send commands through telnet port, could also be called by `self.telnet.send()`

    Args:
        s: `bytes` or `str`
    """
    self.telnet.write(to_bytes(s, '\n'))