はじめに
以前、AtomVM に思い切って挑戦してみたものの、当時は細部を理解せずに進めた部分も多くありました。
そこで今回は、環境構築に焦点を絞り、とくに ビルド済みイメージを活用した導入手順をまとめておきたいと思います。
AtomVM に少しでも興味を持った方の参考になれば幸いです。
対象環境・機材
今回の開発環境・使用機材は以下の通りです。
開発ボード
-
Seeed Studio XIAO ESP32-S3
- オンボードLEDあり(GPIO 21, 負論理)
開発用PC
- Debian 系 Linux(LMDE6)
- Elixir 1.17(Erlang/OTP 27)
- AtomVM 0.6.6(ビルド済みバイナリを使用)
- esptool 5.0(ESP32向け公式フラッシュ書込ツール)
- picocom 3.1(シリアルモニタ)
- python 3.13 (Python 製のツールを利用するため)
※ esptool は Python 製のツールです。Python 3.x が事前にインストールされている必要があります。
※今回は「AtomVM を自分でビルドしない」構成のため、ESP-IDF の導入は不要です。
※ AtomVM が公式に動作確認している Erlang/OTP や Elixir のバージョンについては、以下の Release Notes をご参照ください。
esptool のインストール
ESP32 にファームウェアを書き込むための公式ツールです。
pip で簡単にインストールできます。バージョン 5.x 系ではオプション表記が変更されているため、誤って古いものをインストールしないようバージョンの範囲を明示しましょう。
今回は、管理がしやすく、最新版にも追従しやすい pip 経由でのインストールを行います。
pip install "esptool>=5,<6"
バージョン 5.x 系では、オプション表記がハイフン形式へ変更されているため、>=5
を指定しています。
また、Python 3.x の環境が必要です
ポート名(接続先デバイス)の確認
ESP32 デバイスを USB ケーブルで接続すると、Linux 側で自動的にシリアルデバイス(仮想シリアルポート)が認識されます。このとき、どのポート名が割り当てられたかを確認しておく必要があります。
この情報は、後ほど esptool
や mix atomvm.esp32.flash
の --port
オプションに指定するために使います。
# 接続直後のメッセージを確認
dmesg | grep tty
esptool インストール後の動作確認
esptool が正しくインストールされ、ESP32 デバイスと通信できる状態かどうかを簡単に確認してみましょう。
# esptool のバージョンを確認
esptool.py version
# フラッシュの製造情報などを取得(接続テストにも使える)
esptool.py -p /dev/ttyACM0 flash-id
※ ポート名は適宜、事前に確認したものに置き換えてください。
AtomVM ファームウェアのダウンロードと書き込み
ここからは、ビルド済みの AtomVM イメージ(v0.6.6)を ESP32-S3 に書き込んでいきます。
公式の GitHub Releases に掲載されている .img
ファイルを使うことで、自分でビルドする必要はありません。
イメージのダウンロード
以下のコマンドで、GitHub Releases にあるビルド済みファームウェアを取得できます:
# ダウンロード先は任意
mkdir -p $HOME/Projects/atomvm && cd $_
curl -LO https://github.com/atomvm/AtomVM/releases/download/v0.6.6/AtomVM-esp32s3-elixir-v0.6.6.img
フラッシュメモリの消去
書き込み前にフラッシュメモリを全消去することが推奨されています。
esptool.py --chip auto --port /dev/ttyACM0 --baud 921600 erase-flash
AtomVM ファームウェアの書き込み
esptool.py --chip auto --port /dev/ttyACM0 --baud 921600 \
write_flash 0x0 $HOME/Projects/atomvm/AtomVM-esp32s3-elixir-v0.6.6.img
AtomVM の公式ドキュメントでは、ESP32-S3 向けファームウェアの書き込みアドレス(bootloader offset)として 0x0
が指定されています。
そのため、この .img
イメージもアドレス 0x0
に書き込む必要があります。
Elixir アプリケーションの作成と転送
ESP32-S3 に AtomVM を書き込んだら、次はいよいよ Elixir アプリケーション の出番です。
ここでは、LED を点滅させる Blinky
を作成・転送して動作確認します。
サンプルコードを取得
まずは、AtomVM 公式の Elixir サンプル集 から Blinky
プロジェクトを取得します。
# サンプルプロジェクトの保存場所は任意
cd $HOME/Projects/atomvm
git clone https://github.com/atomvm/atomvm_examples.git
cd atomvm_examples/elixir/Blinky
依存ライブラリ(exatomvm)を取得:
mix deps.get
GPIO ピン番号を変更(XIAO ESP32-S3 用)
Seeed Studio XIAO ESP32-S3 のオンボード LED は GPIO 21
に接続されています。
デフォルトのサンプルは GPIO 2
なので、以下のように修正します。
defmodule Blinky do
@pin 21
def start() do
:gpio.set_pin_mode(@pin, :output)
loop(@pin, :low)
end
defp loop(pin, level) do
:io.format(~c"Setting pin ~p ~p~n", [pin, level])
:gpio.digital_write(pin, level)
Process.sleep(1000)
loop(pin, toggle(level))
end
defp toggle(:high), do: :low
defp toggle(:low), do: :high
end
.avm
書き込み位置(flash offset)を指定
flash_offset: 0x250000
は、公式の AtomVM ファームウェアイメージが期待する .avm
の書き込み位置です。
この値を指定しないと、書き込んでも起動時に認識されないので注意が必要です。
次に、.avm
ファイルを書き込む位置(flash offset)を明示するため、mix.exs
を以下のように設定します。
defmodule SampleApp.MixProject do
use Mix.Project
def project do
[
app: :sample_app,
version: "0.1.0",
elixir: "~> 1.13",
start_permanent: Mix.env() == :prod,
deps: deps(),
atomvm: atomvm()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:exatomvm, git: "https://github.com/atomvm/ExAtomVM/"}
]
end
def atomvm do
[
start: SampleApp,
flash_offset: 0x250000 # ← このオフセットが重要
]
end
end
アプリケーションのパッキング(.avm
生成)
以下のコマンドで、Elixir アプリケーションを AtomVM 用の .avm
形式に変換します:
mix atomvm.packbeam
成功すると、以下のような .avm
ファイルが生成されます。
$ ls -l *.avm
.rw-r--r-- 51k mnishiguchi 31 Aug 21:56 Blinky.avm
.rw-r--r-- 50k mnishiguchi 31 Aug 21:56 deps.avm
.rw-r--r-- 40 mnishiguchi 31 Aug 21:56 priv.avm
この .avm
ファイルが、ESP32-S3 上で実行可能な AtomVM アプリケーションになります。
ESP32-S3 への書き込み
以下のコマンドで、先ほど生成した .avm
ファイルを ESP32-S3 に転送します。
mix atomvm.esp32.flash --port /dev/ttyACM0
これだけでアプリケーションの更新ができます。
AtomVM 本体は再書き込み不要です。.avm
アプリケーションだけを何度でも差し替え可能です。
シリアルモニタによるログ確認
Blink アプリでは、LED を点滅させるだけでなく、AtomVM 側からログ出力も行われます。
シリアルモニタを使って、ログを確認してみましょう。
picocom を使う方法
軽量でシンプルなシリアルモニタ picocom を使います。
picocom /dev/ttyACM0 --baud 115200
- 終了方法:
Ctrl+A
→Ctrl+X
- 起動直後にログが表示されない場合、ボードをリセットするか
.avm
を再転送してみてください。
おわりに
今回は、ビルド済み AtomVM イメージを使って、ESP32-S3 上で Elixir 製アプリケーションを動かすところまでを一通り体験しました。
「ファームウェアの書き込み」や「.avm
の転送」など、組み込み開発の最初の一歩を Elixir で踏み出せたのではないでしょうか。
今後は、センサとの連携や Wi-Fi/MQTT を使った通信など、より実用的な応用にも挑戦していきたいと思います。
本記事が、みなさんの「組み込み Elixir」への最初の一歩になれば嬉しいです。