【物联网设备端开发】ESP开发工具:QEMU的使用方法
概要
本文提供了一些运行QEMU的ESP特定说明。有关QEMU的一般使用问题,请参阅官方文档:https://www.qemu.org/documentation/.
编译 QEMU
准备工作
libgcrypt-devellibgcryptlibgcrypt配置
ninja./configure --target-list=xtensa-softmmu \
--enable-gcrypt \
--enable-slirp \
--enable-debug --enable-sanitizers \
--enable-sdl \
--disable-strip --disable-user \
--disable-capstone --disable-vnc \
--disable-gtk--disable./configure --help--enable-sdl--enable-gtk--enable-sdl--enable-gtk编译
ninjaninja -C buildbuild/qemu-system-xtensa编译ESP-IDF程序进行仿真
esptool.py merge_binesptool.pycd build
esptool.py --chip esp32 merge_bin --fill-flash-size 4MB -o flash_image.bin @flash_argsflash_argsmerge_bin--fill-flash-size 4MBQEMU中的ESP32目标支持大小为2、4、8和16MB的闪存,创建任何其他大小的镜像都会导致错误。
注意
flash_argsflash_argsbootloader.bin0x1000 bootloader/bootloader.binesptool.py 运行 QEMU
不加载GDB
如果你不需要调试客户应用程序,你可以在不加载GDB的情况下执行QEMU:
build/qemu-system-xtensa -nographic \
-machine esp32 \
-drive file=flash_image.bin,if=mtd,format=rawflash_image.bin使用GDB服务器,等待连接
-s -Sbuild/qemu-system-xtensa -nographic -s -S \
-machine esp32 \
-drive file=flash_image.bin,if=mtd,format=rawflash_image.bin然后,要连接GDB客户端,请使用以下命令:
xtensa-esp32-elf-gdb build/app-name.elf \
-ex "target remote :1234" \
-ex "monitor system_reset" \
-ex "tb app_main" -ex "c"app_mainc硬件加密支持
从IDF 4.1开始,默认启用以下硬件加密功能:AES、SHA、RSA。 所有这些都在QEMU中实现了ESP32目标。但是,请注意,SHA模拟目前不支持不同SHA类型的并发操作。
以太网口支持
ESP-IDF中添加了对Opencores以太网MAC的支持。
CONFIG_EXAMPLE_CONNECT_ETHERNETCONFIG_EXAMPLE_USE_OPENETHCONFIG_ETH_USE_OPENETHesp_eth_mac_new_openethopen_eth用户模式网络
例如,要在用户模式下启动网络(仅TCP/UDP,模拟设备位于NAT之后),请在QEMU命令行中添加以下选项:
-nic user,model=open_eth一些ESP项目(特别是运行TCP侦听器)可能需要设置端口转发,
-nic user,model=open_eth,id=lo0,hostfwd=tcp:127.0.0.1:PORT_HOST-:PORT_GUESThostfwd=tcp:127.0.0.1:22222-:2222nc localhost 2222指定引导模式
要指定所需的 strapping 模式, 在运行QEMU时需要添加以下参数:
-global driver=esp32.gpio,property=strap_mode,value=0x0fGPIO_STRAP0x120x0fSpecifying eFuse storage
Add extra arguments to the command line:
-drive file=qemu_efuse.bin,if=none,format=raw,id=efuse
-global driver=nvram.esp32.efuse,property=drive,value=efuseqemu_efuse.binefusenvram.esp32.efuseThe file must be created before starting QEMU:
dd if=/dev/zero bs=1 count=124 of=/tmp/qemu_efuse.bin124 bytes is the total size of ESP32 eFuse blocks.
Note
Specifying eFuse storage is mandatory to test out any platform security features like “Secure Boot” or “Flash Encryption”.
Emulating ESP32 ECO3
For the application to detect the emulated chip as ESP32 ECO3, the following virtual efuses must be set:
- CHIP_VER_REV1
- CHIP_VER_REV2
xxd -p000000000000000000000000008000000000000000001000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
00000000efuse.hexxxd -r -p efuse.hex qemu_efuse.binAlternatively, these bits can be set using espefuse:
espefuse.py --port=socket://localhost:5555 burn_efuse CHIP_VER_REV1
espefuse.py --port=socket://localhost:5555 burn_efuse CHIP_VER_REV2Disabling the watchdogs
By default, Timer Group watchdog timers are emulated, and TG0 WDT is enabled at reset. It is sometimes useful to disable these watchdog timers. This can be done by adding the following to the command line:
-global driver=timer.esp32.timg,property=wdt_disable,value=trueThis disables the emulation of TG watchdog timers. Even if the application configures them, they will not fire.
The RTC watchdog timer is not emulated yet, so it doesn’t need to be disabled.
Using esptool.py and espefuse.py to interact with QEMU
Start QEMU:
build/qemu-system-xtensa -nographic \
-machine esp32 \
-drive file=flash_image.bin,if=mtd,format=raw \
-global driver=esp32.gpio,property=strap_mode,value=0x0f \
-drive file=qemu_efuse.bin,if=none,format=raw,id=efuse \
-global driver=nvram.esp32.efuse,property=drive,value=efuse \
-serial tcp::5555,server,nowaitThe final line redirects the emulated UART to TCP port 5555 (QEMU acts as a server).
Type q and press Enter at any time to quit.
Run esptool.py:
esptool.py -p socket://localhost:5555 flash_ididf.pyexport ESPPORT=socket://localhost:5555
idf.py flashOr, run espefuse.py:
espefuse.py --port socket://localhost:5555 --do-not-confirm burn_custom_mac 00:11:22:33:44:55esptoolsystem_resetSpecifying ROM ELF file
-kernel-bios-bios Using flash encryption
Self-encryption workflow
CONFIG_SECURE_FLASH_ENC_ENABLEDmenuconfigBuild the flash image as per the instructions from the Compiling the ESP-IDF program to emulate section.
qemu_efuse.binqemu-system-xtensabuild/qemu-system-xtensa -nographic -machine esp32 \
-drive file=/path/to/qemu_efuse.bin,if=none,format=raw,id=efuse \
-global driver=nvram.esp32.efuse,property=drive,value=efuse \
-drive file=/path/to/flash_image.bin,if=mtd,format=raw \
-global driver=timer.esp32.timg,property=wdt_disable,value=trueAdding PSRAM
-m 2M-m 4MhimemUsing SD cards
QEMU emulates SD/MMC host controller used in ESP32. To add an SD card to the system, create an image and pass it to QEMU.
Create a raw image file, for example, 64 MB:
$ dd if=/dev/zero bs=$((1024*1024)) count=64 of=sd_image.binAdd the following argument when running QEMU:
-drive file=sd_image.bin,if=sd,format=rawcqow2qemu-imgOnly one SD card is supported at a time. You can use either slot 0 or slot 1 of the SD/MMC controller in the application code.
Enabling graphical user interface (GUI)
The ESP32 QEMU implementation implements a virtual RGB panel, absent on the real hardware, that can be used to show graphical interface. It is associated to a virtual frame buffer that can be used to populate the pixels to show. It is also possible to use the target internal RAM as a frame buffer.
To enable the graphical interface, while keeping the serial output in the console, use the following command line:
build/qemu-system-xtensa \
-machine esp32 \
-drive file=flash_image.bin,if=mtd,format=raw
-display sdl \
-serial stdiogtk-display sdl-display gtk
上一篇: 鸿蒙开发工程师需要学什么
