emdbg.bench.skynode

Auterion Skynode Test Bench

The test bench consists of a Auterion Skynode FMU that is powered through a Yocto Relay and connected to a J-Link, USB-Serial adapter for the NSH and a Digilent Analog Discovery 2.

The main entry point is the emdbg.bench.skynode function, which orchestrates the entire setup and yields an initialized bench object.

Command Line Interface

To quickly debug something interactively on the test bench, you can launch GDB directly:

python3 -m emdbg.bench.skynode --px4-dir path/to/PX4-Autopilot \
    --target px4_fmu-v5x -ui tui --stlink
 1# Copyright (c) 2023, Auterion AG
 2# SPDX-License-Identifier: BSD-3-Clause
 3
 4"""
 5.. include:: skynode.md
 6"""
 7
 8from __future__ import annotations
 9import time
10from pathlib import Path
11from .fmu import debug as fmu_debug, Fmu, _arguments
12
13import emdbg
14
15class Skynode(Fmu):
16    """
17    Skynode Debug Bench with Logic Analyzer and Power relay
18    """
19    def __init__(self, elf: Path,
20                 gdb: "emdbg.debug.remote.gdb.Interface",
21                 nsh: "emdbg.serial.protocol.Nsh" = None,
22                 power: "emdbg.power.base.Base" = None,
23                 io: "emdbg.io.digilent.Digilent" = None):
24        super().__init__(elf, gdb, nsh, power, io)
25
26        if self.io is not None:
27            self.sdio_cmd = self.io.gpio(0)
28            self.sdio_clk = self.io.gpio(1)
29
30    def disturb_sdcard_cmd_line(self, count: int = 15, delay: float = 0.1):
31        """
32        Toggle the CMD line of the SDIO interface via the Digilent scope to
33        trigger an SDCard access failure.
34        """
35        self.sdio_cmd.set_output(self.sdio_cmd.Config.OpenDrain, self.sdio_cmd.Level.Low)
36        time.sleep(1)
37        for _ in range(count):
38            self.sdio_cmd.high()
39            time.sleep(delay)
40            self.sdio_cmd.low()
41            time.sleep(delay)
42        self.sdio_cmd.set_input()
43
44    def disturb_sdcard_clk_line(self, count: int = 5, delay: float = 0.1):
45        """
46        Toggle the CLK line of the SDIO interface via the Digilent scope to
47        trigger an SDCard access failure.
48        """
49        self.sdio_clk.set_output(self.sdio_clk.Config.PushPull)
50        for _ in range(count):
51            self.sdio_clk.low()
52            time.sleep(delay)
53            self.sdio_clk.high()
54            time.sleep(delay)
55        self.sdio_clk.set_input()
56
57
58# -----------------------------------------------------------------------------
59def debug(px4_directory: Path, target: Path, serial: str = None,
60          digilent: str = None, ui: str = None, commands: list[str] = None,
61          with_rpyc: bool = False, keep_power_on: bool = True,
62          upload: bool = True, backend: str = None) -> Skynode:
63    """
64    Configures `px4_debug.bench.fmu.bench()` with a YRelay as power connection.
65    """
66    power = emdbg.power.yocto_relay(channel=1, inverted=True)
67    return fmu_debug(px4_directory, target, serial, digilent, power, ui,
68                     commands, with_rpyc, keep_power_on, upload, backend,
69                     _FmuClass=Skynode)
70
71
72# -----------------------------------------------------------------------------
73if __name__ == "__main__":
74    def _modifier(parser):
75        parser.add_argument(
76            "--turn-off",
77            default=False,
78            action="store_true",
79            help="Turn Skynode off via relay after debugging.")
80    args, backend = _arguments("Debug Skynode FMU", _modifier)
81
82    with debug(args.px4_dir, args.target, ui=args.ui, commands=args.commands,
83               backend=backend, keep_power_on=not args.turn_off) as gdb_call:
84        exit(gdb_call)
class Skynode(emdbg.bench.fmu.Fmu):
16class Skynode(Fmu):
17    """
18    Skynode Debug Bench with Logic Analyzer and Power relay
19    """
20    def __init__(self, elf: Path,
21                 gdb: "emdbg.debug.remote.gdb.Interface",
22                 nsh: "emdbg.serial.protocol.Nsh" = None,
23                 power: "emdbg.power.base.Base" = None,
24                 io: "emdbg.io.digilent.Digilent" = None):
25        super().__init__(elf, gdb, nsh, power, io)
26
27        if self.io is not None:
28            self.sdio_cmd = self.io.gpio(0)
29            self.sdio_clk = self.io.gpio(1)
30
31    def disturb_sdcard_cmd_line(self, count: int = 15, delay: float = 0.1):
32        """
33        Toggle the CMD line of the SDIO interface via the Digilent scope to
34        trigger an SDCard access failure.
35        """
36        self.sdio_cmd.set_output(self.sdio_cmd.Config.OpenDrain, self.sdio_cmd.Level.Low)
37        time.sleep(1)
38        for _ in range(count):
39            self.sdio_cmd.high()
40            time.sleep(delay)
41            self.sdio_cmd.low()
42            time.sleep(delay)
43        self.sdio_cmd.set_input()
44
45    def disturb_sdcard_clk_line(self, count: int = 5, delay: float = 0.1):
46        """
47        Toggle the CLK line of the SDIO interface via the Digilent scope to
48        trigger an SDCard access failure.
49        """
50        self.sdio_clk.set_output(self.sdio_clk.Config.PushPull)
51        for _ in range(count):
52            self.sdio_clk.low()
53            time.sleep(delay)
54            self.sdio_clk.high()
55            time.sleep(delay)
56        self.sdio_clk.set_input()

Skynode Debug Bench with Logic Analyzer and Power relay

Skynode( elf: pathlib.Path, gdb: emdbg.debug.remote.gdb.Interface, nsh: "'emdbg.serial.protocol.Nsh'" = None, power: emdbg.power.base.Base = None, io: emdbg.io.digilent.Digilent = None)
20    def __init__(self, elf: Path,
21                 gdb: "emdbg.debug.remote.gdb.Interface",
22                 nsh: "emdbg.serial.protocol.Nsh" = None,
23                 power: "emdbg.power.base.Base" = None,
24                 io: "emdbg.io.digilent.Digilent" = None):
25        super().__init__(elf, gdb, nsh, power, io)
26
27        if self.io is not None:
28            self.sdio_cmd = self.io.gpio(0)
29            self.sdio_clk = self.io.gpio(1)
def disturb_sdcard_cmd_line(self, count: int = 15, delay: float = 0.1):
31    def disturb_sdcard_cmd_line(self, count: int = 15, delay: float = 0.1):
32        """
33        Toggle the CMD line of the SDIO interface via the Digilent scope to
34        trigger an SDCard access failure.
35        """
36        self.sdio_cmd.set_output(self.sdio_cmd.Config.OpenDrain, self.sdio_cmd.Level.Low)
37        time.sleep(1)
38        for _ in range(count):
39            self.sdio_cmd.high()
40            time.sleep(delay)
41            self.sdio_cmd.low()
42            time.sleep(delay)
43        self.sdio_cmd.set_input()

Toggle the CMD line of the SDIO interface via the Digilent scope to trigger an SDCard access failure.

def disturb_sdcard_clk_line(self, count: int = 5, delay: float = 0.1):
45    def disturb_sdcard_clk_line(self, count: int = 5, delay: float = 0.1):
46        """
47        Toggle the CLK line of the SDIO interface via the Digilent scope to
48        trigger an SDCard access failure.
49        """
50        self.sdio_clk.set_output(self.sdio_clk.Config.PushPull)
51        for _ in range(count):
52            self.sdio_clk.low()
53            time.sleep(delay)
54            self.sdio_clk.high()
55            time.sleep(delay)
56        self.sdio_clk.set_input()

Toggle the CLK line of the SDIO interface via the Digilent scope to trigger an SDCard access failure.

def debug( px4_directory: pathlib.Path, target: pathlib.Path, serial: str = None, digilent: str = None, ui: str = None, commands: list[str] = None, with_rpyc: bool = False, keep_power_on: bool = True, upload: bool = True, backend: str = None) -> Skynode:
60def debug(px4_directory: Path, target: Path, serial: str = None,
61          digilent: str = None, ui: str = None, commands: list[str] = None,
62          with_rpyc: bool = False, keep_power_on: bool = True,
63          upload: bool = True, backend: str = None) -> Skynode:
64    """
65    Configures `px4_debug.bench.fmu.bench()` with a YRelay as power connection.
66    """
67    power = emdbg.power.yocto_relay(channel=1, inverted=True)
68    return fmu_debug(px4_directory, target, serial, digilent, power, ui,
69                     commands, with_rpyc, keep_power_on, upload, backend,
70                     _FmuClass=Skynode)

Configures px4_debug.bench.fmu.bench() with a YRelay as power connection.