feat(qemu): add a CLI option for graphics output

This commit is contained in:
Ivan Grokhotkov 2023-12-13 11:58:49 +08:00
parent 459422f75f
commit d9983c0039
No known key found for this signature in database
GPG Key ID: 1E050E141B280628
2 changed files with 37 additions and 4 deletions

View File

@ -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 <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 <https://components.espressif.com/components/espressif/esp_lcd_qemu_rgb>`_ component to your project. This component provides an esp_lcd compatible driver for the virtual framebuffer device.

View File

@ -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,
}
]
}