1. Nerves 开发环境配置全攻略
作为一名长期深耕嵌入式开发的工程师,最近被 Elixir 生态中的 Nerves 框架深深吸引。这个基于 BEAM 虚拟机的嵌入式开发平台,让我们能够用函数式编程语言来构建坚如磐石的嵌入式系统。今天我就来分享在 Ubuntu 系统上配置 Nerves 开发环境的完整过程,特别是那些官方文档没有详细说明的坑点和技巧。
Nerves 的核心原理是通过定制化的 Linux 内核驱动硬件,然后启动 Erlang 运行时接管系统,最终运行 Elixir 应用程序。这种架构带来了 Erlang/OTP 的所有优势 - 容错性、热代码升级和分布式能力,全都打包在一个嵌入式系统中。
2. 系统环境准备
2.1 操作系统选择
Nerves 开发环境需要类 Unix 系统支持,官方推荐使用 Linux 或 macOS。在 Windows 上可以通过 WSL 来运行 Linux 环境。我个人选择的是 Ubuntu 24.04 LTS 虚拟机,主要基于以下考虑:
- 较新的内核版本(5.15+)能更好地支持 Nerves 所需的各种功能
- 软件包仓库提供了较新的工具链版本
- 作为 LTS 版本有长期支持保障
提示:虽然 Ubuntu 22.04 也能用,但会遇到更多依赖库版本冲突问题。如果必须使用旧版系统,建议通过 Docker 容器来隔离开发环境。
2.2 基础依赖安装
Nerves 编译系统需要一系列基础工具和开发库。以下是必须安装的软件包列表:
bash复制sudo apt update
sudo apt install -y \
build-essential \
automake \
autoconf \
git \
squashfs-tools \
pkg-config \
curl \
libmnl-dev \
libnl-genl-3-dev \
libssl-dev \
libncurses5-dev \
help2man \
libconfuse-dev \
libarchive-dev \
file \
unzip \
libgnutls28-dev
这些依赖可以分为几类:
- 编译工具链:build-essential、automake、autoconf 等
- Nerves 核心工具:squashfs-tools(用于构建固件镜像)
- 网络相关:libmnl-dev、libnl-genl-3-dev(WiFi 支持)
- 加密/安全:libssl-dev、libgnutls28-dev
- 其他辅助工具:git、curl、unzip 等
在实际安装过程中,可能会遇到 libnl-genl-3-dev、libarchive-dev 和 libgnutls28-dev 之间的依赖冲突。这时可以尝试:
bash复制sudo apt install aptitude
sudo aptitude install libnl-genl-3-dev libarchive-dev libgnutls28-dev
aptitude 会提供多个解决方案供选择,通常选择降级某些依赖包的版本即可解决冲突。
3. Erlang/OTP 环境配置
3.1 版本要求
Nerves 对 Erlang/OTP 的版本要求较高,当前最新版 Nerves 1.13.0 需要 OTP 26+。Ubuntu 官方仓库中的 Erlang 版本往往较旧,因此我们需要其他安装方式。
3.2 通过 asdf 安装(推荐)
asdf 是一个通用的版本管理工具,支持多种语言运行时。安装步骤如下:
- 安装 asdf 核心:
bash复制git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
source ~/.bashrc
- 添加 Erlang 和 Elixir 插件:
bash复制asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
asdf plugin add elixir https://github.com/asdf-vm/asdf-elixir.git
- 安装依赖(用于编译 Erlang):
bash复制sudo apt install -y \
libwxgtk3.2-dev \
libgl1-mesa-dev \
libglu1-mesa-dev \
libpng-dev \
libssh-dev \
unixodbc-dev \
xsltproc \
fop
- 安装指定版本:
bash复制asdf install erlang 28.1
asdf install elixir 1.19.5-otp-28
asdf global erlang 28.1
asdf global elixir 1.19.5-otp-28
3.3 手动编译安装(备选方案)
如果不想使用版本管理工具,也可以手动编译安装:
- 下载 OTP 源码:
bash复制wget https://github.com/erlang/otp/releases/download/OTP-28.1/otp_src_28.1.tar.gz
tar -xzf otp_src_28.1.tar.gz
cd otp_src_28.1
- 配置和编译:
bash复制./configure
make -j$(nproc)
sudo make install
- 验证安装:
bash复制erl -version
4. Elixir 环境配置
4.1 安装 Elixir
如果使用 asdf,已经在上一步完成了 Elixir 安装。手动安装也很简单:
- 下载预编译包:
bash复制wget https://github.com/elixir-lang/elixir/releases/download/v1.19.5/Precompiled.zip
unzip Precompiled.zip -d ~/elixir-1.19.5
- 添加到 PATH:
bash复制echo 'export PATH="$HOME/elixir-1.19.5/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
- 验证安装:
bash复制elixir -v
4.2 使用官方安装脚本
Elixir 官方提供了一个方便的安装脚本:
bash复制curl -fsSO https://elixir-lang.org/install.sh
chmod +x install.sh
./install.sh --version 1.19.5
这个脚本会自动检测系统环境并安装合适的 Elixir 版本。
5. Nerves 特定工具安装
5.1 fwup
fwup 是 Nerves 用于烧录固件的工具:
bash复制wget https://github.com/fwup-home/fwup/releases/download/v1.10.2/fwup_1.10.2_amd64.deb
sudo dpkg -i fwup_1.10.2_amd64.deb
5.2 nerves_bootstrap
安装 Nerves 项目初始化工具:
bash复制mix archive.install hex nerves_bootstrap
6. 解决网络问题
在国内环境,从 GitHub 下载依赖可能会很慢。有两个关键文件经常需要下载:
- 系统镜像(如 nerves_system_rpi4)
- 交叉编译工具链
6.1 手动下载
可以先通过其他方式下载这些文件,然后放到正确位置:
bash复制mkdir -p ~/.nerves/dl
# 将下载的 .tar.gz 和 .tar.xz 文件放入此目录
6.2 环境变量控制
设置下载目录:
bash复制export NERVES_DL_DIR="$HOME/nerves_downloads"
mkdir -p "$NERVES_DL_DIR"
查看下载URL(用于手动下载):
bash复制NERVES_DEBUG=1 MIX_TARGET=rpi4 mix deps.get
7. 创建第一个 Nerves 项目
7.1 初始化项目
bash复制mix nerves.new hello_nerves
cd hello_nerves
7.2 配置目标硬件
编辑 config/target.exs,选择正确的系统类型:
elixir复制config :hello_nerves, target: "rpi4"
7.3 获取依赖
bash复制export MIX_TARGET=rpi4
mix deps.get
7.4 构建固件
bash复制mix firmware
7.5 烧录到SD卡
插入SD卡后:
bash复制mix firmware.burn
8. 常见问题排查
8.1 依赖下载失败
症状:mix deps.get 卡在下载系统镜像或工具链
解决:
- 设置 NERVES_DEBUG=1 查看下载URL
- 手动下载后放入 ~/.nerves/dl
- 再次运行 mix deps.get
8.2 版本不兼容
症状:奇怪的编译错误或运行时崩溃
解决:
- 确认 Erlang/OTP 版本符合要求
- 更新 Nerves 和依赖到最新版本
- 清理并重新获取依赖:
bash复制mix deps.clean --all
mix deps.get
8.3 权限问题
症状:烧录固件时提示权限不足
解决:
- 将用户加入 dialout 组:
bash复制sudo usermod -aG dialout $USER
- 注销后重新登录
9. 开发技巧与优化
9.1 加速编译
- 启用并行编译:
bash复制export MAKEFLAGS="-j$(nproc)"
- 使用 ccache:
bash复制sudo apt install ccache
export CCACHE_DIR="$HOME/.ccache"
export CC="ccache gcc"
9.2 交互式开发
- 通过 IEx 控制台与设备交互:
bash复制mix firmware.gen.script
./upload.sh
- 远程 shell 访问:
elixir复制# 在应用中启用
defmodule HelloNerves.Application do
use Application
def start(_type, _args) do
HelloNerves.Supervisor.start_link()
end
end
9.3 自定义系统镜像
如果需要添加额外的系统包或配置:
- 创建自定义系统:
bash复制mix nerves.system.new my_custom_system --target rpi4
- 修改配置后构建:
bash复制cd my_custom_system
make
- 在项目中使用:
elixir复制# mix.exs
defp deps do
[
{:my_custom_system, path: "../my_custom_system"}
]
end
经过这些步骤,你应该已经拥有了一个功能完整的 Nerves 开发环境。在实际项目中,我发现 Nerves 特别适合需要高可靠性的物联网设备开发,BEAM 虚拟机的特性让系统在意外情况下也能保持稳定运行。
