嵌入式Linux驱动开发:设备树与平台设备驱动

嵌入式Linux驱动开发:设备树与平台设备驱动

引言

本笔记旨在详细记录嵌入式Linux驱动开发中设备树(Device Tree)和平台设备驱动(Platform Driver)的核心概念与实现。通过分析提供的代码与设备树文件,我们将深入理解如何在i.MX6ULL平台上使用设备树来描述硬件,并通过平台设备驱动来管理这些硬件资源。本文档将结合代码实例,详细解释每个关键部分的作用与实现细节。

设备树(Device Tree)

设备树是一种数据结构,用于描述硬件的配置和连接方式,使得操作系统可以在不硬编码硬件信息的情况下初始化和使用硬件。设备树文件通常以.dts为扩展名,编译后生成.dtb文件,由引导加载程序传递给内核。

设备树文件结构

设备树文件由一系列节点(node)和属性(property)组成。每个节点代表一个硬件设备或子系统,属性则描述该设备的具体配置。

根节点

设备树的根节点用/表示,包含全局属性和子节点。

/dts-v1/;
#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"/ {model = "Freescale i.MX6 ULL 14x14 EVK Board";compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";...
};
  • model:描述开发板的型号。
  • compatible:指定设备的兼容性,用于匹配驱动程序。
子节点

子节点描述具体的硬件设备,如内存、外设等。

memory {reg = <0x80000000 0x20000000>;
};
  • memory节点描述系统的物理内存布局,reg属性指定内存的起始地址和大小。

设备树源文件(DTSI)

设备树源文件(.dtsi)类似于C语言的头文件,包含多个.dts文件共享的通用定义。通过#include指令引入。

#include "imx6ull.dtsi"

设备树编译

设备树文件需要编译成二进制格式(.dtb),通常使用dtc(Device Tree Compiler)工具完成。

dtc -I dts -O dtb -o imx6ull-alientek-emmc.dtb imx6ull-alientek-emmc.dts

平台设备驱动

平台设备驱动是Linux内核中用于管理平台特定设备的一种机制。它通过设备树描述硬件资源,并在驱动程序中解析这些资源。

平台设备(Platform Device)

平台设备由platform_device结构体表示,包含设备的名称、资源和私有数据。

资源定义

资源定义了设备所需的内存、中断等硬件资源。

static struct resource led_resources[] = {[0] = {.start = CCM_CCGR1_BASE,.end = CCM_CCGR1_BASE + REGISTER_LNE - 1,.flags = IORESOURCE_MEM,},...
};
  • startend:资源的起始和结束地址。
  • flags:资源类型,如IORESOURCE_MEM表示内存资源。
平台设备注册

平台设备通过platform_device_register函数注册到内核。

static struct platform_device leddevice = {.name = "imx6ull-led",.id = -1,.dev = {.release = leddevice_realease,},.num_resources = ARRAY_SIZE(led_resources),.resource = led_resources,
};static int __init leddevice_init(void)
{platform_device_register(&leddevice);return 0;
}

平台驱动(Platform Driver)

平台驱动由platform_driver结构体表示,包含驱动的名称、匹配表、探测和移除函数。

匹配表

匹配表用于将驱动与设备树中的节点关联。

struct of_device_id led_of_match[] = {{.compatible = "alientek,gpioled"},{/* sentinel */}
};
  • compatible:与设备树中节点的compatible属性匹配。
探测函数

探测函数在设备与驱动匹配成功后调用,用于初始化设备。

static int led_probe(struct platform_device *dev)
{gpioled.nd = of_find_node_by_path("/gpioled");if (gpioled.nd == NULL) {printk("gpioled node not find!\r\n");return -EINVAL;}gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpios", 0);if (gpioled.led_gpio < 0) {printk("can't get led-gpio");return -EINVAL;}ret = gpio_direction_output(gpioled.led_gpio, 1);if (ret < 0) {printk("can't set gpio!\r\n");}// 注册字符设备驱动...return 0;
}
  • of_find_node_by_path:根据路径查找设备树节点。
  • of_get_named_gpio:从设备树节点中获取GPIO编号。
  • gpio_direction_output:设置GPIO为输出模式。
移除函数

移除函数在设备卸载时调用,用于释放资源。

static int led_remove(struct platform_device *dev)
{cdev_del(&gpioled.cdev);unregister_chrdev_region(gpioled.devid, GPIOLED_CNT);device_destroy(gpioled.class, gpioled.devid);class_destroy(gpioled.class);return 0;
}

字符设备驱动

字符设备驱动通过file_operations结构体定义设备的操作函数。

static struct file_operations gpioled_fops = {.owner = THIS_MODULE,.open = led_open,.read = led_read,.write = led_write,.release = led_release,
};
  • open:打开设备。
  • read:读取设备数据。
  • write:写入设备数据。
  • release:关闭设备。

应用程序

应用程序通过系统调用与驱动程序交互,控制硬件设备。

int main(int argc, char *argv[])
{int fd, retvalue;char *filename;unsigned char databuf[1];if (argc != 3) {printf("Error Usage!\r\n");return -1;}filename = argv[1];fd = open(filename, O_RDWR);if (fd < 0) {printf("file %s open failed!\r\n", argv[1]);return -1;}databuf[0] = atoi(argv[2]);retvalue = write(fd, databuf, sizeof(databuf));if (retvalue < 0) {printf("LED Control Failed!\r\n");close(fd);return -1;}close(fd);return 0;
}
  • open:打开设备文件。
  • write:向设备写入数据,控制LED状态。
  • close:关闭设备文件。

参考资料

  • 源码仓库

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

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

相关文章

【完整源码+数据集+部署教程】骨折检测系统源码和数据集:改进yolo11-EfficientHead

背景意义 骨折作为一种常见的骨骼损伤&#xff0c;其诊断和治疗对患者的康复至关重要。传统的骨折检测方法主要依赖于医生的经验和影像学检查&#xff0c;如X光、CT等&#xff0c;这不仅耗时&#xff0c;而且容易受到主观因素的影响。随着计算机视觉和深度学习技术的迅猛发展&a…

面试记录7 c++软件开发工程师

开目 一面&#xff1a; 自我介绍你做的xxx应用是用c做的吗&#xff0c;是在window平台吗具体做的事情是什么你说的2D3D的结构是什么样的&#xff0c;怎样去做校验有没有二维到三维或者三维到二维的数据转换两个向量怎么去做校验做的什么优化有调用第三方库吗是用的什么工具&…

计算机网络:服务器处理多客户端(并发服务器)

一、服务器处理多客户端&#xff08;并发服务器&#xff09;&#xff08;一&#xff09;listen:监听客户端的连接请求&#xff0c;放入请求队列&#xff08;二&#xff09;accpet&#xff1a;请求队列中提取已连接的请求&#xff0c;返回连接好的fd&#xff08;循环accpet即可&…

Ansible自动化运维:原理以及安装教程

目录 Linux Ansible&#xff1a;作用与原理详解 一、Ansible 的核心作用 1. 配置管理&#xff08;Configuration Management&#xff09; 2. 应用部署&#xff08;Application Deployment&#xff09; 3. 任务编排&#xff08;Orchestration&#xff09; 4. 其他扩展作用 二、A…

[机器学习]基于K-means聚类算法的鸢尾花数据及分类

基于Kmeans&#xff0c;对鸢尾花数据集前两个特征进行聚类分析通过迭代优化&#xff0c;将150个样本划分到K个簇中。目标函数&#xff1a;最小化所有样本到其所属簇中心的距离平方和。算法步骤&#xff1a;随机初始化K个簇中心。将每个样本分配到最近的中心。计算均值确定每个簇…

Altium Designer 22使用笔记(10)---PCB铺铜相关操作

目录 01 | 简 述 02 | 环境描述 03 | 铺 铜 04 | 铺铜挖空 05 | 敷铜合并 06 | 敷铜的修改 07 | 总 结 01 | 简 述 在PCB设计阶段&#xff0c;除了布局、布线操作需要频繁进行调整外&#xff0c;铺铜操作的使用也非常频繁&#xff1b;因此本篇文章的主要内容为&#xff…

leetcode 338 比特位计数

一、题目描述二、解题思路我们可以借助位运算的思想来解决这个问题。通过kk&(k-1)来消除k中最右边为1的比特位&#xff0c;每次消除后进行count&#xff0c;当k为0时&#xff0c;表示所有的1消除完毕&#xff0c;此时的count即为所有1的个数。三、代码实现时间复杂度&#…

PHP的md5()函数分析

MD5&#xff08;Message-Digest Algorithm 5&#xff09;是一种广泛使用的哈希函数&#xff0c;由Ronald Rivest于1991年设计&#xff0c;属于密码散列算法家族。其核心功能是将任意长度的输入数据&#xff08;如字符串、文件等&#xff09;通过不可逆的数学运算转换为固定长度…

【面试场景题】怎么做业务领域划分

文章目录一、核心原则&#xff1a;以业务为中心&#xff0c;而非技术二、具体步骤&#xff1a;从业务理解到边界定义1. 深入理解业务&#xff1a;梳理业务全景2. 识别核心领域与支撑领域3. 划分“限界上下文”&#xff1a;定义领域边界4. 定义领域内的“聚合”&#xff1a;细化…

海量小文件问题综述和解决攻略(二)

1. 解决NameNode的内存问题 上面的内容提到过每个block的元数据都需要加载到NameNode的内存中&#xff0c;这导致一个Hadoop集群在NameNode中存储的对象是有上限的&#xff0c;并且对象太多会带来启动时间较长以及网络延迟的问题。常见的有两种解决方案&#xff0c;减少集群的…

《开发避坑指南:从异常中读懂系统的“求救信号”》

异常现象从不只是孤立的“故障”&#xff0c;而是系统发出的“健康预警”。太多团队困在“出现问题-临时修复-再次复发”的循环里&#xff0c;将精力消耗在表面问题的扑救上&#xff0c;却忽视了背后潜藏的架构缺陷、逻辑漏洞与环境适配盲区。真正成熟的开发思维&#xff0c;是…

数字孪生技术为UI前端赋能:实现产品性能的实时监测与预警

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!过去十年&#xff0c;前端技术栈翻天覆地&#xff1a;React/Vue/Angular、Webpack/Vite、Serve…

【性能优化】Unity 渲染优化全解析:Draw Call、Batch、SetPass 与批处理技术

Unity 渲染优化全解析&#xff1a;Draw Call、Batch、SetPass 与批处理技术 在 Unity 开发中&#xff0c;性能优化是保证游戏流畅的核心环节。尤其在移动端或 VR/AR 场景&#xff0c;Draw Call 过多、材质切换频繁都会严重影响帧率。 本文将从 Unity Statistics 面板参数解析…

基于Spring Boot的短信平台平滑切换设计方案

基于Spring Boot的短信平台平滑切换设计方案 案例背景 在电商系统中&#xff0c;短信服务是用户注册、登录验证、订单通知等环节的关键基础设施。由于业务需求或成本优化&#xff0c;企业可能需要在不同短信平台&#xff08;如阿里云、腾讯云、云片等&#xff09;之间进行切换。…

信息技术发展

信息技术是研究如何获取信息、处理信息、传输信息和使用信息的技术。计算机硬件控制器、运算器、存储器、输入设备、输出设备。计算机软件系统软件、应用软件、中间件。通信系统包括源系统、传输系统、目的系统。网络基础 个人局域网、局域网、城域网、广域网、公用网、专用网。…

2023年12月GESP5级C++真题解析,包括选择判断和编程

一、选择题&#xff08;每道题2分&#xff0c;共30分&#xff09; 1、下面C代码用于求斐波那契数列&#xff0c;该数列第1 、2项为1&#xff0c;以后各项均是 前两项之和。下面有关说法错误的是( ) A. fiboA( ) ⽤递归⽅式&#xff0c;fiboB() 循环⽅式 B. fiboA( ) 更加符合…

C++ 面试高频考点 力扣 704.二分查找 基础二分查找 题解 每日一题

文章目录二分查找&#xff1a;从基础原理到代码实现二分查找的特点算法重点题目描述&#xff1a;LeetCode 704. 二分查找为什么可以用二分查找&#xff1f;暴力算法解法二分查找解法核心逻辑&#xff1a;三种情况的处理二分查找什么时候结束&#xff1f;为什么二分查找一定是对…

《UE5_C++多人TPS完整教程》学习笔记45 ——《P46 待机与跳跃动画(Idle And Jumps)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P46 待机与跳跃动画&#xff08;Idle And Jumps&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09…

2025年03月 Scratch 图形化(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch图形化等级考试(1~4级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 气球初始位置如下图所示,运行下列程序,气球会朝哪个方向移动?( ) A:水平向右 B:垂直向下 C:水平向左 D:垂直向上 答案:A 气球水平向右移动 第2题 使用下列哪个选项可以将…

android 不同分辨图片放错对应文件夹会怎样?

多年前有人问过我这个问题&#xff0c;当时没太了解这个东西&#xff0c;觉得是无所谓的东西&#xff0c;不过没答上来这个问题还是让我记了很久。今天又看到有人发文章讨论这个问题&#xff0c;我也就特意再研究下。1&#xff0c;了解一下Android分辨率是什么。2&#xff0c;同…