设备树 Overlay(Device Tree Overlays, DTO),它在嵌入式Linux系统(尤其是基于ARM的设备,比如树莓派、NanoPi等)中非常常见。它主要用于动态修改设备树,以适配硬件的变化或扩展外设支持。


1. 设备树 (Device Tree) 基础

  • 设备树是Linux内核用来描述硬件的一个数据结构(通常是 .dts 源文件,编译成 .dtb 二进制文件)。
  • 它告诉内核“硬件是什么”,“有什么设备”,以及“设备如何连接”的信息。
  • 这样,内核就不需要硬编码特定硬件,增强了移植性。

2. 设备树 Overlay(DTO)是什么?

  • Overlay 就是对设备树的“增量补丁”,它定义了一段额外的设备树节点,能够在运行时或者启动时“叠加”到主设备树上。
  • 目的:实现设备树的动态扩展,比如给板子添加新的外设(GPIO扩展板、摄像头模块、触摸屏等),而不用修改主设备树文件。
  • Overlay通常是一个独立的 .dtbo 文件(编译后的Overlay),由主设备树加载时或内核模块加载时合并。

3. 使用场景

典型场景:

  • 外设模块动态添加
    比如你的主板没有集成摄像头,需要外接摄像头模块,就可以用Overlay来描述摄像头设备节点和相关GPIO、中断配置。

  • GPIO复用和引脚配置
    一块板子多个设备共用引脚,Overlay能配置引脚复用,打开或关闭某些设备接口。

  • 设备树不方便修改的环境
    有些固件或内核只能加载固定的主设备树,Overlay给了动态配置的能力。


4. Overlay 如何使用?

  • 制作Overlay文件

    1. 编写 .dts 文件,继承主设备树的内容,只写你想“覆盖/新增”的部分。
    2. 使用设备树编译器(dtc)编译成 .dtbo 文件。
  • 加载Overlay

    • 在启动时加载(很多板子在bootloader配置文件中支持Overlay加载,比如 config.txt 里的 dtoverlay=
    • 运行时加载(通过configfs接口,动态插入Overlay)

举例(树莓派):

# /boot/config.txt
dtoverlay=your-overlay-name

5. Overlay 和 Initramfs、systemd 对比

特性设备树 Overlayinitramfssystemd
作用动态修改硬件描述,加载新硬件节点早期用户空间临时根文件系统加载Linux启动初始化系统及服务管理
关注层面硬件抽象层系统启动早期阶段用户空间环境系统服务管理及并发启动
运行时机启动阶段或运行时内核设备树修改内核启动时挂载,用于系统启动内核启动后启动管理服务
主要功能硬件描述扩展、配置引脚、设备绑定提供最初的文件系统环境启动服务、管理依赖、日志、资源等
适用场景硬件变动、模块化硬件设计内核启动时根文件系统不可用场景系统服务启动和管理
是否直接涉及硬件
动态修改硬件描述能力支持,动态加载/卸载Overlay不支持不支持

6. 简单总结

  • 设备树 Overlay:专注于硬件描述和配置,特别适合动态加载硬件节点。
  • initramfs:内核启动的第一个用户空间,负责挂载根文件系统和初始化环境。
  • systemd:现代Linux系统的初始化和服务管理器,负责启动和维护系统服务。

7. 你实际使用设备树Overlay时要注意

  • 设备树版本兼容性
  • Overlay文件的正确编译
  • 确保Overlay描述的硬件节点匹配实际硬件
  • 确保bootloader或内核支持Overlay机制
  • 运行时加载Overlay需内核开启CONFIG_OF_OVERLAY支持

很好,你正在使用的是 NanoPi NEO Core 这类基于 Allwinner H3 SoC 的板子,跑的是 Armbian,这类系统通常是 Debian 或 Ubuntu 的轻量定制版本,广泛用于嵌入式设备和 DIY 项目。


✅ 背景确认

你的平台:

  • 硬件:NanoPi NEO Core(基于 Allwinner H3)
  • 系统:Armbian(可能基于 Debian/Ubuntu)
  • 用途:可能用于音频服务(你提到 Navidrome)或其他嵌入式用途
  • 需求:动态控制硬件(如 I2C、SPI、UART、GPIO、LED、外接模块等)

📌 在 Armbian 上使用设备树 Overlay(DTO)

Armbian 提供 标准化支持 DTO 的机制,适用于大多数基于 mainline kernel 的 Allwinner 平台。


📘 Armbian Overlay 使用方法

1. 查看当前启用的 Overlays

armbian-config

进入 → SystemHardware → 你可以通过界面启用常见的设备树 Overlays(I2C, SPI, UART, PWM, etc)

或手动查看:

cat /boot/armbianEnv.txt

你可能会看到类似:

overlays=spi-spidev i2c0 uart1
param_spidev_spi_bus=0

2. 启用已有 Overlay

编辑 /boot/armbianEnv.txt

sudo nano /boot/armbianEnv.txt

添加或修改:

overlays=spi-spidev i2c0 uart1

保存后重启:

sudo reboot

你可以用 dmesg | grep spils /dev/spidev* 来确认是否生效。


3. Overlay 文件存放位置

Armbian 默认加载 /boot/dtb/overlay/ 中的 .dtbo 文件。你也可以:

ls /boot/dtb/allwinner/overlay/

4. 自定义 Overlay 示例

举个例子:你要启用一个额外的 LED 灯连接到 GPIO PH7

创建文件:my-led-overlay.dts

/dts-v1/;
/plugin/;&{/} {fragment@0 {target-path = "/";__overlay__ {my_led: gpio-leds {compatible = "gpio-leds";status_led {label = "status_led";gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>;  // PH7 = port 7, pin 7default-state = "on";};};};};
};

然后编译:

dtc -@ -I dts -O dtb -o my-led-overlay.dtbo my-led-overlay.dts

拷贝到 overlay 文件夹:

sudo cp my-led-overlay.dtbo /boot/dtb/allwinner/overlay/

修改 /boot/armbianEnv.txt 添加:

user_overlays=my-led-overlay

保存并重启:

sudo reboot

🧠 Overlay 与 systemd/initramfs 区别(再次归纳)

项目设备树 Overlay (DTO)initramfssystemd
含义动态叠加修改设备树(硬件配置)临时根文件系统(启动用)启动初始化系统管理器
使用时机启动时或运行时加载启动时使用内核启动后立即运行
作用层面硬件层(GPIO/I2C/UART等)用户空间临时运行环境管理服务、守护进程、挂载等
是否与硬件直接相关✅ 是❌ 否❌ 否

🧪 常用场景举例(在你设备上)

目标使用方式
启用 SPIoverlays=spi-spidev
启用 UARToverlays=uart1 uart2
自定义 LED GPIO自写 DTO + user_overlays
音频模块支持(I2S DAC)DTO + 手动加载驱动
外接 OLED 屏(I2C)overlays=i2c0 + dto 添加地址和驱动绑定

🔧 小贴士

  • dtc -I fs /proc/device-tree 可以查看当前设备树的实际内容
  • 确保 CONFIG_OF_OVERLAY=y 在内核中开启(Armbian默认是开的)
  • 你可以使用 fdtput 工具直接修改 .dtb 文件(高级用法)

如果你遇到的问题是:

  • DTO加载无效 ➜ 看 /boot/armbianEnv.txt 里拼写是否正确
  • 驱动不生效 ➜ 用 dmesglsmodmodinfo 等调试
  • 不知道引脚编号 ➜ 查找对应的 sunxi pin map(Allwinner特有)

你想在 NanoPi NEO Core(Armbian) 上通过 I2C 接 OLED 显示屏(SSD1306 控制器),下面是完整详解,包括:

  • ✅ 硬件连接
  • ✅ 内核模块/驱动配置
  • ✅ 设备树 Overlay 编写与使用
  • ✅ 软件层显示内容(Python 示例)

✅ 1. 硬件接线(基于 I2C)

OLED LabelNanoPi NEO PinNotes
VCC3.3V / 5VOLED 供电
GNDGND地线
SDAI2C0_SDA (Pin 3, GPIO PA11)数据线
SCLI2C0_SCL (Pin 5, GPIO PA12)时钟线

确认你接在了 I2C0(默认引出)的 SDA/SCL 上。


✅ 2. 启用 I2C0 接口(Armbian Overlay)

编辑 /boot/armbianEnv.txt

overlays=i2c0

保存后重启:

sudo reboot

确认 /dev/i2c-0 是否出现:

ls /dev/i2c*

还可以确认 OLED 是否连上(地址通常为 0x3c):

sudo apt install -y i2c-tools
sudo i2cdetect -y 0

看到类似:

     0 1 2 3 4 5 6 7 8 9 a b c d e f
00:          -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- 3c
...

✅ 3. 添加设备树 Overlay(挂载 SSD1306)

Armbian 自带的 overlay 目录通常 没有直接包含 SSD1306 的 overlay。所以我们需要自定义:

✏️ 创建文件 ssd1306-i2c.dts

/dts-v1/;
/plugin/;/ {compatible = "allwinner,sun8i-h3";fragment@0 {target-path = "/";__overlay__ {i2c@01c2ac00 {status = "okay";ssd1306: ssd1306@3c {compatible = "solomon,ssd1306fb-i2c";reg = <0x3c>;pinctrl-names = "default";reset-gpios = <0>; /* if no reset pin */width = <128>;height = <64>;page-offset = <0>;seg-remap;com-invdir;contrast = <127>;};};};};
};

说明:

  • 如果你接的是 128x32 OLED,请将 height = <32>
  • 若有 reset 引脚可设置为 <&pio X Y GPIO_ACTIVE_LOW>,比如 <&pio 0 6 0> 是 PA6。

🛠️ 编译 & 安装

dtc -@ -I dts -O dtb -o ssd1306-i2c.dtbo ssd1306-i2c.dts
sudo cp ssd1306-i2c.dtbo /boot/dtb/allwinner/overlay/

修改 /boot/armbianEnv.txt 添加:

user_overlays=ssd1306-i2c

然后重启:

sudo reboot

✅ 4. 驱动检查

确认驱动模块是否加载:

lsmod | grep ssd1306

如果没有:

sudo modprobe ssd1306

也可以添加到 /etc/modules 里让其开机加载:

echo ssd1306 | sudo tee -a /etc/modules

✅ 5. 显示内容(Python)

安装 Python 库

sudo apt install python3-pip
pip3 install luma.oled

示例 Python 脚本

from luma.core.interface.serial import i2c
from luma.oled.device import ssd1306
from PIL import ImageDraw, ImageFont, Imageserial = i2c(port=0, address=0x3C)
device = ssd1306(serial)draw = ImageDraw.Draw(Image.new("1", device.size))
font = ImageFont.load_default()
draw.text((0, 0), "Hello NanoPi!", font=font, fill=255)device.display(draw.im)

✅ 6. 常见问题排查

问题原因
/dev/i2c-0 不存在overlay 没启用 i2c0
i2cdetect 无响应或空线路错误 / 接线问题
OLED 无反应地址错误(0x3c vs 0x3d),接错线,驱动未加载
无法加载驱动没有开启内核模块 CONFIG_FB_SSD1306
Python 报错未装 luma.oled 或设备没有正确挂载

✅ 小结

你只需要:

  1. 确保 I2C 通了 → overlays=i2c0
  2. 加载自定义 Overlay → ssd1306@3c
  3. 加载驱动 → ssd1306fb(内核驱动或 Python 用户空间库)
  4. 选定显示方式 → 控制台 framebuffer 或 Python 图形库

很好!你想通过 framebuffer 控制 SSD1306 OLED(I2C 接口),这样你可以直接使用命令行工具、C 程序或 Shell 脚本将图像、文字显示到屏幕上,而不需要 Python 库。


🧩 目标实现:

让 SSD1306 显示屏出现在 /dev/fb1,通过 catfbidd 等 framebuffer 工具控制它显示内容。


✅ 1. 检查内核模块

确保内核已包含以下模块(Armbian 通常自带):

lsmod | grep ssd1306

如果没有,手动加载:

sudo modprobe ssd1306
sudo modprobe ssd1306fb

⚠️ 如果提示模块不存在,可能你需要启用模块支持并重新编译内核(我可指导你做)。


✅ 2. 设备树 Overlay(带 framebuffer 绑定)

使用下面的 .dts 文件创建 overlay,挂载 SSD1306,并启用 framebuffer 输出。

✏️ 文件:ssd1306-fb-i2c.dts

/dts-v1/;
/plugin/;/ {compatible = "allwinner,sun8i-h3";fragment@0 {target = <&i2c0>;__overlay__ {status = "okay";ssd1306fb: ssd1306fb@3c {compatible = "solomon,ssd1306fb-i2c";reg = <0x3c>;width = <128>;height = <64>;page-offset = <0>;seg-remap;com-invdir;contrast = <127>;rotate = <0>;};};};
};

✅ 3. 编译并启用 overlay

dtc -@ -I dts -O dtb -o ssd1306-fb-i2c.dtbo ssd1306-fb-i2c.dts
sudo cp ssd1306-fb-i2c.dtbo /boot/dtb/overlay/

编辑 /boot/armbianEnv.txt,添加:

user_overlays=ssd1306-fb-i2c

保存后重启:

sudo reboot

✅ 4. 验证 framebuffer

重启后检查:

ls /dev/fb*

你应该看到 /dev/fb1(主 framebuffer 通常是 fb0)

确认信息:

cat /sys/class/graphics/fb1/name

应返回:ssd1306fb

查看分辨率:

cat /sys/class/graphics/fb1/virtual_size

✅ 5. 使用 framebuffer 工具显示内容

🖼️ 显示图片(需安装 fbi 工具)

sudo apt install fbi
sudo fbi -d /dev/fb1 -T 1 --noverbose -a your-image.png

注意:

  • 图片必须为 单色位图(1bit bmp/png),大小 128×64。
  • 你也可以用 imagemagick 转图:
convert input.png -resize 128x64\! -monochrome out.bmp

🧪 输出简单图像(命令行写 framebuffer)

sudo bash -c 'dd if=/dev/zero of=/dev/fb1 bs=1024 count=1'

这会清空屏幕。

你可以写一个程序像素级控制 /dev/fb1,例如写字符、画图。


✅ 6. 示例:C 程序写 framebuffer

#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main() {int fb = open("/dev/fb1", O_RDWR);if (fb < 0) return 1;// 简单填充图案char buffer[1024]; // 128 x 64 = 1024 bits = 128 bytes x 8 linesmemset(buffer, 0xAA, sizeof(buffer)); // 交错黑白条纹write(fb, buffer, sizeof(buffer));close(fb);return 0;
}

✅ 小结

步骤动作
1️⃣确保 OLED 连到 I2C(地址 0x3c)
2️⃣使用 ssd1306fb-i2c overlay
3️⃣检查 /dev/fb1 是否出现
4️⃣fbidd、程序操作 framebuffer 显示内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88713.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88713.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/88713.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArkUI-X的声明式语法转换过程

以下是ArkUI-X声明式语法转换过程的详细解析&#xff0c;结合其核心设计原理与实现机制&#xff1a; ‌一、基础语法转换规则 组件声明转换 传统命令式组件创建&#xff08;如Android XMLJava&#xff09;转换为ArkUI-X的Component结构&#xff1a; // 命令式&#xff08;A…

Docker 入门教程(一):从概念到第一个容器

文章目录 &#x1f433; Docker 入门教程&#xff08;一&#xff09;&#xff1a;从概念到第一个容器1. Docker 是什么&#xff1f;2. Docker 的核心概念3. 安装 Docker4. 运行你的第一个 Docker 容器 &#x1f433; Docker 入门教程&#xff08;一&#xff09;&#xff1a;从概…

如何在 Vue 应用中嵌入 ONLYOFFICE 编辑器

以下是仅包含 纯前端集成 ONLYOFFICE 文档编辑器到 Vue.js 项目 的完整代码与说明&#xff0c;无需重新创建项目&#xff0c;可直接集成到现有 Vue 项目中&#xff1a; Vue.js 集成 ONLYOFFICE 文档编辑器&#xff08;纯前端实现&#xff09; 后端需要部署到服务器&#xff0c…

Cursor 1.0 炸裂功能:在后台运行多个Agent,释放双手

Cursor 1.0 版本更新了用于代码审查的 BugBot、对内存、一键式 MCP 设置、Jupyter 支持以及 Background Agent 的正式发布。 今天这篇文章主要介绍 Background Agent 的使用教程。 文章目录 1. Background Agent 的基本概念2. 后台 Agent 的使用方法3. 让后台 Agent 创造一个简…

MLX LM - 在Apple芯片上运行大语言模型的Python工具包

文章目录 一、关于MLX LM1、项目概览2、相关链接资源3、功能特性 二、安装配置三、使用指南1、快速开始2、Python API3、量化模型&#xff0c;上传HF4、流式生成采样 5、命令行6、长提示词与生成 四、支持模型大模型 一、关于MLX LM 1、项目概览 MLX LM是一个Python工具包&am…

【git学习】学习目标及课程安排

Git 是一款非常强大的版本控制工具&#xff0c;掌握它对编程和团队协作都有巨大帮助。 &#x1f3af;学习目标&#xff08;适合个人与团队使用&#xff09; 理解 Git 和版本控制的基本概念 熟练使用 Git 进行代码提交、分支管理、合并与冲突解决 掌握远程仓库协作流程&#x…

HDFS(Hadoop分布式文件系统)总结

文章目录 一、HDFS概述1. 定义与定位2. 核心特点 二、HDFS架构核心组件1. NameNode&#xff08;名称节点&#xff09;2. DataNode&#xff08;数据节点&#xff09;3. Client&#xff08;客户端&#xff09;4. Secondary NameNode&#xff08;辅助名称节点&#xff09; 三、数据…

破局与融合:破解开发与供应链安全的业务场景难题

数字化转型下的安全新范式与融合挑战 在数字化浪潮的席卷下&#xff0c;企业正全面拥抱云计算、微服务、容器化和开源技术。这种转型在极大提升业务敏捷性的同时&#xff0c;也带来了全新的安全挑战&#xff1a;传统网络边界消融&#xff0c;攻击面急剧扩大&#xff0c;“开发安…

Centos7 安装部署Git、创建仓库

概述 Git版本控制&#xff0c;大家都不会陌生&#xff0c;实践诉求是从零部署本地Git服务&#xff0c;在执行推送远程分支代码时&#xff0c;用Git服务自带的hooks触发同步代码文件&#xff0c;从而做到自动同步代码&#xff0c;实现自动更新&#xff0c;操作环境centos7.9,Gi…

【Redis原理】Redis数据结构底层原理

目录 一、SDS 二、IntSet&#xff08;整数集合&#xff09; 三、双向链表 四、压缩列表 五、字典&#xff08;哈希表&#xff09; 七、跳表 八、QuickList 九、RedisObject 一、SDS Redis 是用 C语言实现的&#xff0c;但是它没有直接使用C 语言的 char* 字符数组来实现…

C#.NET HttpClient 使用教程

简介 HttpClient 是 .NET 中用于发送 HTTP 请求和接收 HTTP 响应的现代化 API&#xff0c;它取代了过时的 WebClient 和 HttpWebRequest 类。 HttpClient 是 .NET Framework 4.5 和 .NET Core/.NET 5 中提供的、基于消息处理管道&#xff08;message handler pipeline&#…

Nginx常用安全配置指南

Nginx是一个轻量级的&#xff0c;高性能的Web服务器以及反向代理和邮箱代理服务器。它运行在UNIX、GNU、linux、BSD、Mac OS X、Solaris和Windows各种版本。根据调查统计数据显示&#xff0c;当前全球超过6%的网站使用Nginx Web服务器来管理Web网站应用。 为了保证基于Nginx的…

【UniApp 日期选择器实现与样式优化实践】

UniApp 日期选择器实现与样式优化实践 发布时间&#xff1a;2025/6/26 前言 在移动端应用开发中&#xff0c;日期选择器是一个常见且重要的交互组件。本文将分享我们在 UniApp 项目中实现自定义日期选择器的经验&#xff0c;特别是在样式优化过程中遇到的问题及解决方案。通过…

推荐系统的视频特征-视频关键帧特征提取与向量生成

&#x1f4cc; 总体流程概览 视频文件 (.mp4)↓ 关键帧抽取&#xff08;FFmpeg / SceneDetect&#xff09;↓ 帧图像&#xff08;.jpg&#xff09;↓ 图像模型提取特征&#xff08;CLIP / CNN / ViT&#xff09;↓ 多帧聚合成视频向量&#xff08;均值池化等&#xff09;↓ 向…

Apache SeaTunnel Flink引擎执行流程源码分析

目录 1. 任务启动入口 2. 任务执行命令类:FlinkTaskExecuteCommand 3. FlinkExecution的创建与初始化 3.1 核心组件初始化 3.2 关键对象说明 4. 任务执行:FlinkExecution.execute() 5. Source处理流程 5.1 插件初始化 5.2 数据流生成 6. Transform处理流程 6.1 插…

Vue 3 + Element Plus 实现「动态表单组件」详解教程

✅ Vue 3 Element Plus 实现「动态表单组件」详解教程 &#x1f4cc; 适用场景&#xff1a;表单字段根据配置动态生成&#xff0c;支持校验、提交、自定义组件、复杂布局等。 &#x1f9e9; 技术栈&#xff1a;Vue 3 TypeScript Element Plus &#x1f527; 核心特性&#x…

本地部署开源时间跟踪工具 Kimai 并实现外部访问( Windows 版本)

Kimai 是一款开源的时间跟踪工具&#xff0c;它易于使用&#xff0c;并提供了强大的报告功能&#xff0c;在个人和团队记录工作时间、项目时间和活动时间等之后可以帮助用户了解他们是如何花费时间的&#xff0c;从而提高生产力和效率。本文将详细介绍如何在 Windows 系统本地部…

系统分析师案例知识点

目录 1 必做题1.1 状态机图1.2 活动图1.3 统一软件开发过程RUP 2 需求分析2.1 数据流图DFD2.2 ER图2.3 状态转换图STD2.4 数据字典2.5 流程图2.6 需求评审2.7 设计类2.8 FAST分析2.9 常见的关系类 3 嵌入式3.1 容器技术3.2 虚拟机技术3.3 虚拟机和容器的不同点 4 数据库4.1 NoS…

多相机人脸扫描设备如何助力高效打造数字教育孪生体?

在教育数字化转型浪潮中&#xff0c;数字孪生体作为现实教育场景的虚拟映射&#xff0c;正成为智慧教育发展的关键技术支点。传统教育模式面临师资资源分布不均、个性化教学难以覆盖、跨时空教学场景受限等痛点&#xff0c;而数字孪生体通过构建高仿真虚拟教育主体&#xff08;…

用 EXCEL/WPS 实现聚类分析:赋能智能客服场景的最佳实践

聚类分析作为无监督学习的核心技术&#xff0c;能在客服数据中发现隐藏的用户群体或问题模式。尽管 Excel/WPS 并非专业统计软件&#xff0c;但巧妙利用其内置功能&#xff0c;也能实现基础的聚类分析&#xff0c;为中小型客服团队提供快速洞察。以下介绍具体方法及智能客服场景…