1*61c4878aSAndroid Build Coastguard Worker.. role:: python(code) 2*61c4878aSAndroid Build Coastguard Worker :language: python 3*61c4878aSAndroid Build Coastguard Worker :class: highlight 4*61c4878aSAndroid Build Coastguard Worker 5*61c4878aSAndroid Build Coastguard Worker.. _seed-0108: 6*61c4878aSAndroid Build Coastguard Worker 7*61c4878aSAndroid Build Coastguard Worker======================== 8*61c4878aSAndroid Build Coastguard Worker0108: Emulators Frontend 9*61c4878aSAndroid Build Coastguard Worker======================== 10*61c4878aSAndroid Build Coastguard Worker.. seed:: 11*61c4878aSAndroid Build Coastguard Worker :number: 108 12*61c4878aSAndroid Build Coastguard Worker :name: Emulators Frontend 13*61c4878aSAndroid Build Coastguard Worker :status: Accepted 14*61c4878aSAndroid Build Coastguard Worker :proposal_date: 2023-06-24 15*61c4878aSAndroid Build Coastguard Worker :cl: 158190 16*61c4878aSAndroid Build Coastguard Worker :authors: Octavian Purdila 17*61c4878aSAndroid Build Coastguard Worker :facilitator: Armando Montanez 18*61c4878aSAndroid Build Coastguard Worker 19*61c4878aSAndroid Build Coastguard Worker------- 20*61c4878aSAndroid Build Coastguard WorkerSummary 21*61c4878aSAndroid Build Coastguard Worker------- 22*61c4878aSAndroid Build Coastguard WorkerThis SEED proposes a new Pigweed module that allows users to define emulator 23*61c4878aSAndroid Build Coastguard Workertargets, start, control and interact with multiple running emulator instances, 24*61c4878aSAndroid Build Coastguard Workereither through a command line interface or programmatically through Python APIs. 25*61c4878aSAndroid Build Coastguard Worker 26*61c4878aSAndroid Build Coastguard Worker----------- 27*61c4878aSAndroid Build Coastguard WorkerDefinitions 28*61c4878aSAndroid Build Coastguard Worker----------- 29*61c4878aSAndroid Build Coastguard WorkerAn **emulator** is a program that allows users to run unmodified images compiled 30*61c4878aSAndroid Build Coastguard Workerfor :ref:`target <docs-targets>` on the host machine. The **host** is the machine that 31*61c4878aSAndroid Build Coastguard Workerruns the Pigweed environment. 32*61c4878aSAndroid Build Coastguard Worker 33*61c4878aSAndroid Build Coastguard WorkerAn emulated **machine** or **board** is an emulator abstraction that typically 34*61c4878aSAndroid Build Coastguard Workerhas a correspondence in the real world - a product, an evaluation board, a 35*61c4878aSAndroid Build Coastguard Workerhardware platform. 36*61c4878aSAndroid Build Coastguard Worker 37*61c4878aSAndroid Build Coastguard WorkerAn emulated machine can be extended / tweaked through runtime configuration 38*61c4878aSAndroid Build Coastguard Workeroptions: add sensors on an i2c bus, connect a disk drive to a disk controller, 39*61c4878aSAndroid Build Coastguard Workeretc. 40*61c4878aSAndroid Build Coastguard Worker 41*61c4878aSAndroid Build Coastguard WorkerAn emulator may use an **object model**, a hierarchical arrangement of emulator 42*61c4878aSAndroid Build Coastguard Worker**objects** which are emulated devices (e.g. SPI controller) or internal 43*61c4878aSAndroid Build Coastguard Workeremulator structures. 44*61c4878aSAndroid Build Coastguard Worker 45*61c4878aSAndroid Build Coastguard WorkerAn object can be accessed through an **object path** and can have 46*61c4878aSAndroid Build Coastguard Worker**properties**. Device properties controls how the device is emulated 47*61c4878aSAndroid Build Coastguard Worker(e.g. enables or disables certain features, defines memory sizes, etc.). 48*61c4878aSAndroid Build Coastguard Worker 49*61c4878aSAndroid Build Coastguard WorkerA **channel** is a communication abstraction between the emulator and host 50*61c4878aSAndroid Build Coastguard Workerprocesses. Examples of channels that an emulator can expose to the host: 51*61c4878aSAndroid Build Coastguard Worker 52*61c4878aSAndroid Build Coastguard Worker* An emulated UART could be exposed on the host as a `PTY 53*61c4878aSAndroid Build Coastguard Worker <https://en.wikipedia.org/wiki/Pseudoterminal>`_ or a socket. 54*61c4878aSAndroid Build Coastguard Worker 55*61c4878aSAndroid Build Coastguard Worker* A flash device could be exposed on the host as file. 56*61c4878aSAndroid Build Coastguard Worker 57*61c4878aSAndroid Build Coastguard Worker* A network device could be exposed on the host as a tun/tap interface. 58*61c4878aSAndroid Build Coastguard Worker 59*61c4878aSAndroid Build Coastguard Worker* A remote gdb interface could be exposed to the host as socket. 60*61c4878aSAndroid Build Coastguard Worker 61*61c4878aSAndroid Build Coastguard WorkerA **monitor** is a control channel that allows the user to interactively or 62*61c4878aSAndroid Build Coastguard Workerprogrammatically control the emulator: pause execution, inspect the emulator 63*61c4878aSAndroid Build Coastguard Workerinternal state, connect new devices, etc. 64*61c4878aSAndroid Build Coastguard Worker 65*61c4878aSAndroid Build Coastguard Worker---------- 66*61c4878aSAndroid Build Coastguard WorkerMotivation 67*61c4878aSAndroid Build Coastguard Worker---------- 68*61c4878aSAndroid Build Coastguard WorkerWhile it is already possible to use emulators directly, there is a significant 69*61c4878aSAndroid Build Coastguard Workerlearning curve for using a specific emulator. Even for the same emulator each 70*61c4878aSAndroid Build Coastguard Workeremulated machine (board) has its own peculiarities and it often requires tweaks 71*61c4878aSAndroid Build Coastguard Workerto customize it to a specific project's needs through command line options or 72*61c4878aSAndroid Build Coastguard Workerscripts (either native emulator scripts, if supported, or through helper shell 73*61c4878aSAndroid Build Coastguard Workerscripts). 74*61c4878aSAndroid Build Coastguard Worker 75*61c4878aSAndroid Build Coastguard WorkerOnce started, the user is responsible for managing the emulator life-cycle, 76*61c4878aSAndroid Build Coastguard Workerpotentially for multiple instances. They also have to interact with it through 77*61c4878aSAndroid Build Coastguard Workervarious channels (monitor, debugger, serial ports) that requires some level of 78*61c4878aSAndroid Build Coastguard Workerhost resource management. Especially in the case of using multiple emulator 79*61c4878aSAndroid Build Coastguard Workerinstances manually managing host resources are burdensome. 80*61c4878aSAndroid Build Coastguard Worker 81*61c4878aSAndroid Build Coastguard WorkerA frequent example is the default debugger ``localhost:1234`` port that can 82*61c4878aSAndroid Build Coastguard Workerconflict with multiple emulator instances or with other debuggers running on the 83*61c4878aSAndroid Build Coastguard Workerhost. Another example: serials exposed over PTY have the pts number in 84*61c4878aSAndroid Build Coastguard Worker``/dev/pts/`` allocated dynamically and it requires the user to retrieve it 85*61c4878aSAndroid Build Coastguard Workersomehow. 86*61c4878aSAndroid Build Coastguard Worker 87*61c4878aSAndroid Build Coastguard WorkerThis gets even more complex when using different operating systems where some 88*61c4878aSAndroid Build Coastguard Workertype of host resources are not available (e.g. no PTYs on Windows) or with 89*61c4878aSAndroid Build Coastguard Workerlimited functionality (e.g. UNIX sockets are supported on Windows > Win10 but 90*61c4878aSAndroid Build Coastguard Workeronly for stream sockets and there is no Python support available yet). 91*61c4878aSAndroid Build Coastguard Worker 92*61c4878aSAndroid Build Coastguard WorkerUsing emulators in CI is also difficult, in part because host resource 93*61c4878aSAndroid Build Coastguard Workermanagement is getting more complicated due scaling (e.g. more chances of TCP 94*61c4878aSAndroid Build Coastguard Workerport conflicts) and restrictions in the execution environment. But also because 95*61c4878aSAndroid Build Coastguard Workerof a lack of high level APIs to control emulators and access their channels. 96*61c4878aSAndroid Build Coastguard Worker 97*61c4878aSAndroid Build Coastguard Worker-------- 98*61c4878aSAndroid Build Coastguard WorkerProposal 99*61c4878aSAndroid Build Coastguard Worker-------- 100*61c4878aSAndroid Build Coastguard WorkerAdd a new Pigweed module that: 101*61c4878aSAndroid Build Coastguard Worker 102*61c4878aSAndroid Build Coastguard Worker* Allows users to define emulation :ref:`targets <docs-targets>` that 103*61c4878aSAndroid Build Coastguard Worker encapsulate the emulated machine configuration, the tools configuration and 104*61c4878aSAndroid Build Coastguard Worker the host channels configuration. 105*61c4878aSAndroid Build Coastguard Worker 106*61c4878aSAndroid Build Coastguard Worker* Provides a command line interface that manages multiple emulator instances and 107*61c4878aSAndroid Build Coastguard Worker provides interactive access to the emulator's host channels. 108*61c4878aSAndroid Build Coastguard Worker 109*61c4878aSAndroid Build Coastguard Worker* Provides a Python API to control emulator instances and access the emulator's 110*61c4878aSAndroid Build Coastguard Worker host channels. 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard Worker* Supports multiple emulators, QEMU and renode as a starting point. 113*61c4878aSAndroid Build Coastguard Worker 114*61c4878aSAndroid Build Coastguard Worker* Expose channels for gdb, monitor and user selected devices through 115*61c4878aSAndroid Build Coastguard Worker configurable host resources, sockets and PTYs as a starting point. 116*61c4878aSAndroid Build Coastguard Worker 117*61c4878aSAndroid Build Coastguard WorkerThe following sections will add more details about the configuration, the 118*61c4878aSAndroid Build Coastguard Workercommand line interface, the API for controlling and accessing emulators and the 119*61c4878aSAndroid Build Coastguard WorkerAPI for adding support for more emulators. 120*61c4878aSAndroid Build Coastguard Worker 121*61c4878aSAndroid Build Coastguard Worker 122*61c4878aSAndroid Build Coastguard WorkerConfiguration 123*61c4878aSAndroid Build Coastguard Worker============= 124*61c4878aSAndroid Build Coastguard WorkerThe emulators configuration is part of the Pigweed root configuration file 125*61c4878aSAndroid Build Coastguard Worker(``pigweed.json``) and reside in the ``pw:pw_emu`` namespace. 126*61c4878aSAndroid Build Coastguard Worker 127*61c4878aSAndroid Build Coastguard WorkerProjects can define emulation targets in the Pigweed root configuration file and 128*61c4878aSAndroid Build Coastguard Workercan also import predefined targets from other files. The pw_emu module provides 129*61c4878aSAndroid Build Coastguard Workera set of targets as examples and to promote reusability. 130*61c4878aSAndroid Build Coastguard Worker 131*61c4878aSAndroid Build Coastguard WorkerFor example, the following top level ``pigweed.json`` configuration includes a 132*61c4878aSAndroid Build Coastguard Workertarget fragment from the ``pw_emu/qemu-lm3s6965evb.json`` file: 133*61c4878aSAndroid Build Coastguard Worker 134*61c4878aSAndroid Build Coastguard Worker.. code-block:: 135*61c4878aSAndroid Build Coastguard Worker 136*61c4878aSAndroid Build Coastguard Worker { 137*61c4878aSAndroid Build Coastguard Worker "pw": { 138*61c4878aSAndroid Build Coastguard Worker "pw_emu": { 139*61c4878aSAndroid Build Coastguard Worker "target_files": [ 140*61c4878aSAndroid Build Coastguard Worker "pw_emu/qemu-lm3s6965evb.json" 141*61c4878aSAndroid Build Coastguard Worker ] 142*61c4878aSAndroid Build Coastguard Worker } 143*61c4878aSAndroid Build Coastguard Worker } 144*61c4878aSAndroid Build Coastguard Worker } 145*61c4878aSAndroid Build Coastguard Worker 146*61c4878aSAndroid Build Coastguard Worker 147*61c4878aSAndroid Build Coastguard Worker``pw_emu/qemu-lm3s6965evb.json`` defines the ``qemu-lm3s6965evb`` target 148*61c4878aSAndroid Build Coastguard Workerthat uses qemu as the emulator and lm3s6965evb as the machine, with the 149*61c4878aSAndroid Build Coastguard Worker``serial0`` chardev exposed as ``serial0``: 150*61c4878aSAndroid Build Coastguard Worker 151*61c4878aSAndroid Build Coastguard Worker.. code-block:: 152*61c4878aSAndroid Build Coastguard Worker 153*61c4878aSAndroid Build Coastguard Worker { 154*61c4878aSAndroid Build Coastguard Worker "targets": { 155*61c4878aSAndroid Build Coastguard Worker "qemu-lm3s6965evb": { 156*61c4878aSAndroid Build Coastguard Worker "gdb": "arm-none-eabi-gdb", 157*61c4878aSAndroid Build Coastguard Worker "qemu": { 158*61c4878aSAndroid Build Coastguard Worker "executable": "qemu-system-arm", 159*61c4878aSAndroid Build Coastguard Worker "machine": "lm3s6965evb", 160*61c4878aSAndroid Build Coastguard Worker "channels": { 161*61c4878aSAndroid Build Coastguard Worker "chardevs": { 162*61c4878aSAndroid Build Coastguard Worker "serial0": { 163*61c4878aSAndroid Build Coastguard Worker "id": "serial0" 164*61c4878aSAndroid Build Coastguard Worker } 165*61c4878aSAndroid Build Coastguard Worker } 166*61c4878aSAndroid Build Coastguard Worker } 167*61c4878aSAndroid Build Coastguard Worker } 168*61c4878aSAndroid Build Coastguard Worker } 169*61c4878aSAndroid Build Coastguard Worker } 170*61c4878aSAndroid Build Coastguard Worker } 171*61c4878aSAndroid Build Coastguard Worker 172*61c4878aSAndroid Build Coastguard WorkerThis target emulates a stm32f405 SoC and is compatible with the 173*61c4878aSAndroid Build Coastguard Worker:ref:`target-lm3s6965evb-qemu` Pigweed build target. 174*61c4878aSAndroid Build Coastguard Worker 175*61c4878aSAndroid Build Coastguard WorkerThe configuration defines a ``serial0`` channel to be the QEMU **chardev** with 176*61c4878aSAndroid Build Coastguard Workerthe ``serial0`` id. The default type of the channel is used, which is TCP and 177*61c4878aSAndroid Build Coastguard Workerwhich is supported by all platforms. The user can change the type by adding a 178*61c4878aSAndroid Build Coastguard Worker``type`` key set to the desired type (e.g. ``pty``). 179*61c4878aSAndroid Build Coastguard Worker 180*61c4878aSAndroid Build Coastguard WorkerThe following configuration fragment defines a target that uses renode: 181*61c4878aSAndroid Build Coastguard Worker 182*61c4878aSAndroid Build Coastguard Worker.. code-block:: 183*61c4878aSAndroid Build Coastguard Worker 184*61c4878aSAndroid Build Coastguard Worker { 185*61c4878aSAndroid Build Coastguard Worker "targets": { 186*61c4878aSAndroid Build Coastguard Worker "renode-stm32f4_discovery": { 187*61c4878aSAndroid Build Coastguard Worker "gdb": "arm-none-eabi-gdb", 188*61c4878aSAndroid Build Coastguard Worker "renode": { 189*61c4878aSAndroid Build Coastguard Worker "executable": "renode", 190*61c4878aSAndroid Build Coastguard Worker "machine": "platforms/boards/stm32f4_discovery-kit.repl", 191*61c4878aSAndroid Build Coastguard Worker "channels": { 192*61c4878aSAndroid Build Coastguard Worker "terminals": { 193*61c4878aSAndroid Build Coastguard Worker "serial0": { 194*61c4878aSAndroid Build Coastguard Worker "device-path": "sysbus.uart0", 195*61c4878aSAndroid Build Coastguard Worker "type": "pty" 196*61c4878aSAndroid Build Coastguard Worker } 197*61c4878aSAndroid Build Coastguard Worker } 198*61c4878aSAndroid Build Coastguard Worker } 199*61c4878aSAndroid Build Coastguard Worker } 200*61c4878aSAndroid Build Coastguard Worker } 201*61c4878aSAndroid Build Coastguard Worker } 202*61c4878aSAndroid Build Coastguard Worker } 203*61c4878aSAndroid Build Coastguard Worker 204*61c4878aSAndroid Build Coastguard WorkerNote that ``machine`` is used to identify which renode script to use to load the 205*61c4878aSAndroid Build Coastguard Workerplaform description from and ``terminals`` to define which UART devices to 206*61c4878aSAndroid Build Coastguard Workerexpose to the host. Also note the ``serial0`` channel is set to be exposed as a 207*61c4878aSAndroid Build Coastguard WorkerPTY on the host. 208*61c4878aSAndroid Build Coastguard Worker 209*61c4878aSAndroid Build Coastguard WorkerThe following channel types are currently supported: 210*61c4878aSAndroid Build Coastguard Worker 211*61c4878aSAndroid Build Coastguard Worker* ``pty``: supported on Mac and Linux; renode only supports PTYs for 212*61c4878aSAndroid Build Coastguard Worker ``terminals`` channels. 213*61c4878aSAndroid Build Coastguard Worker 214*61c4878aSAndroid Build Coastguard Worker* ``tcp``: supported on all platforms and for all channels; it is also the 215*61c4878aSAndroid Build Coastguard Worker default type if no channel type is configured. 216*61c4878aSAndroid Build Coastguard Worker 217*61c4878aSAndroid Build Coastguard WorkerThe channel configuration can be set at multiple levels: emulator, target, or 218*61c4878aSAndroid Build Coastguard Workerspecific channel. The channel configuration takes precedence, then the target 219*61c4878aSAndroid Build Coastguard Workerchannel configuration then the emulator channel configuration. 220*61c4878aSAndroid Build Coastguard Worker 221*61c4878aSAndroid Build Coastguard WorkerThe following expressions are replaced in the configuration strings: 222*61c4878aSAndroid Build Coastguard Worker 223*61c4878aSAndroid Build Coastguard Worker* ``$pw_emu_wdir{relative-path}``: replaces statement with an absolute path by 224*61c4878aSAndroid Build Coastguard Worker concatenating the emulator's working directory with the given relative path. 225*61c4878aSAndroid Build Coastguard Worker 226*61c4878aSAndroid Build Coastguard Worker* ``$pw_emu_channel_port{channel-name}``: replaces the statement with the port 227*61c4878aSAndroid Build Coastguard Worker number for the given channel name; the channel type should be ``tcp``. 228*61c4878aSAndroid Build Coastguard Worker 229*61c4878aSAndroid Build Coastguard Worker* ``$pw_emu_channel_host{channel-name}``: replaces the statement with the host 230*61c4878aSAndroid Build Coastguard Worker for the given channel name; the channel type should be ``tcp``. 231*61c4878aSAndroid Build Coastguard Worker 232*61c4878aSAndroid Build Coastguard Worker* ``$pw_emu_channel_path{channel-name}``: replaces the statement with the path 233*61c4878aSAndroid Build Coastguard Worker for the given channel name; the channel type should be ``pty``. 234*61c4878aSAndroid Build Coastguard Worker 235*61c4878aSAndroid Build Coastguard WorkerBesides running QEMU and renode as the main emulator, the target configuration 236*61c4878aSAndroid Build Coastguard Workerallows users to start other programs before or after starting the main emulator 237*61c4878aSAndroid Build Coastguard Workerprocess. This allows extending the emulated target with simulation or emulation 238*61c4878aSAndroid Build Coastguard Workeroutside of the main emulator. For example, for BLE emulation the main emulator 239*61c4878aSAndroid Build Coastguard Workercould emulate just the serial port while the HCI emulation done is in an 240*61c4878aSAndroid Build Coastguard Workerexternal program (e.g. `bumble <https://google.github.io/bumble>`_, `netsim 241*61c4878aSAndroid Build Coastguard Worker<https://android.googlesource.com/platform/tools/netsim>`_). 242*61c4878aSAndroid Build Coastguard Worker 243*61c4878aSAndroid Build Coastguard Worker 244*61c4878aSAndroid Build Coastguard WorkerCommand line interface 245*61c4878aSAndroid Build Coastguard Worker====================== 246*61c4878aSAndroid Build Coastguard WorkerThe command line interfaces enables users to control emulator instances and 247*61c4878aSAndroid Build Coastguard Workeraccess their channels interactively. 248*61c4878aSAndroid Build Coastguard Worker 249*61c4878aSAndroid Build Coastguard Worker.. code-block:: text 250*61c4878aSAndroid Build Coastguard Worker 251*61c4878aSAndroid Build Coastguard Worker usage: pw emu [-h] [-i STRING] [-w WDIR] {command} ... 252*61c4878aSAndroid Build Coastguard Worker 253*61c4878aSAndroid Build Coastguard Worker Pigweed Emulators Frontend 254*61c4878aSAndroid Build Coastguard Worker 255*61c4878aSAndroid Build Coastguard Worker start Launch the emulator and start executing, unless pause 256*61c4878aSAndroid Build Coastguard Worker is set. 257*61c4878aSAndroid Build Coastguard Worker restart Restart the emulator and start executing, unless pause 258*61c4878aSAndroid Build Coastguard Worker is set. 259*61c4878aSAndroid Build Coastguard Worker run Start the emulator and connect the terminal to a 260*61c4878aSAndroid Build Coastguard Worker channel. Stop the emulator when exiting the terminal 261*61c4878aSAndroid Build Coastguard Worker stop Stop the emulator 262*61c4878aSAndroid Build Coastguard Worker load Load an executable image via gdb. If pause is not set 263*61c4878aSAndroid Build Coastguard Worker start executing it. 264*61c4878aSAndroid Build Coastguard Worker reset Perform a software reset. 265*61c4878aSAndroid Build Coastguard Worker gdb Start a gdb interactive session 266*61c4878aSAndroid Build Coastguard Worker prop-ls List emulator object properties. 267*61c4878aSAndroid Build Coastguard Worker prop-get Show the emulator's object properties. 268*61c4878aSAndroid Build Coastguard Worker prop-set Show emulator's object properties. 269*61c4878aSAndroid Build Coastguard Worker gdb-cmds Run gdb commands in batch mode. 270*61c4878aSAndroid Build Coastguard Worker term Connect with an interactive terminal to an emulator 271*61c4878aSAndroid Build Coastguard Worker channel 272*61c4878aSAndroid Build Coastguard Worker 273*61c4878aSAndroid Build Coastguard Worker optional arguments: 274*61c4878aSAndroid Build Coastguard Worker -h, --help show this help message and exit 275*61c4878aSAndroid Build Coastguard Worker -i STRING, --instance STRING 276*61c4878aSAndroid Build Coastguard Worker instance to use (default: default) 277*61c4878aSAndroid Build Coastguard Worker -w WDIR, --wdir WDIR path to working directory (default: None) 278*61c4878aSAndroid Build Coastguard Worker 279*61c4878aSAndroid Build Coastguard Worker commands usage: 280*61c4878aSAndroid Build Coastguard Worker usage: pw emu start [-h] [--file FILE] [--runner {None,qemu,renode}] 281*61c4878aSAndroid Build Coastguard Worker [--args ARGS] [--pause] [--debug] [--foreground] 282*61c4878aSAndroid Build Coastguard Worker {qemu-lm3s6965evb,qemu-stm32vldiscovery,qemu-netduinoplus2} 283*61c4878aSAndroid Build Coastguard Worker usage: pw emu restart [-h] [--file FILE] [--runner {None,qemu,renode}] 284*61c4878aSAndroid Build Coastguard Worker [--args ARGS] [--pause] [--debug] [--foreground] 285*61c4878aSAndroid Build Coastguard Worker {qemu-lm3s6965evb,qemu-stm32vldiscovery,qemu-netduinoplus2} 286*61c4878aSAndroid Build Coastguard Worker usage: pw emu stop [-h] 287*61c4878aSAndroid Build Coastguard Worker usage: pw emu run [-h] [--args ARGS] [--channel CHANNEL] 288*61c4878aSAndroid Build Coastguard Worker {qemu-lm3s6965evb,qemu-stm32vldiscovery,qemu-netduinoplus2} FILE 289*61c4878aSAndroid Build Coastguard Worker usage: pw emu load [-h] [--pause] FILE 290*61c4878aSAndroid Build Coastguard Worker usage: pw emu reset [-h] 291*61c4878aSAndroid Build Coastguard Worker usage: pw emu gdb [-h] [--executable FILE] 292*61c4878aSAndroid Build Coastguard Worker usage: pw emu prop-ls [-h] path 293*61c4878aSAndroid Build Coastguard Worker usage: pw emu prop-get [-h] path property 294*61c4878aSAndroid Build Coastguard Worker usage: pw emu prop-set [-h] path property value 295*61c4878aSAndroid Build Coastguard Worker usage: pw emu gdb-cmds [-h] [--pause] [--executable FILE] gdb-command [gdb-command ...] 296*61c4878aSAndroid Build Coastguard Worker usage: pw emu term [-h] channel 297*61c4878aSAndroid Build Coastguard Worker 298*61c4878aSAndroid Build Coastguard WorkerFor example, the ``run`` command is useful for quickly running ELF binaries on an 299*61c4878aSAndroid Build Coastguard Workeremulated target and seeing / interacting with a serial channel. It starts an 300*61c4878aSAndroid Build Coastguard Workeremulator, loads an images, connects to a channel and starts executing. 301*61c4878aSAndroid Build Coastguard Worker 302*61c4878aSAndroid Build Coastguard Worker.. code-block:: 303*61c4878aSAndroid Build Coastguard Worker 304*61c4878aSAndroid Build Coastguard Worker $ pw emu run qemu-netduinoplus2 out/stm32f429i_disc1_debug/obj/pw_snapshot/test/cpp_compile_test.elf 305*61c4878aSAndroid Build Coastguard Worker 306*61c4878aSAndroid Build Coastguard Worker --- Miniterm on serial0 --- 307*61c4878aSAndroid Build Coastguard Worker --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- 308*61c4878aSAndroid Build Coastguard Worker INF [==========] Running all tests. 309*61c4878aSAndroid Build Coastguard Worker INF [ RUN ] Status.CompileTest 310*61c4878aSAndroid Build Coastguard Worker INF [ OK ] Status.CompileTest 311*61c4878aSAndroid Build Coastguard Worker INF [==========] Done running all tests. 312*61c4878aSAndroid Build Coastguard Worker INF [ PASSED ] 1 test(s). 313*61c4878aSAndroid Build Coastguard Worker --- exit --- 314*61c4878aSAndroid Build Coastguard Worker 315*61c4878aSAndroid Build Coastguard WorkerMultiple emulator instances can be run and each emulator instance is identified 316*61c4878aSAndroid Build Coastguard Workerby its working directory. The default working directory for ``pw emu`` is 317*61c4878aSAndroid Build Coastguard Worker``$PW_PROJECT_ROOT/.pw_emu/<instance-id>`` where ``<instance-id>`` is a command 318*61c4878aSAndroid Build Coastguard Workerline option that defaults to ``default``. 319*61c4878aSAndroid Build Coastguard Worker 320*61c4878aSAndroid Build Coastguard WorkerFor more complex usage patterns, the ``start`` command can be used which will 321*61c4878aSAndroid Build Coastguard Workerlaunch an emulator instance in the background. Then, the user can debug the 322*61c4878aSAndroid Build Coastguard Workerimage with the ``gdb`` command, connect to a channel (e.g. serial port) with the 323*61c4878aSAndroid Build Coastguard Worker``term`` command, reset the emulator with the ``reset`` command, inspect or 324*61c4878aSAndroid Build Coastguard Workerchange emulator properties with the ``prop-ls``, ``prop-get``, ``prop-set`` and 325*61c4878aSAndroid Build Coastguard Workerfinally stop the emulator instance with ``stop``. 326*61c4878aSAndroid Build Coastguard Worker 327*61c4878aSAndroid Build Coastguard Worker 328*61c4878aSAndroid Build Coastguard WorkerPython APIs 329*61c4878aSAndroid Build Coastguard Worker=========== 330*61c4878aSAndroid Build Coastguard WorkerThe pw_emu module offers Python APIs to launch, control and interact with an 331*61c4878aSAndroid Build Coastguard Workeremulator instance. 332*61c4878aSAndroid Build Coastguard Worker 333*61c4878aSAndroid Build Coastguard WorkerThe following is an example of using these APIs which implements a simplified 334*61c4878aSAndroid Build Coastguard Workerversion of the ``run`` pw_emu CLI command: 335*61c4878aSAndroid Build Coastguard Worker 336*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 337*61c4878aSAndroid Build Coastguard Worker 338*61c4878aSAndroid Build Coastguard Worker # start an emulator instance and load the image to execute 339*61c4878aSAndroid Build Coastguard Worker # pause the emulator after loading the image 340*61c4878aSAndroid Build Coastguard Worker emu = Emulator(args.wdir) 341*61c4878aSAndroid Build Coastguard Worker emu.start(args.target, args.file, pause=True) 342*61c4878aSAndroid Build Coastguard Worker 343*61c4878aSAndroid Build Coastguard Worker # determine the channel type and create a pyserial compatible URL 344*61c4878aSAndroid Build Coastguard Worker chan_type = emu.get_channel_type(args.chan) 345*61c4878aSAndroid Build Coastguard Worker if chan_type == 'tcp': 346*61c4878aSAndroid Build Coastguard Worker host, port = emu.get_channel_addr(chan) 347*61c4878aSAndroid Build Coastguard Worker url = f'socket://{host}:{port}' 348*61c4878aSAndroid Build Coastguard Worker elif chan_type == 'pty': 349*61c4878aSAndroid Build Coastguard Worker url = emu.get_channel_path(chan) 350*61c4878aSAndroid Build Coastguard Worker else: 351*61c4878aSAndroid Build Coastguard Worker raise Error(f'unknown channel type `{chan_type}`') 352*61c4878aSAndroid Build Coastguard Worker 353*61c4878aSAndroid Build Coastguard Worker # open the serial port and create a miniterm instance 354*61c4878aSAndroid Build Coastguard Worker serial = serial_for_url(url) 355*61c4878aSAndroid Build Coastguard Worker serial.timeout = 1 356*61c4878aSAndroid Build Coastguard Worker miniterm = Miniterm(serial) 357*61c4878aSAndroid Build Coastguard Worker miniterm.raw = True 358*61c4878aSAndroid Build Coastguard Worker miniterm.set_tx_encoding('UTF-8') 359*61c4878aSAndroid Build Coastguard Worker miniterm.set_rx_encoding('UTF-8') 360*61c4878aSAndroid Build Coastguard Worker 361*61c4878aSAndroid Build Coastguard Worker # now that we are connected to the channel we can unpause 362*61c4878aSAndroid Build Coastguard Worker # this approach will prevent and data loses 363*61c4878aSAndroid Build Coastguard Worker emu.cont() 364*61c4878aSAndroid Build Coastguard Worker 365*61c4878aSAndroid Build Coastguard Worker miniterm.start() 366*61c4878aSAndroid Build Coastguard Worker try: 367*61c4878aSAndroid Build Coastguard Worker miniterm.join(True) 368*61c4878aSAndroid Build Coastguard Worker except KeyBoardInterrupt: 369*61c4878aSAndroid Build Coastguard Worker pass 370*61c4878aSAndroid Build Coastguard Worker miniterm.stop() 371*61c4878aSAndroid Build Coastguard Worker miniterm.join() 372*61c4878aSAndroid Build Coastguard Worker miniterm.close() 373*61c4878aSAndroid Build Coastguard Worker 374*61c4878aSAndroid Build Coastguard WorkerFor convenience, a ``TemporaryEmulator`` class is also provided. 375*61c4878aSAndroid Build Coastguard Worker 376*61c4878aSAndroid Build Coastguard WorkerIt manages emulator instances that run in temporary working directories. The 377*61c4878aSAndroid Build Coastguard Workeremulator instance is stopped and the working directory is cleared when the with 378*61c4878aSAndroid Build Coastguard Workerblock completes. 379*61c4878aSAndroid Build Coastguard Worker 380*61c4878aSAndroid Build Coastguard WorkerIt also supports interoperability with the pw emu cli, i.e. starting the 381*61c4878aSAndroid Build Coastguard Workeremulator with the CLI and controlling / interacting with it from the API. 382*61c4878aSAndroid Build Coastguard Worker 383*61c4878aSAndroid Build Coastguard WorkerUsage example: 384*61c4878aSAndroid Build Coastguard Worker 385*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 386*61c4878aSAndroid Build Coastguard Worker 387*61c4878aSAndroid Build Coastguard Worker # programmatically start and load an executable then access it 388*61c4878aSAndroid Build Coastguard Worker with TemporaryEmulator() as emu: 389*61c4878aSAndroid Build Coastguard Worker emu.start(target, file) 390*61c4878aSAndroid Build Coastguard Worker with emu.get_channel_stream(chan) as stream: 391*61c4878aSAndroid Build Coastguard Worker ... 392*61c4878aSAndroid Build Coastguard Worker 393*61c4878aSAndroid Build Coastguard Worker 394*61c4878aSAndroid Build Coastguard Worker # or start it form the command line then access it programmatically 395*61c4878aSAndroid Build Coastguard Worker with TemporaryEmulator() as emu: 396*61c4878aSAndroid Build Coastguard Worker build.bazel( 397*61c4878aSAndroid Build Coastguard Worker ctx, 398*61c4878aSAndroid Build Coastguard Worker "run", 399*61c4878aSAndroid Build Coastguard Worker exec_path, 400*61c4878aSAndroid Build Coastguard Worker "--run_under=pw emu start <target> --file " 401*61c4878aSAndroid Build Coastguard Worker ) 402*61c4878aSAndroid Build Coastguard Worker 403*61c4878aSAndroid Build Coastguard Worker with emu.get_channel_stream(chan) as stream: 404*61c4878aSAndroid Build Coastguard Worker ... 405*61c4878aSAndroid Build Coastguard Worker 406*61c4878aSAndroid Build Coastguard Worker 407*61c4878aSAndroid Build Coastguard WorkerIntended API shape 408*61c4878aSAndroid Build Coastguard Worker------------------ 409*61c4878aSAndroid Build Coastguard WorkerThis is not an API reference, just an example of the probable shape of the final 410*61c4878aSAndroid Build Coastguard WorkerAPI. 411*61c4878aSAndroid Build Coastguard Worker 412*61c4878aSAndroid Build Coastguard Worker:python:`class Emulator` is used to launch, control and interact with an 413*61c4878aSAndroid Build Coastguard Workeremulator instance: 414*61c4878aSAndroid Build Coastguard Worker 415*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 416*61c4878aSAndroid Build Coastguard Worker 417*61c4878aSAndroid Build Coastguard Worker def start( 418*61c4878aSAndroid Build Coastguard Worker self, 419*61c4878aSAndroid Build Coastguard Worker target: str, 420*61c4878aSAndroid Build Coastguard Worker file: os.PathLike | None = None, 421*61c4878aSAndroid Build Coastguard Worker pause: bool = False, 422*61c4878aSAndroid Build Coastguard Worker debug: bool = False, 423*61c4878aSAndroid Build Coastguard Worker foreground: bool = False, 424*61c4878aSAndroid Build Coastguard Worker args: str | None = None, 425*61c4878aSAndroid Build Coastguard Worker ) -> None: 426*61c4878aSAndroid Build Coastguard Worker 427*61c4878aSAndroid Build Coastguard Worker|nbsp| 428*61c4878aSAndroid Build Coastguard Worker Start the emulator for the given target. 429*61c4878aSAndroid Build Coastguard Worker 430*61c4878aSAndroid Build Coastguard Worker If file is set that the emulator will load the file before starting. 431*61c4878aSAndroid Build Coastguard Worker 432*61c4878aSAndroid Build Coastguard Worker If pause is True the emulator is paused until the debugger is connected. 433*61c4878aSAndroid Build Coastguard Worker 434*61c4878aSAndroid Build Coastguard Worker If debug is True the emulator is run in foreground with debug output 435*61c4878aSAndroid Build Coastguard Worker enabled. This is useful for seeing errors, traces, etc. 436*61c4878aSAndroid Build Coastguard Worker 437*61c4878aSAndroid Build Coastguard Worker If foreground is True the emulator is run in foreground otherwise it is 438*61c4878aSAndroid Build Coastguard Worker started in daemon mode. This is useful when there is another process 439*61c4878aSAndroid Build Coastguard Worker controlling the emulator's life cycle (e.g. cuttlefish) 440*61c4878aSAndroid Build Coastguard Worker 441*61c4878aSAndroid Build Coastguard Worker args are passed directly to the emulator 442*61c4878aSAndroid Build Coastguard Worker 443*61c4878aSAndroid Build Coastguard Worker:python:`def running(self) -> bool:` 444*61c4878aSAndroid Build Coastguard Worker Check if the main emulator process is already running. 445*61c4878aSAndroid Build Coastguard Worker 446*61c4878aSAndroid Build Coastguard Worker:python:`def stop(self) -> None` 447*61c4878aSAndroid Build Coastguard Worker Stop the emulator 448*61c4878aSAndroid Build Coastguard Worker 449*61c4878aSAndroid Build Coastguard Worker:python:`def get_gdb_remote(self) -> str:` 450*61c4878aSAndroid Build Coastguard Worker Return a string that can be passed to the target remote gdb command. 451*61c4878aSAndroid Build Coastguard Worker 452*61c4878aSAndroid Build Coastguard Worker:python:`def get_gdb(self) -> str | None:` 453*61c4878aSAndroid Build Coastguard Worker Returns the gdb command for current target. 454*61c4878aSAndroid Build Coastguard Worker 455*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 456*61c4878aSAndroid Build Coastguard Worker 457*61c4878aSAndroid Build Coastguard Worker def run_gdb_cmds( 458*61c4878aSAndroid Build Coastguard Worker commands : list[str], 459*61c4878aSAndroid Build Coastguard Worker executable: Path | None = None, 460*61c4878aSAndroid Build Coastguard Worker pause: bool = False 461*61c4878aSAndroid Build Coastguard Worker ) -> subprocess.CompletedProcess: 462*61c4878aSAndroid Build Coastguard Worker 463*61c4878aSAndroid Build Coastguard Worker|nbsp| 464*61c4878aSAndroid Build Coastguard Worker Connect to the target and run the given commands silently 465*61c4878aSAndroid Build Coastguard Worker in batch mode. 466*61c4878aSAndroid Build Coastguard Worker 467*61c4878aSAndroid Build Coastguard Worker The executable is optional but it may be required by some gdb 468*61c4878aSAndroid Build Coastguard Worker commands. 469*61c4878aSAndroid Build Coastguard Worker 470*61c4878aSAndroid Build Coastguard Worker If pause is set do not continue execution after running the 471*61c4878aSAndroid Build Coastguard Worker given commands. 472*61c4878aSAndroid Build Coastguard Worker 473*61c4878aSAndroid Build Coastguard Worker:python:`def reset() -> None` 474*61c4878aSAndroid Build Coastguard Worker Performs a software reset 475*61c4878aSAndroid Build Coastguard Worker 476*61c4878aSAndroid Build Coastguard Worker:python:`def list_properties(self, path: str) -> List[dict]` 477*61c4878aSAndroid Build Coastguard Worker Returns the property list for an emulator object. 478*61c4878aSAndroid Build Coastguard Worker 479*61c4878aSAndroid Build Coastguard Worker The object is identified by a full path. The path is target specific and 480*61c4878aSAndroid Build Coastguard Worker the format of the path is emulator specific. 481*61c4878aSAndroid Build Coastguard Worker 482*61c4878aSAndroid Build Coastguard Worker QEMU path example: /machine/unattached/device[10] 483*61c4878aSAndroid Build Coastguard Worker 484*61c4878aSAndroid Build Coastguard Worker renode path example: sysbus.uart 485*61c4878aSAndroid Build Coastguard Worker 486*61c4878aSAndroid Build Coastguard Worker:python:`def set_property(path: str, prop: str, value: str) -> None` 487*61c4878aSAndroid Build Coastguard Worker Sets the value of an emulator's object property. 488*61c4878aSAndroid Build Coastguard Worker 489*61c4878aSAndroid Build Coastguard Worker:python:`def get_property(self, path: str, prop: str) -> None` 490*61c4878aSAndroid Build Coastguard Worker Returns the value of an emulator's object property. 491*61c4878aSAndroid Build Coastguard Worker 492*61c4878aSAndroid Build Coastguard Worker:python:`def get_channel_type(self, name: str) -> str` 493*61c4878aSAndroid Build Coastguard Worker Returns the channel type. 494*61c4878aSAndroid Build Coastguard Worker 495*61c4878aSAndroid Build Coastguard Worker Currently ``pty`` or ``tcp`` are the only supported types. 496*61c4878aSAndroid Build Coastguard Worker 497*61c4878aSAndroid Build Coastguard Worker:python:`def get_channel_path(self, name: str) -> str:` 498*61c4878aSAndroid Build Coastguard Worker Returns the channel path. Raises InvalidChannelType if this is not a PTY 499*61c4878aSAndroid Build Coastguard Worker channel. 500*61c4878aSAndroid Build Coastguard Worker 501*61c4878aSAndroid Build Coastguard Worker:python:`def get_channel_addr(self, name: str) -> tuple:` 502*61c4878aSAndroid Build Coastguard Worker Returns a pair of (host, port) for the channel. Raises InvalidChannelType 503*61c4878aSAndroid Build Coastguard Worker if this is not a tcp channel. 504*61c4878aSAndroid Build Coastguard Worker 505*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 506*61c4878aSAndroid Build Coastguard Worker 507*61c4878aSAndroid Build Coastguard Worker def get_channel_stream( 508*61c4878aSAndroid Build Coastguard Worker name: str, 509*61c4878aSAndroid Build Coastguard Worker timeout: float | None = None 510*61c4878aSAndroid Build Coastguard Worker ) -> io.RawIOBase: 511*61c4878aSAndroid Build Coastguard Worker 512*61c4878aSAndroid Build Coastguard Worker|nbsp| 513*61c4878aSAndroid Build Coastguard Worker Returns a file object for a given host exposed device. 514*61c4878aSAndroid Build Coastguard Worker 515*61c4878aSAndroid Build Coastguard Worker If timeout is None than reads and writes are blocking. If timeout is zero the 516*61c4878aSAndroid Build Coastguard Worker stream is operating in non-blocking mode. Otherwise read and write will 517*61c4878aSAndroid Build Coastguard Worker timeout after the given value. 518*61c4878aSAndroid Build Coastguard Worker 519*61c4878aSAndroid Build Coastguard Worker:python:`def get_channels(self) -> List[str]:` 520*61c4878aSAndroid Build Coastguard Worker Returns the list of available channels. 521*61c4878aSAndroid Build Coastguard Worker 522*61c4878aSAndroid Build Coastguard Worker:python:`def cont(self) -> None:` 523*61c4878aSAndroid Build Coastguard Worker Resume the emulator's execution 524*61c4878aSAndroid Build Coastguard Worker 525*61c4878aSAndroid Build Coastguard Worker--------------------- 526*61c4878aSAndroid Build Coastguard WorkerProblem investigation 527*61c4878aSAndroid Build Coastguard Worker--------------------- 528*61c4878aSAndroid Build Coastguard WorkerPigweed is missing a tool for basic emulators control and as shown in the 529*61c4878aSAndroid Build Coastguard Workermotivation section directly using emulators directly is difficult. 530*61c4878aSAndroid Build Coastguard Worker 531*61c4878aSAndroid Build Coastguard WorkerWhile emulation is not a goal for every project, it is appealing for some due 532*61c4878aSAndroid Build Coastguard Workerto the low cost and scalability. Offering a customizable emulators frontend in 533*61c4878aSAndroid Build Coastguard WorkerPigweed will make this even better for downstream projects as the investment to 534*61c4878aSAndroid Build Coastguard Workerget started with emulation will be lower - significantly lower for projects 535*61c4878aSAndroid Build Coastguard Workerlooking for basic usage. 536*61c4878aSAndroid Build Coastguard Worker 537*61c4878aSAndroid Build Coastguard WorkerThere are two main use-cases that this proposal is addressing: 538*61c4878aSAndroid Build Coastguard Worker 539*61c4878aSAndroid Build Coastguard Worker* Easier and robust interactive debugging and testing on emulators. 540*61c4878aSAndroid Build Coastguard Worker 541*61c4878aSAndroid Build Coastguard Worker* Basic APIs for controlling and accessing emulators to help with emulator 542*61c4878aSAndroid Build Coastguard Worker based testing (and trivial CI deployment - as long as the Pigweed bootstrap 543*61c4878aSAndroid Build Coastguard Worker process can run in CI). 544*61c4878aSAndroid Build Coastguard Worker 545*61c4878aSAndroid Build Coastguard WorkerThe proposal focuses on a set of fairly small number of commands and APIs in 546*61c4878aSAndroid Build Coastguard Workerorder to minimize complexity and gather feedback from users before adding more 547*61c4878aSAndroid Build Coastguard Workerfeatures. 548*61c4878aSAndroid Build Coastguard Worker 549*61c4878aSAndroid Build Coastguard WorkerSince the state of emulated boards may different between emulators, to enable 550*61c4878aSAndroid Build Coastguard Workerusers access to more emulated targets, the goal of the module is to support 551*61c4878aSAndroid Build Coastguard Workermultiple emulators from the start. 552*61c4878aSAndroid Build Coastguard Worker 553*61c4878aSAndroid Build Coastguard WorkerTwo emulators were selected for the initial implementation: QEMU and 554*61c4878aSAndroid Build Coastguard Workerrenode. Both run on all Pigweed currently supported hosts (Linux, Mac, Windows) 555*61c4878aSAndroid Build Coastguard Workerand there is good overlap in terms of APIs to configure, start, control and 556*61c4878aSAndroid Build Coastguard Workeraccess host exposed channels to start with the two for the initial 557*61c4878aSAndroid Build Coastguard Workerimplementation. These emulators also have good support for embedded targets 558*61c4878aSAndroid Build Coastguard Worker(with QEMU more focused on MMU class machines and renode fully focused on 559*61c4878aSAndroid Build Coastguard Workermicrocontrollers) and are widely used in this space for emulation purposes. 560*61c4878aSAndroid Build Coastguard Worker 561*61c4878aSAndroid Build Coastguard Worker 562*61c4878aSAndroid Build Coastguard WorkerPrior art 563*61c4878aSAndroid Build Coastguard Worker========= 564*61c4878aSAndroid Build Coastguard WorkerWhile there are several emulators frontends available, their main focus is on 565*61c4878aSAndroid Build Coastguard Workergraphical interfaces (`aqemu <https://sourceforge.net/projects/aqemu/>`_, 566*61c4878aSAndroid Build Coastguard Worker`GNOME Boxes <https://wiki.gnome.org/Apps/Boxes>`_, 567*61c4878aSAndroid Build Coastguard Worker`QtEmu <https://gitlab.com/qtemu/gui>`_, 568*61c4878aSAndroid Build Coastguard Worker`qt-virt-manager <https://f1ash.github.io/qt-virt-manager/>`_, 569*61c4878aSAndroid Build Coastguard Worker`virt-manager <https://virt-manager.org/>`_) and virtualization ( 570*61c4878aSAndroid Build Coastguard Worker`virsh <https://www.libvirt.org/>`_, 571*61c4878aSAndroid Build Coastguard Worker`guestfish <https://libguestfs.org/>`_). 572*61c4878aSAndroid Build Coastguard Worker`qemu-init <https://github.com/mm1ke/qemu-init>`_ is a qemu CLI frontend but since 573*61c4878aSAndroid Build Coastguard Workerit is written in bash it does not work on Windows nor is easy to retrofit it to 574*61c4878aSAndroid Build Coastguard Workeradd Python APIs for automation. 575*61c4878aSAndroid Build Coastguard Worker 576*61c4878aSAndroid Build Coastguard Worker.. inclusive-language: disable 577*61c4878aSAndroid Build Coastguard Worker 578*61c4878aSAndroid Build Coastguard WorkerThe QEMU project has a few `Python modules 579*61c4878aSAndroid Build Coastguard Worker<https://github.com/qemu/qemu/tree/master/python/qemu>`_ that are used 580*61c4878aSAndroid Build Coastguard Workerinternally for testing and debugging QEMU. :python:`qemu.machine.QEMUMachine` 581*61c4878aSAndroid Build Coastguard Workerimplements a QEMU frontend that can start a QEMU process and can interact with 582*61c4878aSAndroid Build Coastguard Workerit. However, it is clearly marked for internal use only, it is not published on 583*61c4878aSAndroid Build Coastguard Workerpypi or with the QEMU binaries. It is also not as configurable for pw_emu's 584*61c4878aSAndroid Build Coastguard Workeruse-cases (e.g. does not support running the QEMU process in the background, 585*61c4878aSAndroid Build Coastguard Workerdoes not multiple serial ports, does not support configuring how to expose the 586*61c4878aSAndroid Build Coastguard Workerserial port, etc.). The :python:`qemu.qmp` module is `published on pypi 587*61c4878aSAndroid Build Coastguard Worker<https://pypi.org/project/qemu.qmp/>`_ and can be potentially used by `pw_emu` 588*61c4878aSAndroid Build Coastguard Workerto interact with the emulator over the QMP channel. 589*61c4878aSAndroid Build Coastguard Worker 590*61c4878aSAndroid Build Coastguard Worker.. inclusive-language: enable 591*61c4878aSAndroid Build Coastguard Worker 592*61c4878aSAndroid Build Coastguard Worker--------------- 593*61c4878aSAndroid Build Coastguard WorkerDetailed design 594*61c4878aSAndroid Build Coastguard Worker--------------- 595*61c4878aSAndroid Build Coastguard WorkerThe implementation supports QEMU and renode as emulators and works on 596*61c4878aSAndroid Build Coastguard WorkerLinux, Mac and Windows. 597*61c4878aSAndroid Build Coastguard Worker 598*61c4878aSAndroid Build Coastguard WorkerMultiple instances are supported in order to enable developers who work on 599*61c4878aSAndroid Build Coastguard Workermultiple downstream Pigweed projects to work unhindered and also to run 600*61c4878aSAndroid Build Coastguard Workermultiple test instances in parallel on the same machine. 601*61c4878aSAndroid Build Coastguard Worker 602*61c4878aSAndroid Build Coastguard WorkerEach instance is identified by a system absolute path that is also used to store 603*61c4878aSAndroid Build Coastguard Workerstate about the running instance such as pid files for running processes, 604*61c4878aSAndroid Build Coastguard Workercurrent emulator and target, etc. This directory also contains information about 605*61c4878aSAndroid Build Coastguard Workerhow to access the emulator channels (e.g. socket ports, PTY paths) 606*61c4878aSAndroid Build Coastguard Worker 607*61c4878aSAndroid Build Coastguard Worker.. mermaid:: 608*61c4878aSAndroid Build Coastguard Worker 609*61c4878aSAndroid Build Coastguard Worker graph TD; 610*61c4878aSAndroid Build Coastguard Worker TemporaryEmulator & pw_emu_cli[pw emu cli] <--> Emulator 611*61c4878aSAndroid Build Coastguard Worker Emulator <--> Launcher & Connector 612*61c4878aSAndroid Build Coastguard Worker Launcher <--> Handles 613*61c4878aSAndroid Build Coastguard Worker Connector <--- Handles 614*61c4878aSAndroid Build Coastguard Worker Launcher <--> Config 615*61c4878aSAndroid Build Coastguard Worker Handles --Save--> WD --Load--> Handles 616*61c4878aSAndroid Build Coastguard Worker WD[Working Directory] 617*61c4878aSAndroid Build Coastguard Worker 618*61c4878aSAndroid Build Coastguard WorkerThe implementation uses the following classes: 619*61c4878aSAndroid Build Coastguard Worker 620*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.Emulator`: the user visible APIs 621*61c4878aSAndroid Build Coastguard Worker 622*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Launcher`: an abstract class that starts an emulator 623*61c4878aSAndroid Build Coastguard Worker instance for a given configuration and target 624*61c4878aSAndroid Build Coastguard Worker 625*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Connector`: an abstract class that is the interface 626*61c4878aSAndroid Build Coastguard Worker between a running emulator and the user visible APIs 627*61c4878aSAndroid Build Coastguard Worker 628*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Handles`: class that stores specific information about 629*61c4878aSAndroid Build Coastguard Worker a running emulator instance such as ports to reach emulator channels; it is 630*61c4878aSAndroid Build Coastguard Worker populated by :py:class:`pw_emu.core.Launcher` and saved in the working 631*61c4878aSAndroid Build Coastguard Worker directory and used by :py:class:`pw_emu.core.Connector` to access the emulator 632*61c4878aSAndroid Build Coastguard Worker channels, process pids, etc. 633*61c4878aSAndroid Build Coastguard Worker 634*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Config`: loads the pw_emu configuration and provides 635*61c4878aSAndroid Build Coastguard Worker helper methods to get and validate configuration options 636*61c4878aSAndroid Build Coastguard Worker 637*61c4878aSAndroid Build Coastguard Worker 638*61c4878aSAndroid Build Coastguard WorkerDocumentation update 639*61c4878aSAndroid Build Coastguard Worker==================== 640*61c4878aSAndroid Build Coastguard WorkerThe following documentation should probably be updated to use ``pw emu`` instead 641*61c4878aSAndroid Build Coastguard Workerof direct QEMU invocation: :ref:`module-pw_rust`, 642*61c4878aSAndroid Build Coastguard Worker:ref:`target-lm3s6965evb-qemu`. The referenced QEMU targets are defined in 643*61c4878aSAndroid Build Coastguard Workerfragment configuration files in the pw_emu module and included in the top level 644*61c4878aSAndroid Build Coastguard Workerpigweed.json file. 645*61c4878aSAndroid Build Coastguard Worker 646*61c4878aSAndroid Build Coastguard Worker------------ 647*61c4878aSAndroid Build Coastguard WorkerAlternatives 648*61c4878aSAndroid Build Coastguard Worker------------ 649*61c4878aSAndroid Build Coastguard WorkerUNIX sockets were investigated as an alternative to TCP for the host exposed 650*61c4878aSAndroid Build Coastguard Workerchannels. UNIX sockets main advantages over TCP is that it does not require 651*61c4878aSAndroid Build Coastguard Workerdynamic port allocation which simplifies the bootstrap of the emulator (no need 652*61c4878aSAndroid Build Coastguard Workerto query the emulator to determine which ports were allocated). Unfortunately, 653*61c4878aSAndroid Build Coastguard Workerwhile Windows supports UNIX sockets since Win10, Python still does not support 654*61c4878aSAndroid Build Coastguard Workerthem on win32 platforms. renode also does not support UNIX sockets. 655*61c4878aSAndroid Build Coastguard Worker 656*61c4878aSAndroid Build Coastguard Worker-------------- 657*61c4878aSAndroid Build Coastguard WorkerOpen questions 658*61c4878aSAndroid Build Coastguard Worker-------------- 659*61c4878aSAndroid Build Coastguard Worker 660*61c4878aSAndroid Build Coastguard WorkerRenode dynamic ports 661*61c4878aSAndroid Build Coastguard Worker==================== 662*61c4878aSAndroid Build Coastguard WorkerWhile renode allows passing 0 for ports to allocate a dynamic port, it does not 663*61c4878aSAndroid Build Coastguard Workerhave APIs to retrieve the allocated port. Until support for such a feature is 664*61c4878aSAndroid Build Coastguard Workeradded upstream, the following technique can be used to allocate a port 665*61c4878aSAndroid Build Coastguard Workerdynamically: 666*61c4878aSAndroid Build Coastguard Worker 667*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 668*61c4878aSAndroid Build Coastguard Worker 669*61c4878aSAndroid Build Coastguard Worker sock = socket.socket(socket.SOCK_INET, socket.SOCK_STREAM) 670*61c4878aSAndroid Build Coastguard Worker sock.bind(('', 0)) 671*61c4878aSAndroid Build Coastguard Worker _, port = socket.getsockname() 672*61c4878aSAndroid Build Coastguard Worker sock.close() 673*61c4878aSAndroid Build Coastguard Worker 674*61c4878aSAndroid Build Coastguard WorkerThere is a race condition that allows another program to fetch the same port, 675*61c4878aSAndroid Build Coastguard Workerbut it should work in most light use cases until the issue is properly resolved 676*61c4878aSAndroid Build Coastguard Workerupstream. 677*61c4878aSAndroid Build Coastguard Worker 678*61c4878aSAndroid Build Coastguard Workerqemu_gcc target 679*61c4878aSAndroid Build Coastguard Worker=============== 680*61c4878aSAndroid Build Coastguard WorkerIt should still be possible to call QEMU directly as described in 681*61c4878aSAndroid Build Coastguard Worker:ref:`target-lm3s6965evb-qemu` however, once ``pw_emu`` is implemented it is 682*61c4878aSAndroid Build Coastguard Workerprobably better to define a lm3s6965evb emulation target and update the 683*61c4878aSAndroid Build Coastguard Workerdocumentation to use ``pw emu`` instead of the direct QEMU invocation. 684*61c4878aSAndroid Build Coastguard Worker 685*61c4878aSAndroid Build Coastguard Worker 686*61c4878aSAndroid Build Coastguard Worker.. |nbsp| unicode:: 0xA0 687*61c4878aSAndroid Build Coastguard Worker :trim: 688