1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_emu-design: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker====== 4*61c4878aSAndroid Build Coastguard WorkerDesign 5*61c4878aSAndroid Build Coastguard Worker====== 6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module-subpage:: 7*61c4878aSAndroid Build Coastguard Worker :name: pw_emu 8*61c4878aSAndroid Build Coastguard Worker 9*61c4878aSAndroid Build Coastguard Worker----------- 10*61c4878aSAndroid Build Coastguard WorkerParallelism 11*61c4878aSAndroid Build Coastguard Worker----------- 12*61c4878aSAndroid Build Coastguard Worker 13*61c4878aSAndroid Build Coastguard Worker``pw_emu`` supports running multiple instances simultaneously. This is helpful 14*61c4878aSAndroid Build Coastguard Workerfor developers who work on multiple downstream Pigweed projects or who want 15*61c4878aSAndroid Build Coastguard Workerto run multiple tests in parallel on the same machine. 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard WorkerEach instance is identified by a system absolute path that is also used to store 18*61c4878aSAndroid Build Coastguard Workerstate about the running instance such as ``pid`` files for running processes, 19*61c4878aSAndroid Build Coastguard Workercurrent emulator and target, etc. This directory also contains information about 20*61c4878aSAndroid Build Coastguard Workerhow to access the emulator channels, e.g. socket ports, PTY paths, etc. 21*61c4878aSAndroid Build Coastguard Worker 22*61c4878aSAndroid Build Coastguard Worker.. mermaid:: 23*61c4878aSAndroid Build Coastguard Worker 24*61c4878aSAndroid Build Coastguard Worker graph TD; 25*61c4878aSAndroid Build Coastguard Worker TemporaryEmulator & pw_emu_cli[pw emu cli] <--> Emulator 26*61c4878aSAndroid Build Coastguard Worker Emulator <--> Launcher & Connector 27*61c4878aSAndroid Build Coastguard Worker Launcher <--> Handles 28*61c4878aSAndroid Build Coastguard Worker Connector <--> Handles 29*61c4878aSAndroid Build Coastguard Worker Launcher <--> Config 30*61c4878aSAndroid Build Coastguard Worker Handles --Save--> WD --Load--> Handles 31*61c4878aSAndroid Build Coastguard Worker WD[Working Directory] 32*61c4878aSAndroid Build Coastguard Worker 33*61c4878aSAndroid Build Coastguard Worker----------- 34*61c4878aSAndroid Build Coastguard WorkerAPI surface 35*61c4878aSAndroid Build Coastguard Worker----------- 36*61c4878aSAndroid Build Coastguard Worker 37*61c4878aSAndroid Build Coastguard WorkerThe implementation uses the following classes: 38*61c4878aSAndroid Build Coastguard Worker 39*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.frontend.Emulator` - The user-visible API. 40*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Launcher` - An abstract class that starts an 41*61c4878aSAndroid Build Coastguard Worker emulator instance for a given configuration and target. 42*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Connector` - An abstract class that is the 43*61c4878aSAndroid Build Coastguard Worker interface between a running emulator and the user-visible APIs. 44*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Handles` - A class that stores specific 45*61c4878aSAndroid Build Coastguard Worker information about a running emulator instance such as ports to reach emulator 46*61c4878aSAndroid Build Coastguard Worker channels; it is populated by :py:class:`pw_emu.core.Launcher` and 47*61c4878aSAndroid Build Coastguard Worker saved in the working directory and used by 48*61c4878aSAndroid Build Coastguard Worker :py:class:`pw_emu.core.Connector` to access the emulator channels, 49*61c4878aSAndroid Build Coastguard Worker process PIDs, etc. 50*61c4878aSAndroid Build Coastguard Worker* :py:class:`pw_emu.core.Config` - Loads the ``pw_emu`` configuration and 51*61c4878aSAndroid Build Coastguard Worker provides helper methods to get and validate configuration options. 52*61c4878aSAndroid Build Coastguard Worker 53*61c4878aSAndroid Build Coastguard Worker------------------- 54*61c4878aSAndroid Build Coastguard WorkerEmulator properties 55*61c4878aSAndroid Build Coastguard Worker------------------- 56*61c4878aSAndroid Build Coastguard WorkerThe implementation exposes the ability to list, read, and write emulator 57*61c4878aSAndroid Build Coastguard Workerproperties. The frontend does not abstract properties in a way that is 58*61c4878aSAndroid Build Coastguard Workeremulator-independent or even emulator-target-independent, other than mandating 59*61c4878aSAndroid Build Coastguard Workerthat each property is identified by a path. Note that the format of the path is 60*61c4878aSAndroid Build Coastguard Workeralso emulator-specific and not standardized. 61*61c4878aSAndroid Build Coastguard Worker 62*61c4878aSAndroid Build Coastguard Worker---- 63*61c4878aSAndroid Build Coastguard WorkerQEMU 64*61c4878aSAndroid Build Coastguard Worker---- 65*61c4878aSAndroid Build Coastguard WorkerThe QEMU frontend is using `QMP <https://wiki.qemu.org/Documentation/QMP>`_ to 66*61c4878aSAndroid Build Coastguard Workercommunicate with the running QEMU process and implement emulator-specific 67*61c4878aSAndroid Build Coastguard Workerfunctionality like reset, list properties, reading properties, etc. 68*61c4878aSAndroid Build Coastguard Worker 69*61c4878aSAndroid Build Coastguard WorkerQMP is exposed to the host through two channels: a temporary one to establish 70*61c4878aSAndroid Build Coastguard Workerthe initial connection that is used to read the dynamic configuration (e.g. TCP 71*61c4878aSAndroid Build Coastguard Workerports, PTY paths) and a permanent one that can be used throughout the life of 72*61c4878aSAndroid Build Coastguard Workerthe QEMU processes. The frontend is configuring QEMU to expose QMP to a 73*61c4878aSAndroid Build Coastguard Worker``localhost`` TCP port reserved by the frontend and then waiting for QEMU to 74*61c4878aSAndroid Build Coastguard Workerestablish the connection on that port. Once the connection is established the 75*61c4878aSAndroid Build Coastguard Workerfrontend reads the configuration of the permanent QMP channel (which can be 76*61c4878aSAndroid Build Coastguard Workereither a TCP port or a PTY path) and save it as a channel named ``qmp`` in the 77*61c4878aSAndroid Build Coastguard Worker:py:class:`pw_emu.core.Handles` object. 78*61c4878aSAndroid Build Coastguard Worker 79*61c4878aSAndroid Build Coastguard Worker------ 80*61c4878aSAndroid Build Coastguard WorkerRenode 81*61c4878aSAndroid Build Coastguard Worker------ 82*61c4878aSAndroid Build Coastguard WorkerThe Renode frontend uses `robot port 83*61c4878aSAndroid Build Coastguard Worker<https://renode.readthedocs.io/en/latest/introduction/testing.html>`_ to 84*61c4878aSAndroid Build Coastguard Workerinteract with the Renode process. Although the robot interface is designed for 85*61c4878aSAndroid Build Coastguard Workertesting and not as a control interface, it is more robust and better suited to 86*61c4878aSAndroid Build Coastguard Workerbe used as a machine interface than the alternative ``monitor`` interface which 87*61c4878aSAndroid Build Coastguard Workeris a user-oriented, ANSI-colored, echoed, log-mixed, telnet interface. 88*61c4878aSAndroid Build Coastguard Worker 89*61c4878aSAndroid Build Coastguard WorkerBugs 90*61c4878aSAndroid Build Coastguard Worker==== 91*61c4878aSAndroid Build Coastguard WorkerWhile Renode allows passing ``0`` for ports to allocate a dynamic port, it does 92*61c4878aSAndroid Build Coastguard Workernot have APIs to retrieve the allocated port. Until support for such a feature 93*61c4878aSAndroid Build Coastguard Workeris added upstream, the implementation is using the following technique to 94*61c4878aSAndroid Build Coastguard Workerallocate a port dynamically: 95*61c4878aSAndroid Build Coastguard Worker 96*61c4878aSAndroid Build Coastguard Worker.. code-block:: py 97*61c4878aSAndroid Build Coastguard Worker 98*61c4878aSAndroid Build Coastguard Worker sock = socket.socket(socket.SOCK_INET, socket.SOCK_STREAM) 99*61c4878aSAndroid Build Coastguard Worker sock.bind(('', 0)) 100*61c4878aSAndroid Build Coastguard Worker _, port = socket.getsockname() 101*61c4878aSAndroid Build Coastguard Worker sock.close() 102*61c4878aSAndroid Build Coastguard Worker 103*61c4878aSAndroid Build Coastguard WorkerThere is a race condition that allows another program to fetch the same port, 104*61c4878aSAndroid Build Coastguard Workerbut it should work in most light use cases until the issue is properly resolved 105*61c4878aSAndroid Build Coastguard Workerupstream. 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard Worker---------------- 108*61c4878aSAndroid Build Coastguard WorkerMore pw_emu docs 109*61c4878aSAndroid Build Coastguard Worker---------------- 110*61c4878aSAndroid Build Coastguard Worker.. include:: docs.rst 111*61c4878aSAndroid Build Coastguard Worker :start-after: .. pw_emu-nav-start 112*61c4878aSAndroid Build Coastguard Worker :end-before: .. pw_emu-nav-end 113