Hosting a website on an 8-bit microcontroller

A deep dive into hosting a web server on an AVR64DD32 microcontroller with only 8KB of RAM, utilizing SLIP and a custom TCP/IP stack to overcome hardware limitations.
Hosting a website on an 8-bit microcontroller.
In today's episode of "dumb things to do with an AVR microcontroller":
My victim is the AVR64DD32 which is quite similar to the Atmega328 of Arduino fame. Compared to the older Atmega, these AVR DD lines are cheaper for the same memory, use a single programming pin and have nicer peripherals:
- CPU: Single 8-bit AVR core @ 24 MHz (max)
- RAM: 8 kB (static RAM)
- Flash: 64 kB
- EEPROM: 256 bytes
- Voltage: 1.8 - 5.5 Volts
- Cost: $1
So that's the computer (a rather spacious one at that) but it'll need an internet connection to host a website.
The obvious choice is Ethernet, but even the slowest version (10BASE-T) still runs at 10 megabits/second. Worse, it uses Manchester encoding: a zero is sent as "10" and a one as "01", so 10 megabits of data is actually 20 megabits at the wire. This is simply too fast for the AVR to generate. While its processor can run at 24 MHz, all the peripherals and IO pins max out at a 12 MHz clock.
The proper solution is to buy a dedicated ethernet chip, but ethernet is far from the only option. Serial Line Internet Protocol (RFC 1055) is a very old and very simple standard for running networks over serial. Before sending a packet, wrap it in 0xC0 bytes. This scheme was widely used for connecting to the internet in the olden days via dial-up modems.
SLIP is still supported by modern Linux, allowing a normal USB to Serial adapter to become a network interface. The hardware on the microcontroller's end is trivial. Because it only draws a few milliwatts, it can run the server off the serial adapter's 5 volt rail.
In order for a web page to get to a computer, it needs an IP header. Implementing it is easy: just swap around the source and destination of a received packet to generate the header for the response. The other protocol, TCP, is a lot harder: implementing it requires the microcontroller to track connection states and handle retransmissions. As for HTTP, the server always sends a hardcoded response back to the client.
To make it accessible publicly, I used a VPS as a proxy. I set up the server to proxy any requests under /mcu to the microcontroller using a local address block via WireGuard. It's not exactly high-speed, but it works.
Source: Hacker News
















