当前位置: 首页 > news >正文

【物联网设备端开发】ESP开发工具:QEMU的使用方法

概要

本文提供了一些运行QEMU的ESP特定说明。有关QEMU的一般使用问题,请参阅官方文档:https://www.qemu.org/documentation/.

编译 QEMU

准备工作

在此之前,请查看有关构建先决条件的QEMU文档。如果你在Linux主机上构建QEMU,你可以参考 这篇文章.
请确保您的系统上安装了libgcrypt ( Ubuntu 中的libgcrypt-devel, Arch 中的 libgcrypt, macOS Homebrew 中的libgcrypt ).

配置

要生成 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 命令获取。

If you need a graphical interface for the virtual machine, make sure to provide --enable-sdl or --enable-gtk or both.
如果您需要虚拟机的图形界面,请添加 --enable-sdl--enable-gtk配置,或两者都添加。

编译

成功配置项目后,可以使用 ninja 来构建它:

ninja -C build

编译可能需要几分钟,具体取决于之前启用或禁用的组件。编译完成后,会创建build/qemu-system-xtensa 可执行文件。

编译ESP-IDF程序进行仿真

QEMU for ESP32 target is ready, it already includes the first stage bootloader, located on the ROM on the real chip, which is mainly responsible for initializing the peripherals, like the UART and, more importantly, the SPI Flash. The latter must contain the second stage bootloader and the program to run.

Thus, in this section, we are going to create a flash image that combines the (second stage) bootloader, the partition table and the application to run. This can be done using esptool.py merge_bin command, supported in esptool.py 3.1 or later. Let’s suppose that the ESP-IDf project has just been compiled successfully, the following commands will create that flash image:

cd build
esptool.py --chip esp32 merge_bin --fill-flash-size 4MB -o flash_image.bin @flash_args

Here, flash_args is a file generated by ESP-IDF build system in the build directory, it contains the list of names of binary files and corresponding flash addresses. merge_bin command takes this list and creates the binary image of the whole flash. --fill-flash-size 4MB argument specifies the total flash size.

ESP32 target in QEMU supports flash of size 2, 4, 8 and 16MB, creating an image with any other size will result in an error.

Notes

  • For “Secure Boot” feature in ESP-IDF, we recommend separate command to flash bootloader and hence flash_args file do not have corresponding entry. However, you may modify flash_args file to add entry for bootloader.bin as per below:

    0x1000 bootloader/bootloader.bin
    
  • It is also possible to use esptool.py to “flash” the application into QEMU, but QEMU needs to be started with the right strapping mode. See Bootstrapping Mode section below for more info.

Run QEMU

Without attaching GDB

If you don’t need to debug the guest application, you can execute QEMU without attaching GDB to it:

build/qemu-system-xtensa -nographic \-machine esp32 \-drive file=flash_image.bin,if=mtd,format=raw

Where flash_image.bin is the SPI flash image generated previously.

With GDB server, waiting for a connection

If you need to debug the guest application, you can execute QEMU with -s -S options. This tells QEMU not to start the CPU after initializing the virtual machine. It will wait for a connection from a GDB client:

build/qemu-system-xtensa -nographic -s -S \-machine esp32 \-drive file=flash_image.bin,if=mtd,format=raw

Where flash_image.bin is the SPI flash image generated previously.

Then, to connect the GDB client, use the following command:

xtensa-esp32-elf-gdb build/app-name.elf \-ex "target remote :1234" \-ex "monitor system_reset" \-ex "tb app_main" -ex "c"

The last line sets a breakpoint in app_main function of the guest application and starts the virtual CPU with c. If you need to put a breakpoint in any other functions or if you don’t need to start the CPU directly, please adapt this last line.

GDB and toolchain compatibility

If you are using esp2021r1 or an earlier toolchain release, GDB may report the following error when connecting to QEMU:

Remote 'g' packet reply is too long (expected 420 bytes, got 628 bytes):

In that case, you need to set the following environment variable beforehand:

export QEMU_XTENSA_CORE_REGS_ONLY=1

When this environment variable is set, QEMU will only send the values of non-privileged registers to GDB.

If you are using later releases of Xtensa toolchain, i.e. esp-2021r2 and later, GDB will work out-of-the-box, without the need to set this environment variable.

Hardware crypto support

Starting from IDF 4.1, the following hardware crypto features are enabled by default: AES, SHA, RSA.

All of them are implemented in QEMU for ESP32 target. However, please note that the SHA emulation currently doesn’t support concurrent operations with different SHA types.

Ethernet support

Support for Opencores Ethernet MAC in ESP-IDF is added in https://github.com/espressif/esp-idf/commit/31dac92e5f0daac98190fd603df213a0a25a3807.

  • When running protocols examples, enable CONFIG_EXAMPLE_CONNECT_ETHERNET and CONFIG_EXAMPLE_USE_OPENETH.
  • When running a custom app, enable CONFIG_ETH_USE_OPENETH and initialize the Ethernet driver as it is done in examples/common_components/protocol_examples_common/connect.c (look for esp_eth_mac_new_openeth).

When starting QEMU, use open_eth network device.

User mode networking

For example, to start networking in user mode (TCP/UDP only, emulated device is behind NAT), add the following option to the QEMU command line:

-nic user,model=open_eth

Some ESP projects (specifically running TCP listeners) might need port forwarding to be setup,

-nic user,model=open_eth,id=lo0,hostfwd=tcp:127.0.0.1:PORT_HOST-:PORT_GUEST

(e.g. asio-echo-server sets up a server on 2222 by default, so hostfwd=tcp:127.0.0.1:2222-:2222 enables to nc localhost 2222 from host machine)

Bridge/tap networking

  • Tap networking

Specifying bootstrapping mode

To specify the desired strapping mode, it is necessary to add the following argument when running QEMU:

-global driver=esp32.gpio,property=strap_mode,value=0x0f

This sets the value of GPIO_STRAP register.

  • Use 0x12 for flash boot mode (default)
  • Use 0x0f for UART-only download mode (since the SDIO part is not implemented)

Specifying 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=efuse

The first argument creates a block device backed by qemu_efuse.bin file, with identifier efuse. The second line configures nvram.esp32.efuse device to use this block device for storage.

The file must be created before starting QEMU:

dd if=/dev/zero bs=1 count=124 of=/tmp/qemu_efuse.bin

124 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

Here is the corresponding efuse file (in hexadecimal, produced using xxd -p):

000000000000000000000000008000000000000000001000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
00000000

To convert this (efuse.hex) back to binary, run xxd -r -p efuse.hex qemu_efuse.bin.

Alternatively, 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_REV2

Disabling 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=true

This 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

  1. 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,nowait
    

    The 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.

  2. Run esptool.py:

    esptool.py -p socket://localhost:5555 flash_id
    

    Flashing with idf.py also works:

    export ESPPORT=socket://localhost:5555
    idf.py flash
    
  3. Or, run espefuse.py:

    espefuse.py --port socket://localhost:5555 --do-not-confirm burn_custom_mac 00:11:22:33:44:55
    

Note: esptool can not reset the emulated chip using the RTS signal, because the state of RTS is not transmitted over TCP to QEMU. To reset the emulated chip, run system_reset command in QEMU console (started at step 1).

Specifying ROM ELF file

If -kernel and -bios arguments are not given, ESP32 (rev. 3) ROM code will be loaded. This ROM code binary is included in the repository. To specify the ROM code ELF file to load, pass the filename with a -bios <filename> argument.

Using flash encryption

Self-encryption workflow

  1. In the IDF application, enable CONFIG_SECURE_FLASH_ENC_ENABLED through menuconfig, and build it
  2. Build the flash image as per the instructions from the Compiling the ESP-IDF program to emulate section.
  3. Create qemu_efuse.bin as highlighted in the Specifying eFuse storage section.
  4. Execute qemu-system-xtensa using the following command:
    build/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=true
    

Adding PSRAM

QEMU “memory size” option can be used to enable PSRAM emulation. By default, no PSRAM is added to the machine. You can add 2MB or 4MB PSRAM using -m 2M or -m 4M command line options, respectively.

Note that PSRAM MMU is not emulated yet, so things like bank switching (himem in IDF) do not work.

Using 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.

  1. Create a raw image file, for example, 64 MB:

    $ dd if=/dev/zero bs=$((1024*1024)) count=64 of=sd_image.bin
    
  2. Add the following argument when running QEMU:

    -drive file=sd_image.bin,if=sd,format=raw
    

If you need to create a large SD card image, it is recommended to use sparse cqow2 images instead of raw ones. Consult QEMU manual about qemu-img tool for details.

Only 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 stdio

If gtk backend was enabled when compiling QEMU, it is possible to replace -display sdl with -display gtk

相关文章:

【物联网设备端开发】ESP开发工具:QEMU的使用方法

概要 本文提供了一些运行QEMU的ESP特定说明。有关QEMU的一般使用问题&#xff0c;请参阅官方文档&#xff1a;https://www.qemu.org/documentation/. 编译 QEMU 准备工作 在此之前&#xff0c;请查看有关构建先决条件的QEMU文档。如果你在Linux主机上构建QEMU&#xff0c;你…...

c++中std::endl 和“\n“ 这两个换行符有什么区别

std::endl 和 "\n" 都用于在C中生成换行符&#xff0c;但它们之间有一些重要的区别 std::endl&#xff1a; 功能&#xff1a;输出一个换行符&#xff0c;并刷新输出流&#xff08;即缓冲区&#xff09;。作用&#xff1a;确保所有数据立即输出到目的地&#xff0c;例…...

http中get和post怎么选

5.4.2.怎么选择1.如果你是想从服务器上获取资源&#xff0c;建议使用GET请求&#xff0c;如果你这个请求是为了向服务器提交数据&#xff0c;建议使用POST请求。2.大部分的form表单提交&#xff0c;都是post方式&#xff0c;因为form表单中要填写大量的数据&#xff0c;这些数据…...

数据分析及应用:快手直播间人员在线分析

目录 0 需求描述 1、进入直播间的高峰期为?(以进入用户数衡量) 2、晚上 11 点,哪个直播间的进入人数最多? 3、20:00-23:00,娱乐类、搞笑类,进入人数最多直播间分别是? 4、娱乐类、搞笑类,人均在线时长(退出时间-进入时间)最长的直播间分别是? 5、同时在线人数…...

【Python】nn.nn.CircularPad1、2、3d函数和nn.ConstantPad1、2、3d函数详解和示例

前言 在深度学习中&#xff0c;尤其是在处理图像、音频或其他多维数据时&#xff0c;数据填充&#xff08;Padding&#xff09;是一个常见的操作。填充不仅可以保持数据的空间维度&#xff0c;还能在卷积操作中避免信息丢失。PyTorch提供了多种填充方式&#xff0c;其中nn.Cir…...

LearnOpenGL——混合、面剔除

LearnOpenGL——混合、面剔除 混合 Blending一、丢弃片段 Alpha Test二、混合 Alpha Blending渲染顺序 面剔除一、环绕顺序二、面剔除 混合 Blending OpenGL中&#xff0c;混合(Blending)通常是实现物体透明度(Transparency)的一种技术。透明的物体可以是完全透明的&#xff0…...

视频网站为何热衷于SCDN

视频网站为何热衷于SCDN&#xff1f;随着互联网技术的飞速发展&#xff0c;视频网站已成为人们日常生活中不可或缺的一部分。无论是观看高清电影、热门剧集&#xff0c;还是直播体育赛事、游戏竞技&#xff0c;视频网站都以其丰富的内容和便捷的访问方式吸引了无数用户。然而&a…...

Redis与DataBase保持数据一致性

文章目录 1. 读取数据2. 写数据2.1 先操作缓存2.2 先操作数据库 在我们系统中缓存最常用的策略是&#xff1a;服务端需要同时维系DB和Cache&#xff0c;并且是以DB的结果为准&#xff0c; Cache-Aside Pattern&#xff08;缓存分离模式、旁路缓存&#xff09;。 1. 读取数据 当…...

解决 MacOS 连接公司 VPN 成功但是不能网络的问题

目录 解决办法2024 Mac mini 爆料 解决办法 操作比较简单&#xff0c;修改配置文件即可&#xff08;如果没有则需要手动创建&#xff09;。 sudo vim /etc/ppp/options在此文件下&#xff0c;加入 plugin L2TP.ppp&#xff1a; plugin L2TP.ppp如果文件里有l2tpnoipsec&…...

【Kubernetes】k8s集群之Pod容器资源限制和三种探针

目录 一、Pod容器的资源限制 1.资源限制 2.Pod 和容器的资源请求与限制 3.CPU 资源单位 4.内存资源单位 二、Pod容器的三种探针 1.探针的三种规则 2.Probe支持三种检查方法&#xff1a; 一、Pod容器的资源限制 1.资源限制 当定义 Pod 时可以选择性地为每个容器设定所…...

从古代驿站体系看软件安全管控@安全历史04

在古代&#xff0c;车、马都很慢&#xff0c;信息传递很不顺畅&#xff0c;中央的政令又是如何传达至地方的呢&#xff1f;实际上&#xff0c;很多朝代都有专门的驿站制度&#xff0c;可以保障全国各地的信息传递&#xff0c;对于维护统治和稳定有着关键作用。 若将国家比作一个…...

8.8 哈希表简单 1 Two Sum 141 Linked List Cycle

1 Two Sum class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {//给的target是目标sum 要返回vector<int> res(2,0);是在num中找加数//首先假设每个输入都是由唯一的结果&#xff0c;而且不适用相同的元素两次一共有n*(n-1)种…...

动态规划之——背包DP(完结篇)

文章目录 概要说明分组背包模板例题1思路code模板例题2思路code 有依赖的背包问题模板例题思路code 背包问题求方案数模板例题思路code 背包问题求具体方案模板例题思路code 概要说明 本文讲分组背包、有依赖的背包、 背包问题求方案数以及背包问题求具体方案 入门篇(01背包和…...

Advanced IP Scanner - 网络扫描工具介绍

Advanced IP Scanner 是一款免费、快速且用户友好的网络扫描工具。它能够帮助用户扫描局域网&#xff08;LAN&#xff09;中的所有设备&#xff0c;提供详细的设备信息&#xff0c;包括IP地址、MAC地址、设备名称和厂商信息。该工具对IT管理员和普通用户都非常有用&#xff0c;…...

数据库事务的四大特性ACID

数据库事务的四大特性ACID 数据库事务&#xff08;Transaction&#xff09;是数据库管理系统&#xff08;DBMS&#xff09;执行过程中的一个逻辑单位&#xff0c;由一个或多个SQL语句组成&#xff0c;这些语句作为一个整体一起向系统提交&#xff0c;要么全部执行&#xff0c;…...

ELK架构介绍

一、ELK简介 ELK 是由三个开源软件组成的&#xff0c;分别是&#xff1a;Elasticsearch、Logstash和Kibana&#xff0c;这三个软件各自在日志管理和数据分析领域发挥着重要作用。Elasticsearch提供分布式存储和搜索能力&#xff1b;Logstash负责数据收集和处理&#xff0c;而K…...

Vscode下ESP32工程函数定义无法跳转

1.删除.vscode 2.按下 ctrlshiftp&#xff0c;搜索 ESP-IDF:Add vscode Configuration Folder...

liquibase.exception.LockException: Could not acquire change log lock.

项目场景&#xff1a; 启动应用花了好长时间&#xff0c;最后报出异常. 问题描述 启动应用花了好长时间&#xff0c;最后报出异常. 异常&#xff1a; Caused by: liquibase.exception.LockException: Could not acquire change log lock. Currently locked by LAPTOP-OQ9VB…...

【多线程-从零开始-捌】阻塞队列,消费者生产者模型

什么是阻塞队列 阻塞队里是在普通的队列&#xff08;先进先出队列&#xff09;基础上&#xff0c;做出了扩充 线程安全 标准库中原有的队列 Queue 和其子类&#xff0c;默认都是线程不安全的 具有阻塞特性 如果队列为空&#xff0c;进行出队列操作&#xff0c;此时就会出现阻…...

数据结构——栈(Stack)

目录 前言 一、栈的概念 1、栈的基本定义 2、栈的特性 二、栈的基本操作 1.相关操作概念 2.实现方式 &#xff08;1&#xff09;顺序栈 &#xff08;2&#xff09;链式栈 三、栈的应用 总结 前言 栈&#xff08;Stack&#xff09;是一种常见且重要的数据结构&#xff0c;它遵循…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...