AtomVM: como executar o código Elixir em um microcontrolador de 3 $

O AtomVM é uma pequena máquina virtual portátil que permite que o código BEAM seja executado em microcontroladores com menos de 500 KB de RAM, como o ESP32.

Isenção de responsabilidade: O AtomVM ainda não está pronto para produção, pode incendiar sua casa.

Então o que isso significa? Em poucas palavras, você pode atualizar o AtomVM em um ESP32 e executar o código Elixir / Erlang.

Por quê

Trabalho em tempo integral no Astarte, que é uma plataforma de IoT de código aberto escrita em Elixir, e também uso várias placas incorporadas para trabalhar e se divertir, portanto, enquanto trabalhava com uma placa ESP32, percebi que poderia ser interessante usar algumas das os conceitos legais por trás do Elixir em hardware incorporado, então iniciei o AtomVM.

Então, vamos nos concentrar nas especificações do ESP32 apenas por um momento:

  • Conectividade: Ethernet integrada, BLE e WiFi (802.11 b / g / n) + várias placas de desenvolvimento com um chip LoRa adicional
  • CPU: núcleo duplo, até 240 MHz
  • Memória: 520 KiB SRAM (incorporada)
  • Flash: geralmente 4 MiB
  • Potência: 5 µA de corrente de sono profundo

Erlang e Elixir são realmente bons em lidar com pacotes de rede (o ESP32 possui conectividade de rede), executando processos simultâneos (o ESP32 é de núcleo duplo), lidando com falhas (o software incorporado precisa ser confiável), escrevendo software testável (os testes iniciais durante o desenvolvimento são muito melhores do que a depuração no hardware real), permitindo o desenvolvimento rápido (que é um ponto de venda do Arduino), mas o OTP não foi projetado para ser executado em dispositivos de baixo custo.

Por exemplo, já existem dois grandes projetos que permitem que o código Elixir seja executado em dispositivos incorporados que são Nerves e GRiSP. No entanto, para executar, eles precisam de uma placa embarcada com Linux, como um Raspberry Pi (Nerves) ou uma placa personalizada com 64 MiB de RAM (GRiSP).

O AtomVM tenta superar essas limitações por design e permite o desenvolvimento do Elixir para dispositivos de baixo custo, como o ESP32.

Como

O AtomVM tenta usar a menor quantidade possível de memória por design, graças a alguns truques, como a execução de todo o código existente na memória flash (que geralmente é mapeada na memória).

Alguns recursos não são implementados, enquanto outros são opcionais, por exemplo, o suporte a ponto flutuante pode não ser necessário em alguns casos de uso, como também números inteiros de precisão arbitrária podem não ser necessários nesses dispositivos.

Por último, mas não menos importante, a biblioteca padrão é reduzida para economizar preciosa memória flash.

Como piscar um led com Elixir

Piscar um LED é o programa "olá mundo" da computação física, então vamos começar com ele:

… Mas espere um segundo, antes de iniciar, certifique-se de ter todos os componentes necessários:

Hardware:

  • Uma placa de programação ESP32 com um LED (é possível comprar uma por menos de 10 €)
  • Caso sua placa ESP32 não possua um LED integrado: um LED, poucos cabos e uma placa de ensaio

Programas:

  • Erlang / OTP 20 (OTP 21 também deve estar bem)
  • Compilador Elixir (1.6 / 1.7 deve estar bem)
  • esp-idf (v3.1)
  • CMake
  • arquivos de desenvolvimento do zlib
  • gperf

Compilando e piscando o AtomVM na placa ESP32

Basta conectar sua placa e certifique-se de que $ IDF_PATH aponte para o diretório esp-idf e seu SDK esp-idf já esteja configurado. Se você estiver usando o macOS, Fred Dushin criou um excelente post no blog.

~ Clone do $ git https://github.com/bettio/AtomVM.git
~ $ cd AtomVM
~ / AtomVM $ cd src / plataformas / esp32
~ / AtomVM / src / plataformas / esp32 $ make flash
~ / AtomVM / src / plataformas / esp32 $ cd ../../ ..

Compilando e piscando código Elixir

O Blink.ex pode ser compilado usando o elixirc:

$ elixirc Blink.ex

Depois de compilado, você deve ter o Elixir.Blink.beam, que é o módulo compilado real.

No entanto, o Elixir.Blink.beam não é suficiente, ele precisa ser compactado com todos os módulos necessários em um arquivo .avm.

~ / AtomVM $ cd libs / estdlib
~ / AtomVM / libs / estdlib $ erlc * .erl
~ / AtomVM / libs / estdlib $ cd ../exavmlib/
~ / AtomVM / libs / exavmlib $ elixirc GPIO.ex
~ / AtomVM / libs / exavmlib $ cd ../ ..
~ / AtomVM $ cmake.
~ / AtomVM $ cd tools / packbeam
~ / AtomVM / tools / packbeam $ make
~ / AtomVM / tools / packbeam $ cd ../ ..
~ / AtomVM $ tools / packbeam / PackBEAM caminho blink.avm / para / Elixir.Blink.beam libs / estdlib / *. Beam libs / exavmlib / *. Beam
~ / AtomVM $ $ IDF_PATH / components / esptool_py / esptool / esptool.py --chip esp32 --port / dev / ttyUSB0 --baud 115200 - antes do default_reset - após hard_reset write_flash -u --flash_mode dio --flash_freq 40m --flash_size detect 0x110000 blink.avm

Por uma questão de clareza, não fizemos uma compilação fora da fonte, mas você deveria.

Portabilidade e hardware suportado

No momento, apenas sistemas * nix e placas ESP32 são suportados, no entanto, o AtomVM foi projetado para ser facilmente portátil: todo o código específico da plataforma é mantido em uma biblioteca, portanto, a portabilidade do AtomVM para um novo sistema operacional ou novo hardware deve ser bastante simples. O próprio núcleo do AtomVM é construído como uma biblioteca, para que possa ser incorporado a um projeto maior.

O AtomVM também possui realmente poucas dependências, requer ~ 40 funções libc e uma biblioteca zlib opcional.

O suporte para mais plataformas está próximo, incluindo o STM32.

Contribuindo

Contribuições são bem-vindas, basta bifurcá-lo no github e enviar uma solicitação de recebimento. Os problemas de "boa primeira questão" são um bom ponto de partida; também existem problemas de "ajuda desejada" para desenvolvedores qualificados (um deles é a porta do Windows).

Novos problemas também são bem-vindos, fique à vontade para abri-los se encontrar algum bug ou perder algum recurso.

O futuro

Mais recursos estão chegando no futuro próximo, como diversão, mapas, melhor tratamento de erros, suporte a vários núcleos e uma reescrita completa do coletor de lixo.

Outros desenvolvimentos estão planejados e serão implementados no futuro, como suporte a shell remoto, troca de código quente, clustering, etc.

… E é claro que também postarei mais histórias sobre o AtomVM, portanto, fique ligado :)