Hospedando um site em um microcontrolador de 8 bits
(maurycyz.com)- O site foi hospedado usando apenas um MCU AVR64DD32 de 8 bits, funcionando em um ambiente pequeno com CPU de 24MHz, 8KB de RAM e 64KB de Flash
- Como até o 10BASE-T é rápido demais para gerar sinais de Ethernet diretamente, foi usado o SLIP suportado pelo Linux para tratar um link USB-Serial como se fosse uma interface de rede
- O SLIP usa um método simples, encapsulando pacotes com
0xC0e escapando bytes especiais, o que o torna adequado para ligar um MCU ao Linux moderno - O IP ficou mais simples graças à fragmentação desativada, mas a implementação de TCP exigiu estados de conexão, retransmissão e tratamento de exceções, levando vários dias e ainda com bugs restantes
- O acesso externo usa uma estrutura indireta com VPS, WireGuard e proxy, repassando apenas requisições para
/mcu, e o custo do IPv4 público e a ausência de IPv6 aparecem como limitações centrais
Configuração para hospedar um site com AVR de 8 bits
- O AVR64DD32 é um MCU da família AVR de 8 bits, semelhante ao Atmega328 conhecido pelo Arduino, mas mais barato na mesma faixa de memória e oferecendo um único pino de programação e periféricos melhores
- Núcleo AVR único de 8 bits com até 24MHz
- 8KB de RAM estática, 64KB de Flash, 256 bytes de EEPROM
- Faixa de tensão de 1,8~5,5V, na faixa de preço de $1~$2
- Para conectar diretamente à internet só com o MCU, seria necessário gerar sinais de Ethernet, mas até o 10BASE-T mais lento é rápido demais para esse ambiente
- O 10BASE-T opera a 10Mbit/s e, por causa da codificação Manchester, vira 20Mbit na linha real
- A CPU do AVR64DD32 pode chegar a 24MHz, mas os periféricos e pinos de IO têm clock máximo de 12MHz, dificultando a geração direta do sinal
- O caminho padrão seria usar um chip Ethernet dedicado, mas isso exigiria esperar algumas semanas para concluir o projeto
- Como alternativa, foi usado SLIP (Serial Line Internet Protocol, RFC 1055) para colocar rede sobre um link serial
- Os pacotes são encapsulados com o byte
0xC0no início e no fim 0xC0dentro do pacote vira0xDB 0xDC, e0xDBexistente vira0xDB 0xDDpara evitar ambiguidade- Isso dá continuidade ao modelo antigo em que modems discados criavam links seriais sobre a linha telefônica e o computador fazia o processamento de rede por cima disso
- O Linux moderno também suporta SLIP, permitindo transformar um adaptador USB-Serial em interface de rede
- Exemplos de uso:
stty -F /dev/ttyUSB0 115200 raw cs8,slattach -m -F -L -p slip /dev/ttyUSB0
- Os pacotes são encapsulados com o byte
- O hardware do lado do MCU é simples e funciona até sem componentes externos
Implementação dos protocolos e tratamento do acesso público
- A implementação de IP ficou mais simples graças às restrições do ambiente moderno
- Para uma página chegar ao computador do usuário, os pacotes passam por várias redes, e cada um precisa de um cabeçalho IP de 40 bytes com endereço de origem, destino etc.
- No passado, o IP exigia muita memória para lidar corretamente com recursos como fragmentação de pacotes
- Sistemas operacionais modernos desativam a fragmentação, e o IPv6 a removeu, então não é necessário tratá-la diretamente
- Basta trocar origem e destino do pacote recebido e redefinir o contador TTL para montar o cabeçalho de resposta
- A implementação de TCP é bem mais difícil, porque precisa rastrear estados de conexão, retransmitir pacotes perdidos e lidar com várias situações excepcionais
- Foram necessários vários dias até a implementação TCP personalizada funcionar de forma suficientemente estável, e ainda restam alguns bugs
- O HTTP não foi implementado separadamente; o servidor sempre envia uma “resposta” hardcoded ao cliente
- Para um site com apenas uma URL, essa abordagem funciona bem o suficiente
- O processo de carregamento pode ser visto em Video 3
- O acesso externo exige um endereço IPv4 público e roteável, mas o custo e a qualidade da conexão doméstica viraram obstáculos
- A máquina com endereço público e roteável fica em uma VPS em um datacenter perto de Helsinki
- O WireGuard no Linux cria um link de rede virtual sobre a internet, funcionando mesmo quando um dos lados está atrás de CGNAT
- Assim, uma caixa roteadora Linux se conecta à VPS para obter uma conexão de internet mais adequada
- O MCU ainda não tem um IP público próprio, então encaminhar todas as requisições para o endereço da VPS quebraria o site existente
- Em vez disso, o servidor foi configurado para fazer proxy apenas das requisições sob
/mcupara o servidor MCU usando um bloco de endereços local - Os visitantes não se conectam diretamente à pilha TCP/IP do MCU, mas isso segue o mesmo modelo do Vape Server
- Isso torna um pouco mais difícil derrubar o serviço com pacotes SYN, mas na prática o servidor continua vulnerável a DDoS por estar sobre uma conexão quase de internet discada
- Em vez disso, o servidor foi configurado para fazer proxy apenas das requisições sob
- A ausência de IPv6 continua sendo a causa fundamental de toda essa estrutura indireta
- O IPv6 existe há 30 anos, mas a maioria das pessoas ainda não consegue acessá-lo
- /mcu: página hospedada no MCU
- http://ewaste.fka.wtf/: Vape Server hospedado em um MCU de 32 bits retirado do lixo eletrônico
- https://lcamtuf.substack.com/p/psa-if-youre-a-fan-of-atmega-try: texto de lcamtuf sobre a linha AVR Dx
1 comentários
Comentários do Hacker News
Há mais de 25 anos houve uma disputa meio exibicionista para criar o menor servidor web: https://web.archive.org/web/20000815063022/http://www-ccs.cs...
Quem “venceu” usou um microcontrolador ACE1101, mas não consegui encontrar o artigo original, embora exista isto aqui: https://conceptlab.com/fly/
Era um servidor web em cima de uma mosca
Foi muito divertido reduzir o código ao mínimo, e ao remover o ping apareceu espaço para bit-banged I2C e upload por UDP para EEPROM, continuando com menos de 1024 bytes
Gosto das séries AVR DD, EA e EB, mas os lançamentos mais recentes de chips da Microchip parecem um pouco preocupantes para os fãs de AVR: https://www.microchip.com/en-us/products/microcontrollers/32...
O PIC32 CM tem a maior parte dos recursos do AVR DD, como sistema de eventos, MVIO e operação em 5V, além de oferecer um núcleo ARM 32-bit M0+ maior e mais padrão
Isso me faz pensar que o AVR DD ficou um tanto ultrapassado. O AVR EA e o AVR EB parecem mais seguros, com ADC de 12 bits e ganho programável de 16x, e apesar de terem um pouco de ruído, são sensíveis até cerca de 50 microvolts, então são ADCs/sensores de corrente absurdamente bons
Por outro lado, isso também pode tornar a linha AVR mais popular. Fico me perguntando se a existência de um ARM32 Cortex M0+ compatível em pinos aumenta ou reduz a disposição de construir em cima da plataforma AVR
Pessoalmente, acho que os periféricos são o mais importante. O AVR DD provavelmente consome menos energia, especialmente em operação a 1,8V, mas não sei se isso por si só basta
O projeto em si é muito interessante, e o AVR DD continua sendo um ótimo chip de qualquer forma, então é bom ver alguém realmente usando
O 10BASE-T opera a 10 megabits/s e, por causa da codificação Manchester, vira 20 megabits na linha, mas o AVR EB tem um timer PLL x2, então talvez, com bastante insistência, dê para gerar codificação Manchester
Combinando LUT, periférico UART e um circuito de timer acelerado por PLL, talvez dê para empurrar codificação Manchester em alta velocidade, mas ainda preciso pensar melhor se chega a 20 Mbit
Mexer no caminho Cortex-M0 pode ser um sinal de que eles não querem continuar desenvolvendo gerações futuras da plataforma de 8 bits depois da Dx. Se levarem os mesmos recursos para outro núcleo de CPU, acho aceitável
Gostei de ver o HTML sendo transmitido em tempo real na página. Me lembrou da época do acesso discado, quando as imagens iam aparecendo devagar de cima para baixo
Lá dava para baixar várias músicas por conexão, primeiro por FTP e depois pelo Napster
Ao ver o título, minha primeira reação foi: “mas vários dispositivos embarcados/IoT já fazem algo assim”
Aqui vai um exemplo de 8051 com Ethernet 10/100 integrada: https://www.asix.com.tw/public/index.php/en/product/Microcon...
Achei duas coisas interessantes. Primeiro, existe uma errata de 2025 da RFC 1055 que não está incluída no www.c daqui. Essa errata mostra de forma bem convincente como o algoritmo de decodificação muda, e neste caso a outra ponta do link realmente é Linux
Segundo, o próximo destino provavelmente é a RFC 1144
A combinação ENC28J60 + PIC18 era exatamente o tipo de configuração que aparecia nos demos que a Microchip distribuía com frequência há 20 anos
Gostei que o proxy não sobrescreveu o cabeçalho server: da página
Já fiz algo parecido no passado com um Arduino Mega. O impressionante era como podia parecer bem convincente porque o cliente fazia boa parte do trabalho, enquanto o controlador só entregava o conteúdo a partir de um cartão uSD