用ESP32作为你树莓派的Linux无线协处理器

Lobsters Hottest 工具

摘要

一份关于使用乐鑫的esp-hosted项目,将ESP32模块(如ESP32-C6/C5)通过SDIO或SPI接口变成Linux单板计算机的WiFi/BT协处理器的指南,为专有无线网卡提供了一个更开放的替代方案。

<p><a href="https://lobste.rs/s/x1ucie/esp32_as_your_raspberry_pi_s_linux">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/10/12 21:50

# 用 ESP32 做你的 Raspberry Pi Linux 无线协处理器 Source: https://hackaday.com/2026/10/07/esp32-as-your-raspberry-pis-linux-wireless-co-processor/ 如今没有无线连接的笔记本电脑已经很少见了——但当你选购性能强劲的 Linux 单板计算机(SBC)时,却发现不少产品在 WiFi 上偷工减料。与此同时,当前的无线网卡也常常令人失望:一堆专有固件、短暂甚至二进制的驱动程序、从未修复的奇怪故障,有时干脆就是带有过期时间的无源码 blob。也许你的 SBC 没有空闲的 USB 口来插即插即用的 WiFi 芯片,或者你不想为一个难以采购的小众邮票孔模块做设计。 如果我告诉你有一个独特的解决方案呢——只要你的 SBC 有一个空闲的 SDIO 或 SPI 接口就行?有一款无线网卡我们都可以试试看,它当然不完美,但给了我们更多的成长空间——它的固件相当开放,出自一家有信誉的公司,而且几乎保证货源充足。我说的当然是 `esp-hosted`——用 ESP32 模块通过 SDIO 或 SPI 作为你的 WiFi/BT 网卡。 我最近在项目中加入了 ESP32-C6,配置 `esp-hosted` 的过程并不轻松——所以这里有一份指南,顺便聊聊是什么让 `esp-hosted` 如此酷、如此充满前景。先剧透一下:它支持切断供电的隐私开关,它可以被改造成运行 mesh 协议的协处理器,它甚至可能帮助我们打造一块完全开源的 SDIO WiFi 网卡。 ## 两个分支,支持大多数芯片 先做一个快速说明:`esp-hosted` 屋檐下其实有两个项目(https://github.com/espressif/esp-hosted/)。 有 `esp-hosted-mcu`(之前叫 `esp-hosted-fg`,"第一代"),它将 ESP32 作为一个更偏 MCU 角色的芯片运行来连接 WiFi,并在 Linux 侧提供一个相对有限但自给自足的接口;连接层面的管理主要由 ESP32 模块完成,所以无论宿主机重启还是完全关机,它都会连接到你定义的 WiFi 网络。因此,`esp-hosted-mcu` 最适合微控制器,或者你希望 ESP32 成为一个完全独立运行的实体的情况。想让你的 ESP32 成为你的板子的 EC(嵌入式控制器),并附带 WiFi 连接功能?那就选 `-mcu` 版本。 `esp-hosted-linux`(之前叫 `esp-hosted-ng`,"新一代")将无线协议栈留在 Linux 侧,ESP32 作为 Linux 无线协议栈的一个相对轻薄的代理。我这里主要讨论 `esp-hosted-linux`,因为它在 Linux 下的行为方式最接近普通 WiFi 网卡的"原生"表现,不过本文的大部分内容同样适用于 `esp-hosted-mcu`。 `esp-hosted` 需要两个搭档:一台有空闲 SDIO 或 SPI 接口的 Linux 计算机,以及一个受支持的 ESP32 芯片/模块,我选了 ESP32-C6。普通的 ESP32-WROOM 模块就绰绰有余了,不过大多数更新的芯片也被支持。具体来说,ESP32-S2、-S3、-C2、-C3、-C5 和 -C6/C61 都可以与 `esp-hosted-linux` 配合使用。如果你用的是像 -S31 这样的芯片,可以查看父项目的 issue 跟踪器(https://github.com/espressif/esp-hosted/issues)。我选了 C6,因为当时我觉得它是支持功能最多的芯片,而且只比其他型号贵一点点,为什么不选呢?然而!这是一个错误,如果我重新设计一块板子,我会选 ESP32-C5。事实证明,尽管 C 编号更低,ESP32-C5 实际上比 ESP32-C6 更好,特别是它支持 5GHz。 接下来,你需要通过 SDIO 或 SPI 连接它——如果可以的话我推荐 SDIO,因为速度快得多。有一点要注意——确保你的 SBC 的 SDIO 接口被操作系统支持,而不是处于"硬件就绪,就差有人把驱动写出来"的尴尬状态,除非那个人就是你。如果你已经有一块开发板,可以在你认为是 SDIO 引脚上临时接一张 SD 卡来验证 SDIO 接口是否真的能工作! SDIO 本质上是一条全双工并行总线,包含一个控制信号(CMD)、一个时钟(CLK)和四条数据线(D0-D3)——如果你喜欢清修苦行,也可以只用一条数据线 D0。这些信号线翻转速度很快,而且不是差分对,所以你需要按单端信号的规则认真布局。我会写一篇更大的 SDIO 文章,但在此之前,请参考网上众多的 SDIO 布局教程。下面是一份参考原理图: 简短的 SDIO 布局建议:确保下方有连续的接地回流路径,尽量做好信号间的等长匹配(1mm 以内?),并尽可能缩短 SDIO 链路的走线长度。从 Pi Zero 或全尺寸 Pi 的 40 针排针引出 SDIO 时,有些信号需要大量等长匹配,有些则完全不需要——这是正常的,Raspberry Pi 的 GPIO 引脚排列就是这样,只需记住做好匹配即可。按照 ESP-Hosted 文档的要求,需要同时加入串联电阻和上拉电阻。 除了 SDIO 信号之外,你还需要控制 EN 引脚,这样驱动程序可以在开始通信之前将 ESP32 复位到已知良好的状态。如果 GPIO 不够用,也可以像 OLED 显示屏那样用经典的 RC 电路来处理 EN——驱动程序希望 EN 有供电,但并不是必须的,如果你自己处理 EN 的切换,可以在驱动初始化脚本中传入 `resetpin=-1`。 单面布局中同时放置上拉和串联电阻的示例 BOOT 引脚不需要担心。但你需要确保有足够的 3.3V 电源:300mA 到 400mA。Raspberry Pi 板上的 3.3V 电源轨一般足够为 ESP32 供电,但在其他 SBC 上,你可能需要额外添加一个 3.3V 稳压器来满足 ESP32 的 3.3V 需求。最后但同样重要的是,以某种方式引出 ESP32 的 USB 口,因为你需要用它来烧录固件。值得庆幸的是,固件只需要烧录一次。我个人把它引到了一个 4 针 JST-SH 接口上,引脚排列类似 QWIIC,可以在上面的原理图中看到。 ## 编译固件,或者不编译 你需要做三件事(https://github.com/espressif/esp-hosted-linux/blob/master/docs/porting_guide.md):确保你的 SBC 的 SDIO(或 SPI)接口已释放,编译并烧录 ESP32 固件,然后编译并加载驱动程序。不一定非要按这个顺序,但三件事你都得做。 在 Raspberry Pi 上释放 SDIO 接口相对容易:只需修改 `config.txt` 即可(https://github.com/espressif/esp-hosted-linux/blob/master/docs/setup.md#22-sdio-configuration)。你只需要重新映射 SDIO 引脚,如果板上已有 WiFi 网卡,还需要禁用其蓝牙功能。"禁用蓝牙"这一步很可能是必须的,因为板载 WiFi 网卡的固件是通过 SDIO 上传的,所以网卡的蓝牙部分反正也无法工作。这样做还能释放 Pi 上的 UART 控制台端口,如果你需要调试 WiFi 接口的初始化,这会非常有帮助!顺便说一句,我对 `poll_once=off` 这个 SD overlay 参数是否必需持怀疑态度,而且它确实会刷屏 `dmesg`。如果你需要清除那些刷屏信息,去掉这个轮询选项可能是个好办法。 在其他 SBC 上,你可能会在 SDIO 上遇到一些麻烦,但只要不是太小众的东西,应该问题不大。如果你在做自己的 SBC,而且有开发板,可以放心地将一个 microSD 卡座接到 SDIO 引脚上,按需加上拉电阻,用一张空闲的 microSD 卡来调试 SDIO 接口的初始化。如果 microSD 卡能正常工作,那 ESP32 大概率也能工作。 ESP32 固件的编译也相对简单。也许你不想在 SBC 上编译 ESP32 固件,因为 RAM 可能不够,执行 `cmake` 时会卡死。在 Pi Zero 上,卡死几乎是必然的。直接用你的台式电脑编译固件,省去这些麻烦。或者,你也可以跳过所有步骤,直接从 GitHub 的 Releases 页面下载固件(https://github.com/espressif/esp-hosted/releases)。目前这些发布版本还放在旧仓库中,但我预计最终新版本会放到 `esp-hosted-linux` 仓库中,敬请关注。 确保你的驱动程序是用与 ESP32 固件相同的 `esp-hosted` git 仓库版本编译的,可以使用 `git log` 之类的命令检查最后一次提交。否则,驱动会发出警告并拒绝加载。如果你认为版本差异太小,可以将该警告补丁掉,但风险自负。 ## 用老派方式完成的驱动 现在来说说驱动程序,你可能需要在 SBC 上直接编译驱动,除非你做交叉编译。`rpi_init.sh` 脚本会编译并加载驱动,其中还包含一些你可能觉得有用的注意事项。如果你的 SBC 内存只有 512MB 或更少——用编辑器打开 `rpi_init.sh`,找到 `make -j8` 命令(https://github.com/espressif/esp-hosted-linux/blob/master/host/rpi_init.sh#L65),将其替换为 `make -j2`(甚至 `-j1`)。否则,编译过程会耗尽内存并使你的 SBC 卡死。 现在所有东西都连接好了吗?如果 SDIO 配置正确且固件已烧录,驱动会成功加载,然后会出现一个 `wlan` 接口。出问题了?查看 `dmesg` 里的驱动模块调试输出。我喜欢在一个空闲的终端窗口中运行 `dmesg -Hw`,或者干脆让它在后台运行。 `rpi_init.sh` 脚本是调试的好工具,但当你想长期运行模块时,你就想甩掉它了,主要是因为它每次运行都会重新编译模块。在同一个目录下,你会发现 `esp_sdio.ko`——那就是你刚刚编译的 Linux 模块。这样做: ``` sudo cp esp_sdio.ko /lib/modules/$(uname -r)/kernel/drivers/ sudo depmod -a ``` 这可能有点 hack,但至少现在你可以用 `modprobe esp_sdio` 代替从脚本目录运行 `insmod` 了。然后你还可以把模块名(`esp_sdio`)写入 `/etc/modules`,让它每次启动时自动加载,这比重新运行脚本和随之而来的重新编译好太多了。 ## 能用,非常有前景 忘记加上拉电阻了,只能临时凑合 当然,还有一些需要改进的地方。首先,模块应该被正确集成到设备树接口中,这样就不需要手动添加到 `/etc/modules`,而是可以通过 overlay 自动加载。它也应该获得 `dkms` 集成,就像 esp8089 驱动的分发方式一样。目前,每次内核升级后你都需要重新编译并将模块重新放入内核模块目录,而 `dkms` 可以彻底解决这个问题。吞吐量还可以(https://github.com/espressif/esp-hosted-linux#5-throughput-performance),在默认 SDIO 频率下可以达到 40 Mbps 到 50 Mbps。如果你觉得你的硬件条件足够好,可以进一步压榨 SDIO 的极限,这里有一些可以调整的旋钮和参数(https://github.com/espressif/esp-hosted-linux/blob/master/docs/porting_guide.md#242-sdio)! ## 很酷的技巧,但是为什么呢? 那为什么要聊这个呢?有四个我认为重要的原因。首先,这是我知道的唯一一款能通过 SDIO 传递蓝牙而不是占用 UART 端口的 WiFi 网卡,这对 Pi Zero 尺寸的板子尤其有用。仅凭这一点就已经很酷了。 其次,虽然代码并不完美,而且有一大堆待处理的 pull request,但 `esp-hosted` 在我的项目中确实能正常处理硬件电源开关!ESP32 断电时不会导致内核模块崩溃或故障,它能无缝地断开和重新连接,硬件开关就是能正常工作,我觉得这一点非常可爱。 接下来的两个原因都与它本质上是一块开源固件 WiFi 网卡有关。ESP32 的固件并非完全开源,RF 部分按照惯例是闭源的,并以 blob 形式编译进去,但已经有一些(https://hackaday.com/2024/01/15/reverse-engineering-the-esp32s-wifi-binary-blob-with-a-faraday-cage/)相当了不起的(https://hackaday.com/2024/05/27/the-long-road-towards-reverse-engineering-the-esp32-wi-fi-driver/)项目(https://hackaday.com/2024/12/28/38c3-towards-an-open-wifi-mac-stack-on-esp32/)在尝试解放 ESP32 WiFi 协议栈中的专有部分。随着越来越多的人参与尝试,我们完全有可能将无处不在的 ESP32 模块变成完全开源固件的 Linux WiFi 网卡,价格极其低廉且随处可见。真正对黑客友好的持久型 WiFi 网卡,有什么理由不爱呢? 最后一个原因是最有趣的,甚至不需要去专有化。在完成 SDIO 接线之后,ESP32 还剩下很多空闲引脚,其中包括高速 SPI 引脚。谁说我们不能在上面接一个 LoRa 调制解调器来运行 Meshtastic/Meshcore 之类的呢?由于固件大部分是开源的,理论上可以在 WiFi/BT 的间隙中添加任何代码,然后将有意义的数据转发给 Linux 宿主机。而且我也没忽略新 ESP32 芯片原生支持 Zigbee 和 Thread,将这些功能暴露给 Linux 也只不过是写代码的事。对我来说,这才是最棒的部分——想象有一天我们可以把 ESP32 变成运行 Linux 的 CPU 的真正瑞士军刀式通信协处理器。

相似文章

多个项目发现 ESP32 微控制器中隐藏的 SDR 能力

Hacker News Top

多个独立项目在 ESP32 微控制器中发现了未文档化的固件功能,可实现原始 IQ 基带采集,从而将廉价的 Wi-Fi 芯片转变为覆盖 2.2–2.7 GHz、采样率高达 80 MS/s 的软件定义无线电(SDR)。这些项目包括 ESPARGOS、基于 ESP32-S3 加 FPGA 的流式采集方案,以及 C5VRX 5.8 GHz FPV 接收器。

ESP32-S31

Hacker News Top

Espressif 发布了 ESP32-S31,这是一款双核 RISC-V SoC,支持 Wi-Fi 6、蓝牙 5.4 LE、以太网以及高级安全功能,面向物联网和多媒体应用。