设备驱动模型

设备驱动模型 - kobject 目录 一. 设备驱动模型简介 二. kobject简介 2.1 kobject内核数据结构 2.2 kobject操作内核接口 三. kobject实例 3.1 Makefile 3.2 实例1 3.3 实例2 3.4 实例3 一. 设备驱动模型简介 Linux设备模型的核心是使用Bus、Class、Device、Driver四个核心数据结构,将大量的、不同功能的硬... 阅读详情

优快云仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
本博文对应地址: https://hceng.cn/2017/03/18/设备驱动模型/#more
最近在看设备驱动模型,记录下分析的结构。


设备驱动模型提供了硬件的抽象,内核可以使用该抽象完成很多硬件重复的工作,这样很多重复的代码就不需要重复编写和调试了。这些抽象包括:电源管理、即插即用设备的支持、与用户空间的通信。

1.sysfs文件系统

sysfs文件系统是Linux众多文件系统中的一个,在Linux中每个文件系统都要自己的特殊的用途。Liunx设备驱动模型由大量的数据结构和算法组成,数据结构之间通过指针相互关联,构成树形或者网状关系。显示这种关系最好的利用树形结构的文件系统,同时还要显示内核中一些关于设备、驱动和驱动的信息,因此内核开发者创造sysfs这种新文件系统来实现上述的要求。
  sysfs是一个只存在于内存的文件系统,内核通过这个文件系统将系统信息导出到用户空间,同时用户空间的数据也能通过它传到内核中,实现设置驱动程序的状态和属性。
  sysfs文件系统是内核对象(kobject)、属性(kobj_type)及它们互相关系的一种表现机制。内核与sysfs的关系如下:

Linux内核中的结构sysfs中的结构
kobject目录
kobj_type属性文件
对象间的关系符号链接
![](https://blog-image-1257972744.cos.ap-chongqing.myqcloud.com/hceng/blog_image/170318/1.jpg)

2.核心数据结构

设备驱动模式由kobject、kset、subsystem这三个核心数据结构组成。

2.1 kobject

在Linux系统中,kobject结构体是组成设备驱动模型的基本结构,提供最基本的设备对象管理能力,每个在内核注册的kobject对象都对应sysfs文件系统中的一个目录。

  kobject结构体:
{% codeblock lang:c %}
struct kobject {
const char name; / 对应sysfs的目录名 /
struct list_head entry; /
kobjetct双向链表 ,指向下一个kobject结构*/
struct kobject parent; / 指向kset中的kobject,相当于指向父目录 */
struct kset *kset; /*指向所属的kset */
struct kobj_type *ktype; /指向kobject的类型描述符/
struct sysfs_dirent *sd; /对应的sysfs文件目录/
struct kref kref; /kobject引用计数,为0释放/
unsigned int state_initialized:1; /kobject是否已初始化,1初0未/
unsigned int state_in_sysfs:1 ; /kobject是否注册到sysfs/
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};
{% endcodeblock %}
  kobject操作函数:

2.2 kset

kobject通过kset组织层次化,kest是拥有相同类型的kobject的集合。
  kset结构体:
{% codeblock lang:c %}
struct kset {
struct list_head list; /* 连接所包含的kobject对象的链表头部 /
spinlock_t list_lock; /
添加/删除kobject时使用的自旋锁 */
struct kobject kobj; /*所有属于该kset的kobject的parent均指向这 */
const struct kset_uevent_ops uevent_ops; / 热拔插事件函数集 */
};
{% endcodeblock %}
  kset操作函数:

kest和kobject关系:

2.3 注册kobject到sysfs中的实例

{% codeblock lang:c [kobject_test.c] https://github.com/hceng/learn/blob/master/kobject_test/kobject_test.c%}
/*
目的:在/sys目录下添加一个名为kobject_test的目录名,
并在该目录下添加一个kobject_test_attr的文件,这个文件为属性文件;
功能:koject_test_show()函数显示属性的值;
kobject_test_store()函数向属性中写入一个值;
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/stat.h>

/声明释放kobject结构体函数/
void kobject_test_release(struct kobject *kobject);

/读属性的函数/
ssize_t kobject_test_show(struct kobject *kobject, struct attribute *attr, char *buf);

/写属性的函数/
ssize_t kobject_test_store(struct kobject *kobject, struct attribute *attr, const char *buf, size_t count);

/定义了一个名为kobject_test,可以读写的属性/
struct attribute test_attr = {
.name = “kobject_test_attr”,
.mode = S_IRWXUGO,
};

/该object只有一个属性/
static struct attribute *def_attrs[] = {
&test_attr,
NULL,
};

/操作函数/
struct sysfs_ops obj_test_sysops = {
.show = kobject_test_show,
.store = kobject_test_store,
};

/kobject属性/
struct kobj_type ktype = {
.release = kobject_test_release,
.sysfs_ops = &obj_test_sysops,
.default_attrs = def_attrs,
};

/释放kobject结构体函数/
void kobject_test_release(struct kobject *kobject)
{
printk(“kobject_test: kobject_test_release(). \n”);
}

/该函数用于读取一个属性的名字/
ssize_t kobject_test_show(struct kobject *kobject, struct attribute *attr, char *buf)
{
printk(“call kobject_test_show(). \n”);
printk(“attrname:%s.\n”, attr->name);
sprintf(buf, “%s\n”, attr->name);
return strlen(attr->name)+2;
}

/该函数用于写入一个属性的值/
ssize_t kobject_test_store(struct kobject *kobject, struct attribute *attr, const char *buf, size_t count)
{
printk(“call kobject_test_store(). \n”);
printk(“write: %s\n”, buf);
strcpy(attr->name, buf);
return count;
}

/入口函数/
struct kobject kobj;
static int kobject_test_init()
{
printk(“kobject test_init().\n”);
kobject_init_and_add(&kobj, &ktype, NULL, “kobject_test”);
return 0;
}

/出口函数/
static int kobject_test_exit()
{
printk(“kobject test exit.\n”);
kobject_del(&kobj);
return 0;
}

module_init(kobject_test_init);
module_exit(kobject_test_exit);
MODULE_AUTHOR(“hceng”);
MODULE_LICENSE(“Dual BSD/GPL”);
{% endcodeblock %}

{% codeblock lang:c [kobject_app.c] https://github.com/hceng/learn/blob/master/kobject_test/kobject_app.c%}

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

/*
kobject_test
*/
int fd;

int main(int argc, char **argv)
{
fd = open("/dev/kobject_test", O_RDWR);
if (fd < 0)
{
printf(“can’t open!\n”);
return -1;
}

return 0;

}
{% endcodeblock %}

调用关系:

3.三大组件

设备驱动模型中有三个重要的组件:总线(bus_type)、设备(device)、驱动(driver),三者关系如下:

  • bus_type通过扫描设备链表和驱动链表,使用mach方法查找匹配的设备和驱动,然后将struct device中的*driver设置为匹配的驱动;
  • 将struct device_driver中的device设置为匹配的设备,这就完成了将总线、设备和驱动3者之间的关联;
  • bus_type只有很少的成员必须提供初始化,大部分由设备模型核心控制;
  • 内核提供许多函数实现bus_type的注册注销等操作,新注册的总线可以再**/sys/bus目录**下看到;

3.1总线

总线数据结构bus_type:
{% codeblock lang:c %}
struct bus_type {
const char name; / 总线类型名 */
struct bus_attribute bus_attrs; / 总线的属性、方法 */
struct device_attribute dev_attrs; / 设备属性,为每个加入总线的设备建立属性链表 */
struct driver_attribute drv_attrs; / 驱动属性,为每个加入总线的驱动建立属性链表 */

/* 驱动与设备匹配函数:当一个新设备或者驱动被添加到这个总线时,这个方法会被调用一次或多次,
若指定的驱动程序能够处理指定的设备,则返回非零值。
必须在总线层使用这个函数, 因为那里存在正确的逻辑,核心内核不知道如何为每个总线类型匹配设备和驱动程序 */
int (*match)(struct device *dev, struct device_driver *drv);
/在为用户空间产生热插拔事件之前,这个方法允许总线添加环境变量(参数和 kset 的uevent方法相同)/
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device dev); / 设备移除调用操作 */
void (*shutdown)(struct device *dev);

 int (*suspend)(struct device *dev, pm_message_t state);
 int (*resume)(struct device *dev);

 const struct dev_pm_ops *pm;                     /*电源管理相关操作符*/

 struct subsys_private *p;                                /* 一个很重要的域,包含了device链表和drivers链表 */

};
{% endcodeblock %}    

  相关操作函数:

3.2设备

设备数据结构device:
{% codeblock lang:c %}
struct device {
struct device parent; / 父设备,总线设备指定为NULL */
struct device_private p; / 包含设备链表,driver_data(驱动程序要使用数据)等信息 */
struct kobject kobj;
const char init_name; / 初始默认的设备名,但@device_add调用之后又重新设为NULL */
struct device_type type;
struct mutex mutex; /
mutex to synchronize calls to its driver */
struct bus_type bus; / type of bus device is on */
struct device_driver driver; / which driver has allocated this device */
void platform_data; / Platform specific data, device core doesn’t touch it */
struct dev_pm_info power;

#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 dma_mask; / dma mask (if dma’able device) */
//Like dma_mask, but for alloc_coherent mappings as not all hardware supports 64 bit addresses
//for consistentallocations such descriptors.
u64 coherent_dma_mask;
struct device_dma_parameters dma_parms;
struct list_head dma_pools; /
dma pools (if dma’ble) */
struct dma_coherent_mem dma_mem; / internal for coherent mem override /
/
arch specific additions */
struct dev_archdata archdata;
#ifdef CONFIG_OF
struct device_node *of_node;
#endif

 dev_t devt;	 /* dev_t, creates the sysfs "dev" 设备号 */
 spinlock_t devres_lock;
 struct list_head devres_head;
 struct klist_node knode_class;
 struct class *class;
 const struct attribute_group **groups; 	/* optional groups */

 void (*release)(struct device *dev); 

};
{% endcodeblock %}  

3.3驱动

驱动数据结构driver·:
{% codeblock lang:c %}
struct device_driver {
const char name; / 驱动名称,在sysfs中以文件夹名出现 */
struct bus_type bus; / 驱动属于的总线,总线上可以有很多设备 */
struct module owner; / 设备驱动自身模块 */
const char mod_name; / 驱动模块名字 /
bool suppress_bind_attrs; /
disables bind/unbind via sysfs */

const struct of_device_id  *of_match_table;
 /*检测设备方法,并检测设备驱动可以控制那些设备*/
 int (*probe) (struct device *dev);
 int (*remove) (struct device *dev);	/*移除设备时调用的方法*/
 void (*shutdown) (struct device *dev);	/*关闭设备时调用的方法*/
 int (*suspend) (struct device *dev, pm_message_t state); /*处于低功耗时调用的方法*/
 int (*resume) (struct device *dev);	/*恢复正常状态时调用的方法*/
 const struct attribute_group **groups; 	/*属性组*/

 const struct dev_pm_ops  *pm;	/*用于电源管理*/

 struct driver_private  *p;	 /* 定义device_driver中的私有数据类型 */

};
{% endcodeblock %}  

五.linux设备驱动模型 站在设备驱动这个角度分析,设备驱动模型是如何构建出来,起到什么作用,认识它并在写驱动的时候去利用设备驱动模型 目录 一.linux 设备驱动模型简介 1.1、 什么是设备驱动模型 1.2、 为什么需要设备驱动模型 1.3、 驱动开发的2个点 二.设备驱动模型的底层架构 2.1、kobject结构体 2.2、kobj_type结构体 2.3、kset结构体 三.总线式设备驱... 阅读详情

相关推荐

linux设备驱动的模型详解

一、什么是设备驱动模型 (1)类class、总线bus、设备device、驱动driver 四个结构体 (2)kobject和对象生命周期 (3)sysfs cat 查看属性信息 、 echo 往里面写东西 (4)udev 同步信息2、设备模型解决了一些什么问题? (1)设备驱动模型负责统一实现和维护一些特性,诸如:电源管理、热插拔、对象生命周期、用

huangliangben的博客 1695

探究Linux的总线、设备、驱动模型

理解Linux的总线、设备、驱动模型是理解Linux驱动框架的关键,也是破解Linux为什么极易移植到不同的平台,以及被如此多广泛领域使用根源的关键。我的优快云直播将以浅显易懂地语言,深入地把这一模型剖析清楚,道出这样的设计的好处。

安捷伦示波器实战指南:从基础操作到精准触发

本文详细介绍了安捷伦示波器的基础操作与高级功能,包括精准触发配置、波形分析和常见问题排查。通过实战技巧和优化建议,帮助工程师快速掌握示波器的核心功能,提升调试效率。特别适合电子工程师和测试技术人员参考使用。

weixin_30839881的博客 135

Linux驱动开发实战(一)——设备驱动模型

在早期的Linux内核中并没有为设备驱动提供统一的设备模型。随着内核的不断扩大及系统更加复杂,编写一个驱动程序越来越困难,所以在Linux2.6内核中添加了一个统一的设备模型。这样,写设备驱动程序就稍微容易一些了。本章将对设备模型进行详细的介绍。设备驱动模型比较复杂,Linux系统将设备和驱动归一到设备驱动模型中来管理。设备驱动模型的提出,解决了以前编写驱动程序没有统一方法的局面。设备驱动模型给各种驱动程序提供了很多辅助性的函数,这些函数经过严格测试,可以很大程度上地提高驱动开发人员的工作效率。

m0_56145255的博客 3357

Isograph Reliability Workbench 14实战:从零构建故障树分析模型

本文以“马达不转”为例,手把手教你使用Isograph Reliability Workbench 14从零构建故障树分析模型。内容涵盖创建工程、定义顶事件、添加逻辑门与基础事件等核心步骤,并介绍了模型检查与定性定量分析,帮助你系统掌握这一强大的可靠性工程工具。

weixin_29309213的博客 356

【AMD显卡在WIndow10/11部署带GPU支持的深度学习环境(Pytorch-DirectML篇)】

这篇是之前Tensorflow-DirectML的姊妹篇,如果对TF感兴趣的可以搜索我的博文。 首先我们丢一个官网地址,但是官网那个会误导新人如果你按那个操作的话。 https://docs.microsoft.com/en-us/windows/ai/directml/gpu-pytorch-windows 这里用我的方法操作: 首先声明一下,因为我的显卡是AMD RX6600,不带XT(性能和RTX3060 12G版本半斤八两),所以目前没有最新的WSL2驱动,如果有了的话欢迎告知我,所以我这里就.

weixin_44029053的博客 2万+

设备驱动模型:总线-设备-驱动

总线是连接处理器和设备之间的桥梁代表着同类设备需要共同遵循的工作时序。总线驱动:负责实现总线行为,管理两个链表。name:指定总线的名称,当新注册一种总线类型时,会在 /sys/bus 目录创建一个新的目录,目录名就是该参数的值;bus_groups、dev_groups、drv_groups:分别表示 总线、设备、驱动的属性。通常会在对应的 /sys 目录下在以文件的形式存在,对于驱动而言,在目录 /sys/bus//driver/ 存放了驱动的默认属性;

u013921164的博客 2736

LabVIEW vs Python:谁更适合你的ATE自动化测试系统?实测对比与选型建议

本文深入对比了LabVIEW和Python在ATE自动化测试系统中的性能表现、开发效率和应用场景,帮助工程师根据实时控制需求、数据处理复杂度及团队技能做出最优选型决策。通过实测数据和典型案例,分析两者在硬件集成、系统性能和维护成本等方面的差异,并提供混合架构实施建议。

weixin_29240711的博客 275

Linux设备驱动模型

文章目录前言1.linux设备驱动模型简介2.设备驱动模型的底层架构3.总线式设备驱动组织方式4.platform平台总线工作原理4.平台总线实践环节 前言 1.linux设备驱动模型简介 1、什么是设备驱动模型 (1)类class、总线bus、设备device、驱动driver(内核代码中有4个结构体) (2)kobject和对象生命周期(自动管理生命周期) (3)sysfs(虚拟文件系统,在内核空间和用户空间间建立关系,把内核的结构体变量的一些值以文件的形式展现出来,通过echo、cat操作属性节点

weixin_44705391的博客 4318

FPGA AXI DDR3读写时序调试与FIFO缓存实战解析

本文深入解析FPGA中AXI协议与DDR3的读写时序调试,重点探讨FIFO缓存在数据流控制中的关键作用。通过实战案例详细讲解突发传输中的地址对齐、数据分片等常见问题,并提供状态机设计、仿真波形分析和性能优化技巧,帮助开发者高效解决高速数据存储场景下的时序同步与数据一致性问题。

blockchain9miner的博客 1117

《多模态融合改进》目录一览 | 专栏介绍 :全网 第一份 完整的多模态改进教程,提供《多模态模型改进完整项目包》-开箱即用

在大家订阅专栏后,便可获得多模态模型改进完整项目包-开箱即用,方便简单

Limiiiing的博客 1万+

Linux 设备驱动模型

linux 设备驱动模型

MATLABCSD的博客 803

软件需求规格说明书(SRS)深入解析

摘要: SRS(软件需求规格说明书)是定义系统功能、性能与接口的核心文档,为开发、测试、项目管理提供依据。标准结构包括引言、总体描述、功能/非功能需求、接口等模块。撰写需确保清晰、可验证、无歧义,避免模糊术语。示例展示学生注册模块的需求写法,强调性能与安全性要求。推荐使用Confluence、StarUML等工具辅助编写,交付时需包含主文档、原型图及需求跟踪矩阵。SRS应兼具技术性与管理性,作为沟通桥梁和验收标准。

moton2017的博客 2909

linux设备驱动模型

1.什么是设备驱动模型? (1)类class、总线bus、设备device、驱动driver (2)kobject和对象生命周期 (3)sysfs (4)udev 2.为什么需要设备驱动模型? (1)早期内核(2.4之前)没有统一的设备驱动模型,但照样可以用 (2)2.6版本中正式引入设备驱动模型,目的是在设备越来越多,功耗要求等新特性要求的情况下让驱动体系更易用、更优秀。 (3)设备驱动模型负责...

qq_33472414的博客 202

Dify 第 4 篇 Dify 示例:数据库执行Agent

本文介绍了如何在Dify平台创建一个能够执行SQL查询的数据库Agent。通过安装并配置"通义千问"和"数据库"两个插件,实现自然语言到SQL语句的转换和执行。关键步骤包括:1)安装插件并配置API Key;2)设置默认数据库连接(建议使用只读账号);3)准备测试数据表结构。该Agent支持通过工具调用查询表结构、转换自然语言为SQL、执行查询并返回结果,同时提供了CSV查询和HTTP API接口功能。文中还提供了MySQL测试数据表的创建脚本和示例数据。

甘蓝的专栏 1156

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

LINUX设备驱动模型简介

××××××××××××××LINUX设备驱动模型简介×××××××××××××××××第一部分————————————————————————————————————- 1.linux设备驱动模型简介 2.设备驱动模型的底层架构:类,总线,设备,驱动,platform3.实践:使用设备驱动模型来加载上一个led驱动1.linux设备驱动模型简介 《1》什么是设备驱动模型将一个概念时怎样讲明白

love23_linuxer的博客 665

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Linux设备驱动模型1——设备驱动模型的简介与底层架构

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

主要记录嵌入式学习与开发过程。 2315

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

linux驱动 设备驱动模型

前言 在早期的Liux内核中并没有为设备驱动提供统一的设备模型。随着内核的不断扩大及系统更加复杂,编写一个驱动程序越来越困难,所以在Liux2.6内核中添加了一个统一的设备模型。这样,写设备驱动程序就稍微容易一些了。本章将对设备模型进行详细的介绍。 一、设备驱动模型概述 设备驱动模型比较复杂,Lux系统将设备和驱动归一到设备驱动模型中来管理。设备驱动模型的提出,解决了以前编写驱动程序没有统一方法的局面。设备驱动模型给各种驱动程序提供了很多辅助性的函数,这些函数经过严格测试,可以很大程度地提高驱动开发人员的

weixin_42109053的博客 2804

(五)Linux设备驱动模型介绍

本系列导航 (一)初识Linux驱动 (二)Linux设备驱动的模块化编程 (三)写一个完整的Linux驱动程序访问硬件并写应用程序进行测试 (四)Linux设备驱动之多个同类设备共用一套驱动 (五)Linux设备驱动模型介绍 (六)Linux驱动子系统-I2C子系统 (七)Linux驱动子系统-SPI子系统 (八)Linux驱动子系统-PWM子系统 (九)Linux驱动子系统-Light子系统 ...

韩朋的博客 3882

设备驱动模型的实现

关于设备驱动模型的一个简单陈述。

cryil_0301的博客 177
上一篇: Linux常用命令
下一篇: 搭建嵌入式Linux开发环境
hceng_blog
博客等级 码龄10年 263粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值