Linux驱动----总线

总线相关

  • 总线
    • 注册和注销总线
    • device对象----描述设备信息,包括地址,中断号和其他的一些自定义数据
      • 注册和注销device对象----指将device注册到mybus总线
    • driver对象----描述设备驱动的方法(操作地址和中断)
      • 注册和注销driver对象----指将driver注册到mybus总线
      • 总线匹配成功之后,如何自动调用driver的probe方法
  • 平台总线
    • 平台总线作用
    • 平台总线中的三元素

总线

在这里插入图片描述

总线的作用是将设备与驱动关联起来,或者称为管理起来,完成匹配
总线是在sys/bus目录下的,linux文件系统已经预设了一些总线,例如IIC总线,SPI总线,USB总线等,我们也可以自己创建自己的总线,以下是创建自己的总线需要注意的地方:

struct bus_type  : 总线对象,描述一个总线,管理device和driver
struct bus_type {const char *name;int (*match)(struct device *dev, struct device_driver *drv);
}

注册和注销总线

int bus_register(struct bus_type *bus);
void bus_unregister(struct bus_type *bus);

注册总线和注销总线需要分别写在模块初始化和模块退出的部分,这里不再赘述。

需要将device和driver分别放入我们的总线中进行匹配,因此需要先创建device和driver对象

device对象----描述设备信息,包括地址,中断号和其他的一些自定义数据

设备对象,用于描述设备信息,包括地址,中断号和其他的一些自定义数据。

struct device{struct kobject kobj,  //所有对象的父类const char *init_name,  //在总线中的名字,用于做匹配,在sys/bus/mybus/device/名字struct bus_type *bus,  //依附于总线的对象,也就是在哪个bus中void *platform_data, //自定义的数据,可以指向任何数据类型.....
}

注册和注销device对象----指将device注册到mybus总线

int device_register(struct device *dev);
void device_unregister(struct device *dev); 

driver对象----描述设备驱动的方法(操作地址和中断)

struct device_driver{const char *name,  //driver的名字, 用于匹配 sys/bus/mybus/driver/名字struct bus_type, //指向该对象依附于哪个总线的int (*probe)(struct device* dev); //如果device和driver匹配后,driver要做的事情int (*remove)(struct device* dev); //如果device和driver从总线移除之后,driver要做的事情
}

注册和注销driver对象----指将driver注册到mybus总线

int driver_register(struct device_driver *drv);
void driver_unregister(struct device_driver *drv); 

总线匹配成功之后,如何自动调用driver的probe方法

1、实现bus对象中的match方法

int match_mybus(struct device *dev, struct device_driver* drv){//如果匹配成功,match方法返回一个1,否则返回0if(! strncmp(drv->name,  dev->kobj.name, strlen(drv->name))){printk("match ok\n");return 1;}else {printk("match failed\n");return 0;}return 0;
}

2、保证driver和device中的名字一致,总线中调用match去匹配,匹配成功才能自动执行drv中的probe方法执行匹配成功后的操作

struct device_driver my_driver = {.name = "fs_dev_drv", .bus = &mybus,.probe = my_drvprobe,
};struct my_devinfo deviceinfo = {.name = "testdev",.irqno = 0000,.addr = 0x8888,
};
struct device my_device = {.init_name = "fs_dev_drv",.bus = &mybus,.platform_data = &deviceinfo,  //通过platform指向一个描述硬件设备的结构体
};
int probe(struct device* dev);  //可以实现例如通过probe函数获取dev中某个设备的中断号,地址等struct my_devinfo *pdesc;
int my_drvprobe(struct device* dev){pdesc = (struct my_devinfo* )dev->platform_data;printk("name = %s\n", pdesc->name);printk("irqno = %d\n", pdesc->irqno);unsigned long *paddr = ioremap(pdesc->addr, 8);return 0;
}

平台总线

平台总线作用

用于平台升级:当soc升级的时候,相似的驱动代码需要编写很多次,其中会有大量重复,因此需要平台总线

device(中断/地址)和driver(操作逻辑)分离,这样就可以在平台升/级的时候修改device中的信息(中断/地址)即可,实现一个driver驱动多个相似的模块,并且修改的代码量很少。

平台总线中的三元素

1、bus:platform_bus不需要自己创建,开机的时候自动创建

struct bus_type platform_bus_type = {.name = "platform",.dev_group = platform_dev_groups,.match = platform_match,.uevent = platform_uevent,.pm = &platform_dev_pm_ops,
};

匹配方法:
优先匹配driver中的id_table, 里面包含了支持不同平台的名字,
直接匹配driver中的名字和device中的名字

int platform_match(struct device* dev, struct device_driver* drv);
int platform_match(pdev, pdrv){if(pdrv->id_table)return platform_match_id(pdrv->id_table, pdev)  != NULL; //先匹配driver中的id_tablereturn (strcmp(pdev->name, drv->name) == 0);匹配driver中的名字和device中的名字
}

2、device对象

struct platform_device{const char *name, //用于做匹配int id, //一般直接给-1struct device dev, //继承了device父类u32	num_resources, //资源的个数struct resource *resource, // 资源:包括了一个设备的地址和中断
}

3、driver对象

struct platform_driver {int (*probe)(struct platform_device *),  //匹配成功后调用的函数int (*remove)(struct platform_device *),  //device移除后调用的函数const struct platform_device_id *id_table,  //如果driver支持多个平台,在列表中写出来struct device_driver driver,  //继承了drvier父类
};

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

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

相关文章

MySQL第3讲--数据类型和表的修改和删除

文章目录 前言数据类型数值类型整数类型浮点数和定点数 字符串类型字符类型:文本类型:二进制数据类型 日期和时间类型实例分析 表的操作添加字段修改字段删除字段修改表名删除表 DDL总结DDL数据库操作DDL表操作 前言 上一节在MySQL第2讲–关系型数据库以…

WebSocket 协议介绍

前言 一.通用协议设计 参考链接 /* --------------------------------------------------------------- | 魔数 2byte | 协议版本号 1byte | 序列化算法 1byte | 报文类型 1byte | --------------------------------------------------------------- | 状态 1byte | …

从0开始搭建vue + flask 旅游景点数据分析系统( 六):搭建后端flask框架

这一期开始开发header部分,预期实现两个目标: 创建 Flask 项目导入旅游数据后端实现旅游数据的查询 1 python 环境 & 开发环境 python 安装和pycharm安装需要去网上找包,建议python使用3.8 或者3.9版本 2 新建项目 我们新建一个文件…

还没排上 SearchGPT ?比 Perplexity 更好用的国产开源平替了解一下?

有 AI 在的科技圈,似乎没有中场休息。除了大模型发布不断,各家科技大厂也在寻找着第一个「杀手级」AI 应用的落脚之地。 OpenAI 首先瞄准的是谷歌 1750 亿美元的搜索业务市场。7 月 25 日,OpenAI 带着 AI 搜索引擎——SearchGPT 高调入场。在演示 demo 中,搜索引擎的使用体…

贪吃蛇(使用QT)

贪吃蛇小游戏 一.项目介绍**[贪吃蛇项目地址](https://gitee.com/strandingzy/QT/tree/zyy/snake)**界面一:游戏大厅界面二:关卡选择界面界面三:游戏界面 二.项目实现2.1 游戏大厅2.2关卡选择界面2.3 游戏房间2.3.1 封装贪吃蛇数据结构2.3.2 …

【CTFWP】ctfshow-web40

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 题目介绍:题目分析:payload:payload解释:payload2:payload2解释:flag 题目介绍: …

第一阶段面试问题(后半部分)

1. c语言中const *p的用法 (1)const int *p; 或 int const *p; 指向常量整数的指针,通过这个指针不能修改它所指向的整数值,但可以修改指针本身来指向其他地址 const int a 10; const int *p &a; // *p 20; // 错误&…

vector中 resize()和reserve()

1.resize()改变容器大小 resize除了预留内存以外,还会调用容器元素的构造函数,不仅分配了N个对象的内存,还会构造N个对象。从这个层面上来说,resize()在时间效率上是比reserve()低的。 2.reserve()容器大小管理 用于预留内存。 …

Flask目录结构路由重定向简单实例讲解——轻量级的 Python Web 框架

假设一个flask目录结构如下: my_flask_app/ │ ├── app.py ├── routes/ │ ├── __init__.py │ ├── ZhejiangProvince/ │ │ ├── __init__.py │ │ ├── la.py │ │ └── el.py │ ├── GuangdongProvince/ │ │ ├…

C语言项目实战FTP文件传输(windows网络编程基础)

文章目录 前言一、客户端和服务端介绍二、客户端和服务器之间进行通信的过程客户端和服务器建立通信的流程通信过程的示例图流程说明 三、客户端代码编写代码解释 四、服务端代码编写代码解释 总结 前言 本篇文章开始将带大家来学习FTP文件传输助手的项目实现,这个…

【单片机毕业设计选题24099】-室内空气质量检测及净化系统

系统功能: 系统上电后OLED显示“欢迎使用请稍后”两秒后进入正常界面显示, 第一行显示温湿度和MQ2值 第二行显示采集到的甲醛值 第三行显示采集到的PM2.5值 第四行显示设定的PM2.5值 短按B4按键增加PM2.5设定阈值 短按B5按键减小PM2.5设定阈值 如果PM2.5采集…

达梦数据库dsc集群动态添加节点

前提条件:在安装好的的dsc集群:达梦数据库dsc集群保姆级部署文档_达梦数据库文档-CSDN博客上动态添加节点 1、环境信息 扩展节点信息: 操作环境:VMware Workstation 16 Pro dmdsc集群 机器ip 主机名 操作系统 资源配置 实…

【传知代码】基于标签相关性的多标签学习(论文复现)

在当今信息爆炸的时代,数据中包含的标签信息对于理解和分析复杂问题至关重要。在诸如文本分类、图像识别和推荐系统等应用中,如何有效地利用标签相关性提升多标签学习的效果成为了研究的热点之一。基于标签相关性的多标签学习方法,通过挖掘不…

JAVA项目基于SpringBoot的外卖点餐管理系统

目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着生活节…

Flink笔记整理(六)

Flink笔记整理(六) 完整系列在公众号:是十三不是四十三,欢迎关注~ 文章目录 Flink笔记整理(六)八、状态管理8.1 Flink中的状态概述状态的分类 8.2 按键分区状态(Keyed State)值状态…

Windows 添加自定义服务实现开机(用户登录之前)自动运行 Python 脚本

实现效果 使用 Python 编写的一个脚本, 希望在 Windows 系统启动时, 用户登录之前就自动运行. 准备工作 首先确保 Python 脚本可以手动正常运行, 演示起见, 编写下面的一个简单的脚本用于在 C 盘根目录中生成一个包含脚本运行时间戳的文本文件. Python 脚本存放在 C:\Python…

python爬虫实践

两个python程序的小实验(附带源码) 题目1 爬取http://www.gaosan.com/gaokao/196075.html 中国大学排名,并输出。提示:使用requests库获取页面的基本操作获取该页面,运用BeautifulSoup解析该页面绑定对象soup&#x…

搭建jenkins一键部署java项目

一、搭建jenkins 链接: https://pan.baidu.com/s/1jzx15PiyI8EhLd_vg7q8bw 提取码: ydhl 复制这段内容后打开百度网盘手机App,操作更方便哦 直接使用docker导入镜像,运行就好 docker run -di --name jenkins -p 8080:8080 -v /home/jenkins_home:/var/je…

【人工智能】NLP入门指南:自然语言处理基础全解析

文章目录 前言一、NLPNLP(自然语言处理)NLU(自然语言理解)NLG(自然语言生成) 二、分词1.什么是分词2.常见的分词工具3.jieba分词 三、词向量1.什么是词向量2.文本张量表示方法3.常见的词向量模型3.1 ont-ho…

15.4 zookeeper java client之Curator使用(❤❤❤❤❤)

Curator使用 1. 为什么使用Curator对比Zookeeper原生2. 集成Curator2.1 依赖引入curator-frameworkcurator-recipes2.2 `yml`配置连接信息2.3 CuratorConfig配置类2.4 Curator实现Zookeeper分布式锁业务2.4.1 业务:可重入锁和不可重入锁可重入锁和不可重入锁InterProcessMutex …