当前位置:首页 > 工业控制 > 电路设计项目集锦
[导读]本项目的目标是使用 Buildroot 为树莓派 Zero W 开发一个定制的嵌入式 Linux 发行版。系统设计仅包含应用程序所需的基本组件,例如 Wi-Fi 连接、SSH 和 SCP 访问、I2C 支持以及 Python。系统还集成了 SSD1306 OLED 显示屏,用于构建菜单式仪表板,可显示系统信息和网络状态。

我遇到的许多现代设备通常都搭载了定制的操作系统,运行在其中。当我尝试配置路由器时,了解到它自带操作系统,我才开始意识到这一点。

本项目的目标是使用 Buildroot 为树莓派 Zero W 开发一个定制的嵌入式 Linux 发行版。系统设计仅包含应用程序所需的基本组件,例如 Wi-Fi 连接、SSH 和 SCP 访问、I2C 支持以及 Python。系统还集成了 SSD1306 OLED 显示屏,用于构建菜单式仪表板,可显示系统信息和网络状态。

通过精心选择所需软件包并优化启动流程,最终系统在启动后内存占用约为25 MB RAM,并在约6.77秒内完成应用程序启动。本项目展示了如何使用Buildroot为嵌入式应用创建一个轻量、高效且可定制的Linux平台。

Buildroot

Buildroot 是一个开源的构建自动化框架,可简化自定义嵌入式 Linux 系统的开发。它通过自动完成下载、配置、编译和集成所有所需软件组件的过程,为目标设备生成完整的 Linux 镜像,提供了一种简便高效的解决方案。

本项目使用 Buildroot 为 Raspberry Pi Zero W 创建了一个自定义的 Linux 发行版。在一台配备 8 GB 内存和 64 GB 存储空间的 Raspberry Pi 5 上配置并构建了 Buildroot 环境,该设备作为主机开发平台。通过 Buildroot,生成了一个定制化的 Linux 镜像,其中仅包含应用程序所需的功能组件,包括 Python 支持、Wi-Fi 连接、SSH 访问、文件传输的 SCP、OLED 显示支持以及一个基于菜单的定制仪表板应用。最终生成的镜像提供了一个轻量级的嵌入式 Linux 环境,优化了快速启动和低资源消耗,同时保留了项目所需的所有功能。

按照以下步骤在 Raspberry Pi 5 上创建 Buildroot 配置:

1. 获取 Buildroot

2. 加载 Raspberry Pi Zero W 配置:此操作用于设置正确的 CPU(ARM1176)、内核配置和引导加载程序设置

3. 自定义配置

Buildroot 配置(make menuconfig)

Python 支持:已安装的包包括:

•python3-pip

•python3-pillow

•python3-setuptools

已启用 Python 3,以支持 boot_manager.py、OLED 显示应用、Wi-Fi 初始化脚本以及菜单驱动界面。其他软件包通过 pip 安装(具体说明见下文)。

已启用 OpenSSH 服务器支持,以允许:

•远程登录

•通过SSH控制菜单

•远程调试与监控

无线网络:Wi-Fi 支持通过以下方式配置:

•WiFi网络安全存取请求者程序

•无线固件包

这使得树莓派Zero W在启动时能够自动连接无线网络。

OLED显示库

已包含用于SSD1306 OLED显示屏的Python包,可实现以下功能:

•启动状态消息

•IP地址显示

•菜单渲染

•Linux 内核配置(make linux-menuconfig)

•I2C 支持

已启用 I2C 支持,以便与 SSD1306 OLED 显示屏进行通信。

启用的关键组件:

•I2C子系统

•BCM2835 I2C 控制器驱动程序

这使得可以通过 /dev/i2c-* 访问 OLED 显示屏。

无线局域网支持

已启用适用于树莓派Zero W无线芯片组的内核支持。

相关驱动程序:

•cfg80211

•brcmutil

•brcmfmac

最初这些是作为内核模块构建的,并由引导管理器在启动时加载。

设备树支持已启用,以实现以下功能:

•树莓派硬件检测

•外设配置

•叠加层支持

这是为了正确初始化Wi-Fi、I2C和GPIO外设所必需的。

树莓派固件

已包含Linux固件支持,以提供:

•Broadcom Wi-Fi 固件

•Pi Zero W 无线芯片组所需的固件文件

如果没有这些固件文件,brcmfmac 驱动程序将无法初始化无线接口。

按照配置命令的顺序进行操作。

1. 设置 buildroot 配置

2. 保存配置

3. 配置 Linux 内核配置

4. 构建

在树莓派5上编译耗时将近2到3小时。编译完成后,镜像文件将位于 output/images/sdcard.img。

在 Pi Zero W 上刷写 Linux 镜像

按照以下步骤在 Mac OS 上将镜像刷入 SD 卡。我已通过 scp 将镜像从我的 Pi 5 复制到 Mac 上。

1. 识别SD卡设备

连接到系统的存储设备通过以下方式列出:

此命令用于识别与microSD卡对应的设备节点,假设此处为/dev/disk2。

2. 卸载SD卡

在写入图像之前,已卸载SD卡以防止文件系统损坏:

3. 编写 Buildroot 镜像

使用 dd 工具将生成的 Buildroot 镜像刷入 SD 卡:

其中:

•if=sdcard.img 指定输入的图像文件。

•of=/dev/rdisk2 指定了原始SD卡设备。

•bs=1m 使用 1 MB 的块大小以提高写入性能。

•使用原始设备(rdisk2)代替缓冲设备(disk2),以实现更快的数据传输速度。

4. 同步待写入数据

图像写入完成后,所有缓冲数据将通过以下方式刷新到SD卡:

这确保了在移除卡片之前,图像已完全写入。

5. 安全弹出SD卡

已安全弹出SD卡:

启动 Pi Zero

由于自定义的 Buildroot 镜像是一个没有图形界面的最小化 Linux 系统,因此无法通过显示器和桌面环境与树莓派 Zero W 交互。相反,在开发和调试期间,访问系统的主方法是通过串行控制台。

树莓派Zero W提供了一个UART(通用异步收发器)接口,可在启动过程中直接与操作系统通信。该接口特别适用于查看内核消息、监控启动进度以及访问命令行 shell。

启用启动分区

根文件系统目前没有显示已挂载的 /boot 分区。/boot 分区是一个小型的 FAT32 分区,其中包含在 Linux 内核接管之前启动系统所需的所有内容。对于此使用场景,我需要修改 config.txt 文件以启用 I2C 外设(具体说明见下文)。

验证分区

通常,p1 是 FAT 启动分区,p2 是 Linux 根文件系统。

使用以下方法手动挂载引导分区(p2):

然后检查启动目录,

设置WiFi模块

Pi Zero W 的 Wi-Fi 栈(即 brcmfmac)作为 Linux 内核模块提供,因此需要手动加载才能访问 Wi-Fi。

验证后,wlan0 应该会弹出提示,表明 WiFi 驱动已成功初始化,且 Linux 已检测到板载 Wi-Fi 芯片。

接下来,应将 wlan0 设置为 active 以启用 WiFi。默认情况下,其状态为 DOWN。

WiFi开启后,即可用于扫描并连接新的网络。我通过创建一个wpa_supplicant配置文件手动设置了WiFi。在目录/etc/中创建一个名为wpa_supplicant.conf的文件。该文件必须包含以下内容:

使用以下方式连接:

使用以下方式检查状态:

请注意,这不会启用互联网访问,因为其IP地址未被分配。要获取其IP地址,请启用DHCP以设置IP地址:

使用简单的 ping 命令测试网络(例如:ping 8.8.8.8)。

设置系统日期和时间

最小化的 Buildroot Linux 镜像不包含桌面 Linux 发行版中常见的许多后台服务。因此,系统在连接到网络后不会自动与互联网时间服务器同步时钟。

当 Raspberry Pi Zero W 首次启动时,系统时钟通常会被初始化为默认的日期和时间。由于该板子没有带电池备份的实时时钟(RTC)模块,因此断电后无法保留正确的时间。因此,在执行依赖精确时间戳的任务(如日志记录、文件管理或安全网络通信)之前,必须手动设置日期和时间。

当前日期和时间可通过以下命令进行配置:

自动时间同步

一旦无线网络配置完成且树莓派成功连接到互联网,就可以自动设置日期和时间。在启动时运行一个Python脚本,可连接网络时间协议(NTP)服务器并获取当前时间。

在此项目中,时间同步功能已集成到自定义启动管理器中。在建立Wi-Fi连接并获取IP地址后,脚本会与NTP服务器通信,并自动更新系统时钟。

设置 I2C 驱动程序

标准的buildroot配置最初并未加载任何I2C内核驱动。检查设备树(ls /proc/device-tree/soc/)后,发现i2c接口最初被禁用。

要启用 I2C 外设,首先在 Raspberry Pi 的固件配置中启用 I2C。将以下内容添加到 /boot/config.txt 文件中。

它告诉树莓派的固件开启专用的I2C引脚,并配置设备树以识别I2C外设。

完成文件修改后,重启设备并确认已连接I2C外设。

启动脚本

自定义的启动脚本是基于 Buildroot 的 Linux 系统的主要启动应用程序,通过 S99boot_manager 初始化脚本在系统启动时自动执行。其目的是初始化嵌入式平台,并为系统运行做好准备。启动过程中,该脚本首先初始化 SSD1306 OLED 显示屏,并显示启动状态信息,向用户提供视觉反馈。随后加载所需的 Wi-Fi 内核模块:cfg80211、brcmutil 和 brcmfmac,启动 wpa_supplicant 以连接已配置的无线网络,并通过 DHCP 获取 IP 地址。一旦网络连接建立,脚本将系统时间与 NTP 服务器同步,以确保日期和时间信息的准确性。在此整个过程中,OLED 显示屏会实时更新连接状态和网络信息,包括分配到的 IP 地址。

执行以下操作以运行启动脚本:1. 创建一个 init 脚本:/etc/init.d/S99bootmanager。该启动脚本必须包含 Python 启动脚本:

2. 将启动脚本编译为可执行文件

这使得 Busybox 在下次启动时能够自动执行它。

缩短启动时间

在对基于 Buildroot 的 Linux 系统进行初始测试时,启动过程在网络初始化阶段出现了延迟,并显示如下信息:

延迟的原因是 Buildroot 的网络服务(S40network)通过 /etc/network/interfaces 文件在启动时被配置为自动启用 wlan0 接口。然而,Wi-Fi 驱动程序(brcmfmac)及其相关的网络组件是由自定义的 boot_manager.py 脚本稍后加载的(因为这些组件作为模块而非内核驱动程序提供)。因此,网络服务需要等待 wlan0 接口可用,从而延长了整体启动时间。

以下的 /etc/network/interfaces 配置导致系统等待无线接口:

由于Wi-Fi初始化和网络配置已由自定义的boot_manager.py脚本处理,因此自动网络配置变得多余。通过注释掉这些行,系统启动时的引导过程不再需要等待wlan0。

因此,延迟被消除,整体启动时间得以缩短,并且在完成必要的系统初始化步骤后,启动管理器应用程序可立即启动。

释放更多内存

在Raspberry Pi Zero W上运行基于Buildroot的最小Linux发行版时,我原本以为该板的512MB内存中大部分都能被Linux系统使用。然而,初步测试显示,操作系统仅能看到约364MB的内存。这促使我调查了Raspberry Pi固件如何分配内存,以及GPU内存划分如何影响可用的系统RAM。

启动新构建的 Buildroot 镜像后,系统报告:

内核启动日志显示:

这表明 Linux 只收到了:

从固件中释放物理内存。

由于树莓派Zero W配备了512MB内存,Linux系统启动前大约有128MB内存似乎被占用了。由于树莓派在ARM CPU和VideoCore GPU之间共享系统内存,我的目标是减少分配给GPU的内存,因为我没有使用桌面版Linux系统,也没有任何与摄像头相关的应用程序。

解决方案

Buildroot生成的config.txt最初包含:gpu_mem_512=100 MB。将其改为16 MB后,Linux仍然只识别到约384 MB的内存。

为验证固件是否正确遵循了GPU内存设置,测试了多个数值。

gpu内存=256

结果:

这确认了固件正在读取并应用配置。

gpu_mem=64

结果:

gpu_mem=32

结果:

gpu_mem=16

结果:

意外的是,将GPU内存降低到32 MB以下时,可用的RAM会急剧下降。这表明固件强制执行了最低支持的GPU内存分配,并在使用不支持的值时切换为不同的内存分配方式。

通过调整 gpu_mem 设置,成功将 Linux 可见内存提升至约 459 MB。此举在保持系统稳定运行的同时,回收了近 100 MB 的 RAM。

速度对比

在本项目中,我将比较构建根文件系统(buildroot)的最小Linux版本与标准的32位树莓派OS Lite,因为后者并非桌面版。我会对比它们的启动时间、内存使用情况以及平均CPU负载。我将把树莓派OS Lite安装在一块32GB的SanDisk Ultra Class-10 SD卡上(速度更快),而构建根版本则安装在一块16GB的Class-4 SD卡上。

1. 启动时间对比

本实验的目的是比较基于自定义Buildroot的Linux发行版与运行在Raspberry Pi Zero W上的Raspberry Pi OS Lite之间的启动性能。

评估了两个指标:

•内核启动时间

•启动管理器启动时间

内核启动时间表示Linux内核初始化并启动init进程所需的时间。启动管理器开始时间表示从开机到用户应用程序(boot_manager.py)开始执行所经过的时间。

在 Buildroot Linux 中,引导管理器被配置为一个 SysV 初始化脚本:

并使用以下方式获取内核启动时间:

启动管理器的启动时间是通过以下方式测量的:

在 Raspberry Pi OS Lite 上,启动管理器被配置为一个 systemd 服务:

内核启动时间通过以下方式获取:

引导程序启动时间是使用相同的Python脚本测量的。

结果

•Buildroot Linux 内核启动时间:4.60 秒

•树莓派 Lite 操作系统 启动时间:11.967 秒

•Buildroot Linux 启动管理器启动时间:6.77 秒

•树莓派 Lite 操作系统启动管理器启动时间:113.07 秒

由于架构精简,Buildroot镜像的启动性能显著更快。Buildroot仅包含应用程序所需的服务和软件包,从而减少了初始化的工作量。

树莓派 Lite 操作系统镜像包含许多附加服务,例如:

•systemd

•网络管理器

•cloud-init

•D-Bus 服务

•主机名和网络配置服务

使用 systemd-analyze 进行分析后显示:

表明大部分延迟源于用户空间服务的初始化,而非内核启动。

Buildroot 系统在内核初始化后约 2.17 秒即可执行应用程序,而 Raspberry Pi OS Lite 则需要超过 100 秒才能启动应用。综上所述,Buildroot 能实现更快的启动速度,因为它仅包含应用程序所需的服务;而 Raspberry Pi OS Lite 则初始化了一个更大的用户空间环境,包括 systemd、NetworkManager 和 cloud-init。

2. 内存使用情况

系统完成启动并建立网络连接后,评估了内存使用情况。

基于 Buildroot 的系统在启动后仅占用 25 MB 内存,而 Raspberry Pi OS Lite 占用 107 MB,内存使用量减少了约 76.6%。

此外,Buildroot 为应用程序执行预留了 426 MB 的内存,而 Raspberry Pi OS Lite 只有 319 MB。

内存占用的减少主要得益于极简的Buildroot配置,该配置排除了NetworkManager、cloud-init、D-Bus以及其他在Raspberry Pi OS Lite中常见的用户空间组件。

结果表明,Buildroot 提供了显著更轻的运行时环境,更适合资源受限的嵌入式系统,这些系统需要较低的内存消耗。

3. CPU负载对比

在启动两个操作系统并使其保持空闲后,使用 Linux 的 uptime 命令评估系统负载。

在 Pi OS lite 上:

在 Buildroot 操作系统上:

启动后的最初几分钟内,Raspberry Pi OS Lite 由于运行了 NetworkManager、蓝牙以及与 systemd 相关的后台服务,导致系统负载较高。相比之下,Buildroot 镜像仅运行应用程序所需的服务,因此整体系统活动较低。

大约10分钟后,两个系统均进入大致空闲状态。然而,在Buildroot上,5分钟和15分钟的负载平均值仍较低,表明后台处理减少,运行环境更轻。这些结果表明,自定义的Buildroot镜像在提供嵌入式应用程序所需功能的同时,保持了更低的系统开销。

4. 根文件系统大小比较

在 Pi OS lite 上:

在 Buildroot Linux 上:

Buildroot镜像仅占用Raspberry Pi OS Lite所需存储空间的一小部分,因为它只包含应用程序所需的软件包。

5. 运行服务

在 Pi OS Lite 上:

在 Buildroot Linux 上:

Buildroot 启动时服务集显著缩小,从而降低了内存使用量和启动时间。

应用:自定义仪表盘

为了为自定义的 Buildroot Linux 系统提供交互式用户界面,开发并显示了一个基于菜单的仪表板应用程序,该应用通过 I2C 接口连接到 Raspberry Pi Zero W 的 OLED 显示屏上。由于 Buildroot 镜像设计为轻量级嵌入式 Linux 系统,不包含图形桌面环境,因此基于 OLED 的仪表板为用户提供了简单高效的设备交互方式。

功能

仪表板采用分层菜单结构,使用户能够轻松切换至不同的系统功能和实用工具。通过SSH终端会话远程控制菜单导航,无需专用键盘、鼠标或显示器即可实现交互操作。

该应用程序集成了多项实用功能,包括:

系统信息

•显示设备IP地址

•当前日期和时间

•网络状态信息

天气信息

•获取并显示当前天气状况

•OLED显示屏上显示的天气图标

•温度和环境信息

Wi-Fi 连接

•网络连接状态显示

无线连接成功验证

•交互式菜单导航

•可滚动的菜单界面

•通过SSH使用键盘输入选择菜单选项

•OLED显示屏上的动态画面更新

结论

该项目成功展示了使用 Buildroot 为 Raspberry Pi Zero W 开发自定义嵌入式 Linux 发行版。主要目标是创建一个轻量级的 Linux 系统,能够支持 Wi-Fi 连接、SSH 和 SCP 访问、I2C 通信、Python 应用程序以及基于 OLED 的用户界面等基本嵌入式功能,同时保持较小的内存占用和快速的启动时间。

本文编译自hackster.io

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

在传统模式下,人类使用手工库存管理系统,这种方式耗时且容易出错。随着技术的发展,我们开发了一款条码扫描器,能够快速扫描产品并管理库存系统。本项目展示了如何构建一款基于树莓派的条码扫描终端,通过即时扫描和记录产品信息,实现...

关键字: 树莓派 条码扫描器 Arduino

官方Arduino UNO Q是一款性能强大的开发板。与传统微控制器不同,它采用“双脑”架构:搭载高通® Dragonwing™ MPU,运行Linux Debian系统,用于处理复杂的AI和计算任务;同时配备STM32...

关键字: 仪表板 STM32微控制器 Linux

reComputer AI Lab 是由 Seeed 推出的边缘 AI 开发平台,围绕即用型体验构建。该平台预集成主流 AI 应用场景,包括通过定制系统镜像实现 YOLO 等功能,并支持一键部署与推理执行,显著降低了开发...

关键字: 边缘 AI 树莓派 RK3576

从小时候起,GTA就是我玩过的最早的游戏之一,从那一刻起我就成了它的忠实粉丝。一直让我着迷的一点是屏幕角落里那个小小的圆形地图,它会显示你的位置以及你在游戏世界中的移动方向。它的运作方式与谷歌地图这样的真实导航系统非常相...

关键字: GTA 谷歌地图 ESP32-S3 显示屏

雷达通过Wi-Fi连接至OpenSky网络API,可下载指定区域内的飞机位置信息。飞机在平滑的动画雷达界面上显示,并配有航向指示器、飞行选择功能以及专用详情页面。

关键字: 飞行雷达 显示屏 ESP32-S3

除了光学红外输出外,许多电表还配备RS485接口,可通过该接口提供用电数据,例如用于控制家庭太阳能系统。根据地区和能源供应商的不同,数据通常通过广为人知的MODBUS RTU协议或所谓的SML协议(智能消息语言)传输。本...

关键字: OLED 显示屏 RS485

最近我接到任务,为一位客户的鸡舍采购一盏太阳能泛光灯。但要求不能是运动感应型的,而且必须使用太阳能供电,因为鸡舍远离电源插座,需要完全自主运行,每天凌晨4点到7点自动开启。网上找不到符合这些条件的产品。起初……

关键字: 太阳能 树莓派 实时时钟

在我的一些之前视频中,我向大家展示了如何在不同显示屏上模拟制作模拟VU表。这次我将讲解如何制作这样一个项目,但使用的是包含几乎所有元件(包括MCU)的显示模块。只需添加几个无源元件和一个LED,即可作为峰值表来工作。

关键字: 显示屏 LED ESP32

这些通过AEC-Q102认证的器件具有与人眼相当的光谱感光度,并采用紧凑的0805和顶视QFN封装,可实现更优的光谱角性能

关键字: 光传感器 显示屏 抬头显示器

一款完全离线、注重隐私的人工智能语音助手,运行在树莓派5上,专为非洲社区打造,能够理解并用特威语、加纳语、埃维语和英语进行交互,无需等待硅谷关注他们的语言。

关键字: AI 树莓派 传感器 MPU6050
关闭