xref: /aosp_15_r20/external/pigweed/seed/0108.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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