返回 2026-05-12
⚙️ 工程

在 AVR 微控制器上托管网站Hosting a website on an AVR

maurycyz.com·2026-05-11

Maurycy Zysk 演示了如何在 AVR64DD32 微控制器(类似 Arduino Atmega328)上搭建简易网站服务器。该设备配备 8KB RAM、64KB Flash 和 24MHz 单核 CPU,虽资源有限,但仍能运行基本 HTTP 服务,展示了嵌入式系统在极简场景下的可行性。

本期节目是“用8位微控制器做蠢事”:

MCU网站演示(如果发布到HN可能会宕机)

我的“受害者”是AVR64DD32,它与著名的Arduino Atmega328非常相似。 相比旧款Atmega,这些芯片在相同内存下更便宜,仅需一个编程引脚,且外围设备也更完善:

这就是计算机(而且相当宽敞),但它需要一个互联网连接来托管网站。

显而易见的选择是以太网,但即使是最低速版本(10BASE-T)仍能以10兆比特/秒运行。 更糟的是它使用曼彻斯特编码: 零被发送为“10”,一被发送为“01”,因此10兆比特的数据实际上在电线上传输的是20兆比特。

这对AVR来说太快了。 虽然它的处理器可以运行在24MHz,但所有外设和IO引脚最高只能达到12MHz。 (尽管有些其他8位芯片可以做到这一点)

正确的解决方案是从DigiKey购买专用的以太网芯片,但这意味着我要等几周才能完成这个项目。

...而且以太网远非唯一选择:

串行线路互联网协议(RFC 1055)是一个非常古老且简单的通过串行线路运行网络的协议:

在发送数据包之前,用0xC0字节将其封装起来。 如果数据包中包含任何0xC0字节,则将其替换为0xDB 0xDC。 为避免歧义,任何原有的0xDB字节都会被替换为0xDB 0xDD。

这种方案曾广泛用于通过调制解调器连接到互联网: 老式拨号调制解调器只需在电话线上建立串行链路,至于计算机如何处理则由计算机自行决定。

...这也是为什么SLIP至今仍在现代Linux中受支持的原因:

# Just a normal USB to Serial adapter
stty -F /dev/ttyUSB0 115200 raw cs8
slattach -m -F -L -p slip /dev/ttyUSB0
# ... and now it's a network interface

微控制器端的硬件极其简单:

它无需外部元件即可工作,但我想要一些指示灯,以及一个防呆二极管——以防我 inevitably 接反电源。

因为它只消耗几毫瓦功率,所以完全可以从串口适配器的5伏轨直接供电: 只用一根线真是太方便了。

现在它有了一个互联网连接,但这几乎算不上是一个真正的服务器。

为了让我的网页能到达你的电脑,它必须经过数十个不同的网络。

为此,每个数据包都包含一个IP头部: 40字节的内容包括源地址和目标地址,以及其他我不太关心的信息。

这个协议曾经复杂得多,具有像分片这样的功能,需要大量内存才能正确处理,但我不必担心: 每个现代操作系统都会禁用分片,而IPv6更是彻底移除了这一特性。

这使得实现变得非常简单: 只需交换接收到的数据包中的源与目标地址,就能生成响应的头部(并重置TTL计数器)。

另一个协议TCP则困难得多: 实现它要求微控制器跟踪连接状态、定期重传丢失的数据包,并处理大量边缘情况。

我花了几天时间才让自定义实现正常工作,目前仍有几个bug。

至于HTTP的实现,我没有做: 服务器总是向客户端返回一个硬编码的“响应”。 只要网站上只有一个URL,这样就没问题。

[视频:页面加载过程。详见web或files目录下的loading.mp4]

好了,但如果我想和朋友分享呢? 遗憾的是,要做到这一点,它需要一个公开可路由的IPv4地址。 这些地址不仅昂贵(数量有限),而且我在家里也搞不到好的互联网连接。

(不,Starlink 并不好用)

我确实有一台拥有公网可路由地址的机器, 但它位于赫尔辛基附近的数据中心: 我需要一条非常长的串口线……

Linux 还支持另一件很酷的事——WireGuard,它能在互联网上创建一个虚拟网络链路。 即使其中一台机器位于(CG)NAT 或其他网络障碍之后,也能正常工作。

问题解决了:

让 Linux 路由器通过 VPS 连接以获得正常的互联网访问?

……但 MCU 仍然没有自己的 IP 地址: 我可以把 VPS 的地址转发给它,但这会破坏我的正常网站。

相反,我设置了服务器,将 /mcu 路径下的所有请求代理到本地地址块中的服务器。 这意味着访客不会直接连接到 MCU 的 TCP/IP 栈…… 不过话说回来,这和 Vape Server 用的是同样的配置,也没人抱怨过。

(这也让通过发送 SYN 包来攻击稍微难一点, 但 DDoS 一个实际上是通过拨号方式连接的服务器,其实也不太难)

相关:

  • /mcu:从微控制器托管的页面。
  • http://ewaste.fka.wtf/:Vape Server,一个运行在从垃圾堆里捡来的 32 位 MCU 上的网站。
  • https://lcamtuf.substack.com/p/psa-if-youre-a-fan-of-atmega-try: lcamtuf 谈 AVR Dx 系列。
  • 需要完整排版与评论请前往来源站点阅读。