亲测有效!用测试开机启动脚本实现Armbian自动点灯
1. 引言:让开发板在开机时自动点亮LED
你有没有这样的需求:希望Armbian系统一启动,就自动点亮某个GPIO引脚上的LED?比如作为运行状态指示、调试信号,或者只是想炫一下“我的板子活了”?
本文将带你从零开始,手把手实现一个开机自动点灯的脚本,并深入讲解背后的启动机制。我们不依赖复杂的图形界面工具,而是通过最直接、最稳定的方式——编写系统级启动服务,确保每次上电都能可靠执行。
整个过程无需额外软件包,只使用Armbian自带的功能,适合树莓派、Orange Pi、NanoPi等各类基于Linux的嵌入式开发板。
无论你是刚接触嵌入式Linux的新手,还是想巩固系统启动知识的老玩家,这篇文章都能让你有所收获。
2. 理解Armbian的启动机制:systemd vs init.d
2.1 Armbian默认使用systemd
现代Armbian系统(基于Debian或Ubuntu)已经全面采用systemd作为初始化系统(init system),也就是系统的第一个进程(PID 1)。它负责启动所有后续的服务和应用。
你可以通过以下命令验证:
ps -p 1 -o comm=输出结果应该是:
systemd这说明你的系统确实是用 systemd 来管理启动流程的。
2.2 init.d 是兼容层,并非原生机制
虽然你还可能看到/etc/init.d/目录下有脚本,甚至可以用update-rc.d添加启动项,但这些其实都是systemd 的兼容性封装。
当你把一个脚本注册到 init.d 时,systemd 会自动生成一个临时的 unit 文件来调用它。这意味着:
- 实际控制权仍在 systemd 手中
- 日志由
journalctl统一管理 - 启动顺序和依赖关系仍受 systemd 规则约束
所以,与其依赖这种“中间层”,不如直接写一个标准的 systemd service 文件,更清晰、更可控。
3. 编写点灯脚本:控制GPIO引脚
我们要做的很简单:在系统启动完成后,自动导出指定GPIO引脚,并设置其为输出模式,然后点亮连接在上面的LED。
3.1 创建脚本文件
首先创建一个可执行脚本,用于配置GPIO:
sudo nano /usr/local/bin/gpio-init.sh输入以下内容:
#!/bin/bash # 导出 GPIO 引脚(根据实际硬件调整编号) echo "6" > /sys/class/gpio/export 2>/dev/null || true echo "8" > /sys/class/gpio/export 2>/dev/null || true echo "9" > /sys/class/gpio/export 2>/dev/null || true echo "10" > /sys/class/gpio/export 2>/dev/null || true # 设置方向为输出 echo "out" > /sys/class/gpio/gpio6/direction 2>/dev/null || true echo "out" > /sys/class/gpio/gpio8/direction 2>/dev/null || true echo "out" > /sys/class/gpio/gpio9/direction 2>/dev/null || true echo "out" > /sys/class/gpio/gpio10/direction 2>/dev/null || true # 设置初始值:1 表示高电平(点亮LED) echo "1" > /sys/class/gpio/gpio6/value 2>/dev/null || true echo "1" > /sys/class/gpio/gpio8/value 2>/dev/null || true echo "1" > /sys/class/gpio/gpio9/value 2>/dev/null || true echo "1" > /sys/class/gpio/gpio10/value 2>/dev/null || true exit 0注意:
2>/dev/null || true是为了防止重复导出时报错导致脚本中断- GPIO编号需根据你的开发板型号和接线进行调整
- 某些板子需要先加载设备树或启用特定内核模块,请确保GPIO功能已启用
3.2 赋予执行权限
保存后,给脚本添加可执行权限:
sudo chmod +x /usr/local/bin/gpio-init.sh3.3 手动测试脚本是否生效
可以手动运行一次看看LED是否会亮:
sudo /usr/local/bin/gpio-init.sh如果LED成功点亮,说明脚本工作正常,接下来我们让它在每次开机时自动运行。
4. 配置systemd服务实现开机启动
4.1 创建service文件
创建一个新的systemd服务单元文件:
sudo nano /etc/systemd/system/gpio-init.service填入以下内容:
[Unit] Description=GPIO Initialization Service After=multi-user.target # 可选:如果你依赖网络或其他服务,可以添加 # Requires=network-online.target # After=network-online.target [Service] Type=oneshot ExecStart=/usr/local/bin/gpio-init.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target参数解释:
Description: 服务描述,便于识别After=multi-user.target: 表示在多用户环境准备好后再运行(即系统基本服务已启动)Type=oneshot: 表示这是一个一次性执行的任务,不需要常驻后台RemainAfterExit=yes: 即使脚本执行完毕,也认为服务处于“激活”状态WantedBy=multi-user.target: 表示该服务属于标准多用户运行级别
4.2 启用服务
保存文件后,通知systemd重新加载配置:
sudo systemctl daemon-reload然后启用该服务,使其开机自启:
sudo systemctl enable gpio-init.service输出应显示:
Created symlink /etc/systemd/system/multi-user.target.wants/gpio-init.service → /etc/systemd/system/gpio-init.service.表示软链接已创建,服务注册成功。
5. 验证与调试:确认服务正常运行
5.1 查看服务状态
重启系统前,可以先手动启动服务测试:
sudo systemctl start gpio-init.service查看状态:
sudo systemctl status gpio-init.service正常输出类似:
● gpio-init.service - GPIO Initialization Service Loaded: loaded (/etc/systemd/system/gpio-init.service; enabled; vendor preset: enabled) Active: active (exited) since Mon 2025-04-05 10:30:22 UTC; 5s ago Process: 456 ExecStart=/usr/local/bin/gpio-init.sh (code=exited, status=0/SUCCESS) Main PID: 456 (code=exited, status=0/SUCCESS) Apr 05 10:30:22 armboard systemd[1]: Started GPIO Initialization Service.只要看到Started和status=0/SUCCESS,就说明执行成功。
5.2 重启并观察效果
现在重启系统:
sudo reboot等待系统重新启动后,观察LED是否自动点亮。如果是,则恭喜你,开机自动点灯已成功实现!
6. 进阶技巧与常见问题解决
6.1 如何知道哪些服务会在开机时启动?
列出所有启用的systemd服务:
systemctl list-unit-files --type=service --state=enabled查找你刚刚添加的服务:
systemctl is-enabled gpio-init.service返回enabled表示已启用。
6.2 查看启动日志定位问题
如果LED没亮,别急,用 journalctl 查看日志:
journalctl -u gpio-init.service --since today你会看到完整的执行记录,包括错误信息。例如:
- 如果提示
No such device,可能是GPIO编号错误或未启用 - 如果权限被拒绝,检查脚本路径和权限设置
6.3 常见问题汇总
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| LED不亮 | GPIO编号不对 | 核对开发板引脚定义图 |
脚本报错Device or resource busy | GPIO已被占用 | 使用echo前加 ` |
| 服务无法启用 | 文件权限不足 | 确保.service和脚本都有正确权限 |
| 服务未运行 | 没有执行daemon-reload | 修改service后必须重载 |
7. 总结:掌握核心,灵活扩展
7.1 回顾关键步骤
我们完成了以下几步,实现了Armbian开机自动点灯:
- 理解启动机制:明确Armbian使用systemd为主控,init.d仅为兼容层
- 编写GPIO控制脚本:通过
/sys/class/gpio/接口操作硬件引脚 - 创建systemd service:以标准化方式注册开机任务
- 启用并验证服务:确保每次重启都能可靠执行
这套方法不仅适用于点灯,还可以扩展用于:
- 开机初始化传感器
- 自动启动串口通信程序
- 设置PWM风扇控制
- 初始化I2C/OLED显示屏
- 批量配置多个GPIO状态
7.2 为什么推荐使用systemd而非rc.local?
有些人习惯把命令写进/etc/rc.local,但这种方式存在几个问题:
- 执行时机不确定(可能早于网络、存储挂载完成)
- 错误难以追踪(无独立日志)
- 不符合现代Linux规范
- 在某些镜像中rc.local已被弃用
而 systemd 提供了:
- 明确的依赖控制
- 完整的日志追踪(
journalctl) - 标准化的启用/禁用管理
- 更高的可靠性与可维护性
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。