跳到正文
原文
Hacker News· joakimeriksson·· 5 小时前精选AI 评分26

esp32sim:支持在浏览器中运行 ESP32 固件的 Rust 指令级模拟器

Show HN: Esp32sim – Run ESP32 firmware in the browser

AI 导读

esp32sim 是用 Rust 写的 ESP32 指令级模拟器,可在浏览器(WebAssembly)里无需安装直接运行真实固件。

推荐理由

展示了在浏览器中指令级模拟 ESP32 固件的实现路径,含 ROM 启动、外设与 WiFi 模型,便于无硬件条件下验证。

正文 · AI 翻译

esp32sim — a smiling chip in an emulator window

esp32sim — 一个用 Rust 编写的 ESP32 模拟器:Xtensa (ESP32, S3) 和 RISC-V (C3, C6)

跨 Espressif 的两种 CPU 架构,对四款 ESP32 SoC 进行指令级模拟。 每款都能启动 真实的掩模 ROM、真实的二级引导程序以及未经修改的应用程序 镜像——无补丁固件、没有 stub 干扰——已建模足够多的 SoC 以端到端运行真实 项目。无云端,无账户。MIT 许可。

经典 ESP32 同样能在双 LX6 核上启动其 ECO3 ROM,并支持 GPIO、UART 和定时器;--board ttgo-tdisplay 增加了 LilyGO TTGO T-Display 的 ST7789 和按键。

ESP32-S3 ESP32-C3 ESP32-C6
CPU 2 × Xtensa LX7 @ 240 MHz 1 × RISC-V RV32IMC @ 160 MHz 1 × RISC-V RV32IMAC @ 160 MHz
Command esp32sim esp32sim-c3 esp32sim-c6
Core crate xtensa-lx7 riscv-rv32 riscv-rv32(+ A 扩展)
报告的全列表解码器校验 977 k 条指令,0 处不匹配 161 k 条指令,0 处不匹配 126 k 条指令,0 处不匹配
启动流程 ROM → bootloader → FreeRTOS → app ROM → bootloader → FreeRTOS → app ROM → bootloader → FreeRTOS → app
开发板 / 显示屏 ST7735、ST7701S 480×480 + 触摸、WS2812、摄像头、音频 无 — 仅控制台 通过 SPI+DMA 的 ST7789 172×320、WS2812,以及一个 802.15.4 能量检测替代
WiFi 虚拟 AP、WPA2、DHCP/DNS/NTP、NAT 至真实网络、HTTPS 同样的虚拟 AP 和网络:扫描、WPA2、DHCP、NAT(一个站点) 同样的虚拟 AP 和网络:扫描、WPA2、DHCP、NAT(一个站点,传统速率)
速度 块解释器 + AArch64 JIT,约 150–240 Minsn/s 纯解释器(尚无块缓存或 JIT)— 在 hello_world 上仍远超实时 同样的解释器
在浏览器中 是(WebAssembly) 是(WebAssembly) 是(WebAssembly)
报告的硬件比较 JTAG 跟踪,定时循环重新同步后 8000 步 控制台 diff,205/208 行一致 控制台 diff,203/204 行一致
状态 成熟 草案 — 参见 docs/esp32c3.md 草案 — 参见 docs/esp32c6.md

这些全列表和硬件计数描述的是较早的手动运行。CI 运行的是已签入的 采样解码器语料库和模拟器 golden 输出;它不包括外部全列表 测试。Xtensa objdump 测试不包括 PIE 操作数比较。硬件跟踪比较 规范化窗口异常并重新同步延时循环,因此并非不间断的 逐周期一致。参见 test scope、CI workflow、 Xtensa decoder test 和 hardware comparator。

SoC 大部分是共享的:C3 复用 S3 的 UART、USB-Serial/JTAG、systimer、定时器组、 GPIO、SPI flash 控制器、GDMA 和 SHA/AES/RSA 模型,并保持不变,同时加入自己的内存映射、 缓存控制器和中断矩阵;C6 同样复用这些模型,并加入自己的内存映射、PLIC 前端、L1 缓存、PCR 以及常开的 LP 模块。只有 CPU crate 是真正独立的。

在浏览器中试用,无需安装: https://mikroverk.github.io/esp32sim/ — S3 上运行 Linux, Touch-LCD-4B 面板及其 SID 播放器,口袋坦克 LLM 水族箱,以及 C3 和 C6 演示。

esp32sim/
  emu-core/       the Bus and Core traits, Trap, ClockTree, AArch64 encoder — shared by both cores
  esp-soc/        Machine<S: Soc>: scheduler, device time, console, scripts, web UI, loaders, boards —
                  one machine for every chip; a chip plugs in its cores, bus and interrupt routing;
                  the virtual WiFi access point, the network behind it and the NAT, for every chip
  esp-periph/     the peripheral IP the chips share (UART, systimer, TIMG, GPIO, SPI_MEM, GDMA, crypto,
                  I2S, RMT, I2C, …), the Device trait, and the device_set! table that mounts them
  ── ESP32-S3 (Xtensa LX7, dual core) ──
  xtensa-lx7/     decoder (sampled objdump checks plus optional full listings), interpreter
                  (windowed regs, loops, XEA2 exceptions/interrupts, FPU, MAC16, booleans,
                  PIE SIMD), basic-block interpreter, AArch64 JIT, objdump-compatible disassembler
  esp32s3/        SoC + boards: memory map, cache MMU, SPI flash/PSRAM, SHA/AES/RSA, RNG,
                  systimer, timer groups, interrupt matrix (per core), GPIO, USB-CDC,
                  UARTs, I2C, GDMA + I2S/LCD_CAM, RMT TX, regi2c, RTC WDT, WiFi MAC;
                  board/: atech14 / waveshare-cam / waveshare-lcd4b / waveshare-amoled18-v2 / none
  cli/            the `esp32sim` command line, every chip (`--chip`); `esp32sim-c3` / `esp32sim-c6` are alias binaries
  ── ESP32-C3 and ESP32-C6 (RISC-V, single core) ──
  riscv-rv32/     RV32IMAC decoder (sampled objdump checks), interpreter, disassembler
  esp32c3/        the C3 SoC: memory map, interrupt matrix, cache controller, RNG;
                  peripheral models shared with esp32s3 where the IP is identical
  esp32c6/        the C6 SoC: unified memory map and MMU, interrupt matrix + PLIC/INTPRI, L1 cache,
                  PCR, the LP blocks (reset cause, software reset, RTC timer), ASSIST_DEBUG,
                  the 802.15.4 and WiFi MACs
  tests/          golden-output regression tests and their fixtures (tests/README.md)
  ── shared ──
  wasm/           C-ABI crate wrapping all three Machines for the browser in one module
  web/            browser UI (board drawing, console, audio, camera) + emu.js/worker.js for wasm
  hw/             JTAG differential-test scripts against a real board, captured C3 and C6 consoles
  examples/       hello_world (IDF, S3, C3 and C6), waveshare-cam (autopling run script + photo),
                  wifi-station (S3), c6-wifi-station (builds for the S3, C3 and C6; the WiFi goldens'
                  firmware), c6-radio-dashboard (WiFi + 802.15.4 on the C6 board)
  tools/          PIE table generator (TRM-derived); bench.py (interleaved A/B benchmark);
                  wasm-build.sh (the WebAssembly module)

开发板 (ESP32-S3)

该 SoC 模型发出引脚级事件(GPIO 边沿、RMT 符号流、I2S 采样),由一个 BoardModel(esp-soc/src/board.rs)对其进行解释。--board atech14(默认)是 Atech 14 端口开发板,搭载 ST7735、WS2812 环形灯、编码器和按键;--board none 是裸模块——可运行任何 ESP32‑S3 固件,仅限控制台;--board waveshare-lcd4b 是 Waveshare ESP32‑S3‑Touch‑LCD‑4B(ST7701S 480×480 通过 LCD_CAM RGB 总线,连接 GT911 触摸、TCA9554 及编解码器),运行 esp32‑screen LVGL 面板并支持触摸;--board waveshare-amoled18-v2 是 Waveshare ESP32‑S3‑Touch‑AMOLED‑1.8 V2(CO5300 368×448 通过 QSPI,CST820 触摸);--board waveshare-cam 是 Waveshare ESP32‑S3‑CAM‑OV5640(CH32V003 IO 扩展器,OV5640 通过 SCCB,ES8311/ES7210 编解码器位于 I2C0,扬声器位于 I2S1,OV5640 位于 LCD_CAM DVP 端口)——端到端运行 waveshare-autopling 固件(IDF 5.5、16 MB Flash、8 MB octal PSRAM:--flash-mb 16 --psram-mb 8):来自 --cam-image 或浏览器的摄像头帧(图片上传/网络摄像头)→ 仿真 PIE SIMD 单元上的 esp‑dl 行人检测器 → 在 ES8311 上发出叮当声。详见 examples/waveshare-cam/。新增开发板 = 实现该 trait(gpio_changes、rmt_frame、i2c_devices、camera_frame……)。

atech14 演示所运行的 Pocket Synth 固件是一个独立项目:atech-firmware——一个使用 PlatformIO 构建的 SID 合成器,以及用于真实 .sid 曲目的 cRSID 播放器。本仓库携带它所生成的可烧录镜像,位于 web/wasm/fw/public/。

cargo build --release
FW=web/wasm/fw/public                       # the demo images the goldens and the web page run
./target/release/esp32sim --boot rom \
    --bootloader $FW/atech-bootloader.bin --ptable $FW/atech-ptable.bin --app $FW/atech-firmware.bin \
    --script $FW/atech-script1.txt --wav out.wav --tft-png tft.png --max-seconds 5

mask ROM ELF 取自 ~/.espressif/tools/esp-rom-elfs/*/esp32s3_rev0_rom.elf(随 ESP‑IDF 一同发布)。若不使用 ESP‑IDF,tools/fetch-demo-assets.sh --no-linux 会将 S3、C3 和 C6 的 ROM 放入 web/wasm/fw/:传入 --rom web/wasm/fw/esp32s3_rev0_rom.elf,或为测试设置 ESP32SIM_ROM_DIR=web/wasm/fw。--boot app 跳过 ROM 与引导加载程序,直接加载应用镜像。

一个普通的 ESP‑IDF 项目,例如 examples/hello_world(使用 idf.py set-target esp32s3 && idf.py build 构建的 IDF 5.5 get‑started 示例):

H=examples/hello_world/build
./target/release/esp32sim --board none --boot rom --console uart0 \
    --bootloader $H/bootloader/bootloader.bin --ptable $H/partition_table/partition-table.bin \
    --app $H/hello_world.bin --elf $H/hello_world.elf --elf $H/bootloader/bootloader.elf --max-seconds 26

在 UART0 上打印 ROM 横幅、引导加载程序和应用日志、Hello world!、倒计时,然后通过 RTC 看门狗复位——与实际芯片行为完全一致(rst:0xc (RTC_SW_CPU_RST)),速度约为实时 30 倍。芯片复位(软件、RTC 看门狗)会以正确的复位原因从 ROM 重新启动机器;而 --no-reboot 会在首次复位时停止。

运行 — ESP32‑C3

esp32sim-c3 在仿真的 RISC‑V 核心上运行未经修改的 ESP‑IDF 固件,从真实的 mask ROM 经由真实的引导加载程序进入 FreeRTOS。标志与 esp32sim 相同(--trace、--break、--watch、--peek、--disasm、--log-periph),并打印带有符号的 RISC‑V 助记符。

H=examples/hello_world-c3/build
./target/release/esp32sim-c3 --boot rom --flash-mb 4 \
    --bootloader $H/bootloader/bootloader.bin --ptable $H/partition_table/partition-table.bin \
    --app $H/hello_world.bin --elf $H/hello_world.elf --max-seconds 26

打印 ROM 横幅、引导加载程序日志、Hello world! 与重启,重复三次。已与实体 C3 模块逐行比对:三次启动周期内 208 行控制台输出中有 205 行完全相同——差异仅在于 ROM 的 Saved PC: 行。--mac、--reset-cause 和 --strap 使一次运行能够采用某块开发板的标识,从而使比较有意义。WiFi Station 模式支持开放和 WPA2 虚拟 AP,并具备 DHCP 与 NAT 功能。不支持开发板;--boot app 不受支持。请参阅 docs/esp32c3.md 以了解支持与不支持的功能,以及硬件所发现的五处模拟器缺陷。

运行 — ESP32‑C6

esp32sim-c6 是 ESP32‑C6 上的同一前端:RV32IMAC、PLIC、统一内存映射。

H=examples/hello_world-c6/build
./target/release/esp32sim-c6 --boot rom --flash-mb 4 \
    --bootloader $H/bootloader/bootloader.bin --ptable $H/partition_table/partition-table.bin \
    --app $H/hello_world.bin --elf $H/hello_world.elf --max-seconds 27

对照 Waveshare ESP32-C6-LCD-1.47 验证:三次启动循环中 204 行控制台有 203 行完全一致,包括 esp_restart() 之后 ROM 的 Saved PC:;唯一不同之处就是首次启动那一行。--board waveshare-c6-lcd147 增加了该开发板 —— 通过 SPI2 的 ST7789 与 GDMA、WS2812、BOOT 按键 —— 而 C6 的 802.15.4 MAC 能响应能量扫描,因此该开发板的 LVGL 频谱扫描固件可以端到端运行(examples/waveshare-c6-lcd147/)。MAC 还能以与无线信号一致的时序发送和接收帧,--cooja 则把 C6 变成 Cooja-NG 的外部节点,通过 NDJSON 实现精确同步驱动(一份未经修改的 Contiki-NG-on-IDF 镜像与仿真的 MSP430 节点交换广播)。WiFi 同样可用:--wifi 接入与 S3 相同的虚拟接入点(见下方 WiFi)。参见 docs/esp32c6.md。

脚本(仿真时间下的主机动作)

1.5  press btn1 150                       # GPIO17 low for 150 ms
2.2  knob cw 2                            # two quadrature detents on CLK5/DT4
3.4  press btn2 120
4.0  serial {"action":"set_note","value":"9"}   # into USB-CDC RX
5.0  stop

WiFi(ESP32-S3、C3、C6 以及经典 ESP32)

--wifi ssid=NAME[,psk=PASS,chan=N,bssid=..] 挂载一个虚拟接入点,未经修改的 Espressif WiFi 二进制能够与之关联 —— 扫描、认证、关联,以及在提供口令后完成 WPA2-PSK 四次握手 —— 并在其后方构建一个虚拟网络(DHCP、ARP、ICMP、DNS、从主机时钟出发的 SNTP)。--net nat(默认配置)通过普通主机套接字中继客户机的 TCP 与 UDP 数据,因此固件能够访问真实网络;--net none 则拒绝转发。无需修改固件,无需 root,无需 tun 设备。

./target/release/esp32sim --board waveshare-lcd4b --boot rom --flash-mb 16 --psram-mb 8 \
    --bootloader $P/bootloader/bootloader.bin --ptable $P/partition_table/partition-table.bin \
    --app $P/energy_panel.bin --console usb --wifi "ssid=home,psk=secret" --max-seconds 45

运行 esp32-screen 能耗面板:加入网络、获取租约、同步时钟、通过 HTTPS 拉取两天的电价,并在局域网上轮询真实的 Home Assistant。docs/networking-howto.md 为操作指南(参数、调试、限制);docs/wifi-plan.md 与 docs/networking-plan.md 介绍 MAC 模型与数据包路径的工作方式,而 docs/architecture.md 的网络章节则描述了每个芯片共用的层次。

ESP32-C6 通过自己的 MAC 模型加入同一接入点和同一网络(docs/wifi-c6-plan.md):一个站点、传统速率、不启用省电模式。examples/c6-wifi-station 是样例 —— 扫描、加入、租约、五次 ping 以及开发板屏幕上的状态 —— 而每次 C6 无线运行都需要 --stub bb_init=0(PHY 的基带校准需要模拟硬件):

B=examples/c6-wifi-station/build-emu
./target/release/esp32sim-c6 --boot rom --flash-mb 4 --board waveshare-c6-lcd147 --console usb \
    --bootloader $B/bootloader/bootloader.bin --ptable $B/partition_table/partition-table.bin \
    --app $B/c6_wifi_station.bin --elf $B/c6_wifi_station.elf --stub bb_init=0 \
    --wifi ssid=esp32sim,psk=esp32sim-pass --max-seconds 14

ESP32-C3 也通过源自 S3 的 MAC 模型加入同一接入点。同一站点示例(不带显示屏、为每个芯片编译)已作为 WiFi 黄金样本的输入提交到 web/wasm/fw/public/(cli/tests/goldens.rs 中的 wifi_station_{s3,c3,c6}),因此无需本地编译即可运行:

P=web/wasm/fw/public
./target/release/esp32sim-c3 --boot rom --flash-mb 4 --console usb \
    --bootloader $P/c3-wifi-bootloader.bin --ptable $P/c3-wifi-ptable.bin --app $P/c3-wifi_station.bin \
    --wifi ssid=esp32sim,psk=esp32sim-pass --max-seconds 14

examples/c6-radio-dashboard 在同一固件中分别运行 WiFi 与 802.15.4 能量扫描,各占一页。

在浏览器中(WebAssembly)

tools/wasm-build.sh                  # the module -> web/wasm/esp32sim.wasm
tools/fetch-demo-assets.sh           # mask ROMs, xterm.js and the Linux image (--no-linux skips its 16 MB)
python3 -m http.server -d web 8790   # then open http://127.0.0.1:8790/?wasm&fw=hello

演示固件已提交;掩模 ROM、xterm.js 和 Linux 镜像并未提交,每个演示都从 ROM 启动,因此只需执行一次获取操作即可。它获取到的文件与 Pages 站点所提供的相同。

同一个模拟器编译为 WebAssembly,在页面内的 Web Worker 中运行:选择一块开发板,从磁盘加载 ROM ELF 和固件(或 ?wasm&fw=<name> 加载托管清单),按 Boot 启动。hello_world、带 SID 播放器的 Touch-LCD-4B 面板、Atech 板、ESP32-C3 和 ESP32-C6 在 Chrome 中都能实时运行;没有 NAT(浏览器没有套接字)。S3 拥有自己的 WebAssembly JIT(热块与热区,WASM SIMD 上的 PIE)。参见 docs/wasm.md。在线演示:https://mikroverk.github.io/esp32sim/ —— ESP32-S3 上的 Linux 6.11(svermigo/Linux-on-esp32-S3,登录后在控制台输入),带 SID 播放器的 Touch-LCD-4B 面板、Atech 板、pocket-tank(在 Touch-AMOLED-1.8 上以 4 位 Transformer 引导小鱼的 pocket-tank),以及正在启动 hello_world 的 ESP32-C3 和 C6;也可以从磁盘为任意芯片加载自己的固件(选择开发板,或 esp32c3 / esp32c6)。

调试

--trace [--trace-from N], --break ADDR, --watch ADDR(当 word 变化时停止), --peek ADDR[,N], --profile(pc 直方图), --log-periph(每个未知寄存器的首次触碰), --stop-after-exceptions N, --gram-png(原始 ST7735 GRAM), --no-jit(解释执行而非运行原生代码——结果必须一致)。环境变量:ESP_EMU_DEBUG, ESP_EMU_DEBUG_SPI, ESP_EMU_DEBUG_USB, ESP_EMU_DEBUG_WIFI[_FRAMES], ESP_EMU_DEBUG_NET, ESP_EMU_DEBUG_AES, ESP_EMU_DEBUG_SHA, ESP_EMU_DEBUG_RSA。

文档

  • docs/adding.md — 添加外设、带器件的开发板、CPU/芯片、观察者

docs/ — 架构、外设覆盖情况、开发板、CLI 参考、Web UI 协议、设计决策与陷阱、路线图、网络使用指南、WiFi 与 网络 设计笔记,以及 测试 计划。

出处

根据 ESP‑IDF 寄存器头文件、ESP‑IDF 自带的 Xtensa 内核配置、RISC-V 规范以及 C3 和 C6 技术参考手册编写,并结合观测到的固件行为。仅参考 QEMU 来确认指令语义(未复制任何代码)。MIT 许可证。

针对真实芯片的差异性测试(hw/)

每颗芯片都通过不同方法对照硬件进行检查:S3 采用 JTAG 同步单步(见下文),C3 和 C6 通过对比捕获到的控制台输出与模拟器运行相同二进制的结果(hw/c3-hello-world-real.txt,205/208 行一致 —— 参见 docs/esp32c3.md;hw/c6-hello-world-real.txt,203/204 行一致 —— 参见 docs/esp32c6.md)。这些对比在每颗芯片上都发现了五个模拟器 Bug,包括设备命令竞态以及复位时未重新计数的周期计数器——这些是无开发板测试所无法发现的。

ESP32-S3,JTAG 同步单步

DIFF_DIR=hw/<board> FLASH_MB=8 hw/difftest.sh 3000 —— 脚本通过 JTAG 读取所连接芯片的 efuses/strapping 引脚,然后基于同一份 flash 镜像使芯片与模拟器同步单步(如果存在 flash-8M.bin)。Atech 板,2026-08-25:自复位起 3000 步,0 处偏差。

任何通过 USB 连接的 ESP32‑S3 开发板均可使用(其内置的 USB‑Serial/JTAG 同时承载控制台和 JTAG)。整个流程均为脚本化:

# one-time: dump the board's bootloader/partition table/app start (esptool) into hw/flash-0-1M.bin
hw/difftest.sh 8000                 # reset → single-step 8000 instructions on the chip and in the emulator, diff
hw/difftest-at.sh 403c8948 6000     # run both to a PC (here the 2nd-stage bootloader entry), then step 6000 and diff

difftest*.sh 读取芯片的 efuses(hw/efuse.txt)、strapping 引脚以及外设复位状态(hw/reset-regs.txt,通过 JTAG 在 reset halt 处导出),并从相同的镜像与状态启动模拟器。hw/compare.py 逐指令地 diff pc a0..a15 ps windowbase,屏蔽 PS.INTLEVEL(在单步期间被强制),隐藏窗口异常处理程序(调试器以原子方式单步跳过它们),并在 CCOUNT 计时的延时循环上重新同步——这些循环在每步耗时为毫秒级时迭代次数会不同。

目前的进展:ROM 复位路径(8000 步)以及 IDF 5.5 bootloader 的 3000+ 步运行结果与参考实现零 PC 分歧;剩余的寄存器差异是依赖前一次启动的 RTC 域值。

实电路板 UI(ESP32-S3)

./target/release/esp32sim --boot rom --bootloader … --ptable … --app … --web 8766
# open http://127.0.0.1:8766/

--web PORT 实时运行模拟器并提供 web/run.html:14 端口电路板(旋钮 + LED 环形灯、按钮、扬声器 VU 表、按实际方向放置并附带可读副本的 ST7735)、USB-CDC 和 UART0 控制台、SDK JSON 协议操作框,以及通过 WebAudio 输出的音频。输入方式:点击按钮、在旋钮上滚轮/拖动/←→、点击旋钮帽按下。

性能 / 实时性(ESP32-S3)

指令块一次性解码并从缓存中执行,然后编译为原生 AArch64 代码(--no-jit 回退到解释器时必须给出相同结果);空闲核心(waiti)会被跳过,设备时间根据计算出的定时器截止时间惰性投递,中断线路仅在源头变化时重新计算。每一步背后的测量数据见 docs/speed-plan.md。Pocket Synth 固件在空闲或演奏音符时都能带裕量地实时运行;唯一跟不上的地方是完整的显示屏重绘,此时 core 1 以 100% 占用率在位操作 SPI(每 20 ms 需要 4.8 M 指令——需 240 Minsn/s,在 M 系列 MacBook 上达到约 70 Minsn/s)。因此每次重绘会带来约 0.3 s 的延迟,UI 的自适应音频缓冲会吸收该延迟(在欠载时增长,最长 400 ms),之后由 pacer 恢复;如果模拟器落后超过 0.5 s,则会重新同步而不是集中追赶。顶部状态栏显示 real time、⚠ N s behind 和重新同步次数。

ESP_EMU_RT_LOG=1 打印每个耗时超过 40 ms 实际时间的 20 ms 窗口,包含两个核心的指令数和 PC。hw/wsdrive.py [port] [seconds] 在没有浏览器的情况下驱动 UI 协议(按钮按下 + 旋钮转动),并上报推送间隔、延迟和已输出的音频——可用它来衡量调度器的改动效果。

贡献

欢迎贡献。CONTRIBUTING.md 列出了 pull request 所需的检查(与 CI 运行的检查一致)以及测试、实验和证据的约定。

许可证

esp32sim 以 MIT 许可证 发布,版权所有 Joakim Eriksson(@joakimeriksson)、Alice(@aliceisjustplaying)和(@mfiumara)Mattia Fiumara。

第三方代码、数据和演示文件保留各自的许可证:

  • pocket-tank(mediacutlet/pocket-tank,MIT)。其 bootloader、分区表和 app 在 web/wasm/fw/public/ 中以 pocket-tank-LICENSE.txt 提交;其 model 是下载获取的。
  • MicroPython(micropython.org,MIT):T-Display 演示的官方 ESP32_GENERIC v1.29.0 镜像,由 tools/fetch-micropython.sh 下载获取,不提交到仓库;演示的 app 和文件系统位于 examples/ttgo-tdisplay,并包含 Russ Hughes 的 st7789py 驱动和字体(MIT),说明见 web/wasm/fw/public/tdisplay-NOTICE.txt。
  • Mask ROM ELFs(espressif/esp-rom-elfs,Apache-2.0),下载获取,不提交到仓库。
  • xterm.js(xtermjs/xterm.js,MIT),下载获取,不提交到仓库。
  • Linux 镜像(svermigo/Linux-on-esp32-S3,GPL-3.0),下载获取,不提交到仓库。
  • ESP-IDF ADC 校准数据(Espressif,Apache-2.0):来自 #165 的曲线拟合系数和 S3 ADC1 校准数据,现合并放在 esp-periph/src/sar_adc.rs 中;详见 esp-periph/LICENSE-ADC。

来源:Hacker News · github.com