From d9983c0039d3a0ef2713c163cfc01c342ea9c5e6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 13 Dec 2023 11:58:49 +0800 Subject: [PATCH] feat(qemu): add a CLI option for graphics output --- docs/en/api-guides/tools/qemu.rst | 21 +++++++++++++++++++++ tools/idf_py_actions/qemu_ext.py | 20 ++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/docs/en/api-guides/tools/qemu.rst b/docs/en/api-guides/tools/qemu.rst index 48eba546c1..379d227d79 100644 --- a/docs/en/api-guides/tools/qemu.rst +++ b/docs/en/api-guides/tools/qemu.rst @@ -21,6 +21,9 @@ If you are using a different platform, you need to build QEMU from source. Refer Usage ----- +Running an Application +~~~~~~~~~~~~~~~~~~~~~~ + To run an IDF application in QEMU, use the following command: .. code-block:: console @@ -29,6 +32,9 @@ To run an IDF application in QEMU, use the following command: This command builds the application, starts QEMU and opens :doc:`IDF monitor `, connecting it to the emulated UART port. You can see the console output of the application and interact with it. IDF Monitor also provides automatic decoding of panic backtraces and UART core dumps. +Debugging +~~~~~~~~~ + To debug an application in QEMU, use the following command: .. code-block:: console @@ -62,3 +68,18 @@ It is also possible to run QEMU without the IDF Monitor: idf.py qemu In this case, the IDF Monitor is not used, and you can interact with QEMU process directly. To switch between the emulated UART console and QEMU console ("QEMU monitor"), use Ctrl-A shortcut. For example, to exit QEMU, press Ctrl-A, then type ``q`` and press Enter. You can use the QEMU console to enter commands, such as for inspecting registers and memory. + +Graphics Support +~~~~~~~~~~~~~~~~ + +QEMU supports a virtual framebuffer device. This device doesn't exist in the real {IDF_TARGET_NAME} hardware, but it can be used to test graphics applications in QEMU. + +To launch QEMU with a virtual framebuffer device enabled, use the following command: + +.. code-block:: console + + idf.py qemu --graphics monitor + +When the ``--graphics`` option is used, QEMU opens an additional window where the framebuffer contents are displayed. + +To use the virtual framebuffer device in your application, you can add the `espressif/esp_lcd_qemu_rgb `_ component to your project. This component provides an esp_lcd compatible driver for the virtual framebuffer device. diff --git a/tools/idf_py_actions/qemu_ext.py b/tools/idf_py_actions/qemu_ext.py index 6d0c23a41b..27797e087a 100644 --- a/tools/idf_py_actions/qemu_ext.py +++ b/tools/idf_py_actions/qemu_ext.py @@ -60,7 +60,7 @@ QEMU_TARGETS: Dict[str, QemuTarget] = { 'esp32c3': QemuTarget( 'esp32c3', 'qemu-system-riscv32', - 'qemu-riscv', + 'qemu-riscv32', '-M esp32c3', # Chip revision 0.3 binascii.unhexlify( @@ -157,7 +157,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: project_desc = json.load(f) return project_desc - def qemu(action: str, ctx: Context, args: PropertyDict, qemu_extra_args: str, gdb: bool) -> None: + def qemu(action: str, ctx: Context, args: PropertyDict, qemu_extra_args: str, gdb: bool, graphics: bool) -> None: project_desc = _get_project_desc(args, ctx) # Determine the target and check if we have the necessary QEMU binary @@ -186,7 +186,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: f.write(qemu_target_info.default_efuse) # Prepare QEMU launch arguments - qemu_args = [qemu_target_info.qemu_prog, '-nographic'] + qemu_args = [qemu_target_info.qemu_prog] qemu_args += qemu_target_info.qemu_args.split(' ') qemu_args += [ '-drive', f'file={bin_path},if=mtd,format=raw', @@ -202,8 +202,14 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: if qemu_extra_args: qemu_args += qemu_extra_args.split(' ') + if graphics: + qemu_args += ['-display', 'sdl'] + else: + qemu_args += ['-nographic'] + # Launch QEMU! if not options.bg_mode: + qemu_args += ['-serial', 'mon:stdio'] yellow_print('Running qemu (fg): ' + ' '.join(qemu_args)) subprocess.run(qemu_args) else: @@ -247,12 +253,18 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict: 'default': '', }, { - 'names': ['--gdb'], + 'names': ['-d', '--gdb'], 'help': ('Wait for gdb to connect. ' 'Use this option to run "idf.py qemu --gdb monitor" in one terminal window ' 'and "idf.py gdb" in another. The program will start running when gdb connects.'), 'is_flag': True, 'default': False, + }, + { + 'names': ['-g', '--graphics'], + 'help': 'Enable graphical window', + 'is_flag': True, + 'default': False, } ] }