linux设备驱动模型:xbus、platform

news2024/9/26 1:21:00

xbus:打造自属的驱动总线

软件和硬件的代码分离,提高程序的复用性。

device:关联硬件代码

driver_devices:关联软件代码

bus_type:统一管理、设置match匹配规则(struct device和struct device_driver)

在struct bus_type里面设置1个链表头,将要管理的一系列struct device通过一个链表串联起来。

在struct bus_type里面设置另1个链表头,将要管理的一系列struct device_driver通过一个链表串联起来。

buses_init()函数

内核启动默认执行,创建名字为“bus”和“system”的kset对象。即/sys/下生成“bus”、“system”目录。

int __init buses_init(void)
{
	bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
	if (!bus_kset)
		return -ENOMEM;

	system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
	if (!system_kset)
		return -ENOMEM;

	return 0;
}

bus_register()函数

总线注册。添加新的总线类型。

int bus_register(struct bus_type *bus)

函数做了哪些事情:

在/sys/bus下建立xbus目录项(xbus是自定义的名字,设置bus->name = “xbus”即可),并创建属性文件。

在/sys/bus/xbus下建立devices目录项,并创建属性文件。

在/sys/bus/xbus下建立drivers目录项,并创建属性文件。

(如上需要创建3个目录,因此bus_type结构体需要3个kobject)

初始化priv->klist_devices链表头

初始化priv->klist_drivers链表头

device_register()函数

设备注册。添加设备,关联硬件相关代码。

int device_register(struct device *dev)

在/sys/bus/xbus/devices下建立yyy目录项(那么struct device里面肯定要包含一个kobject)。

加入bus->priv->devices_kset链表。

加入bus->priv->klist_devices链表。

遍历bus->priv->klist_drivers,执行bus->match来寻找合适的drv。

dev关联driv,执行drv->probe()。

driver_register()函数

驱动注册。添加驱动,关联软件相关代码。

int driver_register(struct device_driver *drv)

在/sys/bus/xbus/drivers下建立zzz目录项(那么struct device_driver里面肯定要包含一个kobject)。

加入bus->priv->drivers_kset链表。

加入bus->priv->klist_drivers链表。

遍历bus->priv->klist_klist_devices链表,执行bus->match来寻找合适的dev。

dev关联driv,执行drv->probe()。

设备驱动模型框图

bus、dev、drv关系图

实验环节:xbus

xbus.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>

int xbus_match(struct device *dev, struct device_driver *drv)
{
        /* __FILE__和__func__ 这两个宏是在编译器里面定义的 */
        printk(KERN_ALERT "%s-%s\n", __FILE__, __func__);
        if(!strncmp(dev_name(dev), drv->name, strlen(drv->name))){
                printk(KERN_ALERT "dev & drv match\n");
                return 1;
        }
        return 0;
}

static struct bus_type xbus = {
        .name = "xbus",
        .match = xbus_match,
};
EXPORT_SYMBOL(xbus);

static int __init xbus_init(void)
{
        int ret;
        printk(KERN_ALERT "xbus init\n");
        ret = bus_register(&xbus);
        if(ret != 0)    return -1;
        return 0;
}

static void __exit xbus_exit(void){
        printk(KERN_ALERT "xbus exit\n");
        bus_unregister(&xbus);
}

module_init(xbus_init);
module_exit(xbus_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("couvrir");
MODULE_DESCRIPTION("led module");
MODULE_ALIAS("led module");

xdev.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>

extern struct bus_type xbus;

void xdev_release(struct device *dev)
{
        printk(KERN_ALERT "%s-%s\n", __FILE__, __func__);
}

static struct device xdev = {
        .init_name = "xdev",
        /* 指明dev属于哪一条总线 */
        .bus = &xbus,
        .release = xdev_release,
};

static int __init xdev_init(void)
{
        int ret;
        printk(KERN_ALERT "xdev init\n");
        ret = device_register(&xdev);
        if(ret != 0)    return -1;
        return 0;
}

static void __exit xdev_exit(void){
        printk(KERN_ALERT "xdev exit\n");
        device_unregister(&xdev);
}

module_init(xdev_init);
module_exit(xdev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("couvrir");
MODULE_DESCRIPTION("led module");
MODULE_ALIAS("led module");

xdrv.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>

extern struct bus_type xbus;

int xdrv_probe(struct device *dev)
{
        /* device和driver关联起来后会调用该函数 */
        printk(KERN_ALERT "%s-%s\n", __FILE__, __func__);
        return 0;
}

int xdrv_remove(struct device *dev)
{
        printk(KERN_ALERT "%s-%s\n", __FILE__, __func__);
        return 0;
}

static struct device_driver xdrv = {
        .name = "xdrv",
        /* 指明dev属于哪一条总线 */
        .bus = &xbus,
        .probe = xdrv_probe,
        .remove = xdrv_remove,
};

static int __init xdrv_init(void)
{
        int ret;
        printk(KERN_ALERT "xdrv init\n");
        ret = driver_register(&xdrv);
        if(ret != 0)    return -1;
        return 0;
}

static void __exit xdrv_exit(void){
        printk(KERN_ALERT "xdrv exit\n");
        driver_unregister(&xdrv);
}

module_init(xdrv_init);
module_exit(xdrv_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("couvrir");
MODULE_DESCRIPTION("led module");
MODULE_ALIAS("led module");

Makefile文件

KERNEL_DIR=/home/couvrir/桌面/ebf_linux_kernel_6ull_depth1/build_image/build
  
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH CROSS_COMPILE

obj-m:=xbus.o xdev.o xdrv.o
all:
        $(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules

.PHONY:clean copy
clean:
        $(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
        sudo rm /home/couvrir/桌面/sharedir/*.ko
copy:
        sudo cp *.ko /home/couvrir/桌面/sharedir

执行过程

虚拟机:执行makemake copy。生成.ko文件。

开发板(在挂载目录下执行):

sudo insmod xbus.ko

观察/sys/bus/下是否有xbus目录,xbus目录下会自动生成device和driver目录项。

sudo insmod xdev.ko

观察/sys/bus/xbus/device/下是否有xdev目录。

sudo insmod xdrv.ko

观察/sys/bus/xbus/driver/下是否有xdrv目录。

sudo rmmod xdrv

sudo rmmod xdev

sudo rmmod xbus

platform:虚拟的驱动总线

platform_device:继承device,关联硬件代码

platform_driver:继承device_driver,重设probe函数指针

platform(bus_type):统一管理、设置match匹配规则(struct platform_device和struct platform_driver)

 

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

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

相关文章

Python程序设计基础:random库的使用

文章目录 一、常见的random库函数二、应用实例 一、常见的random库函数 在使用Python语言进行编程计算时&#xff0c;计算机完成的计算主要是确定的&#xff0c;但是在将其进行应用时&#xff0c;人们会模拟现实生活中的现象和活动&#xff0c;希望其增加一些随机性&#xff0…

Leetcode-每日一题【剑指 Offer 34. 二叉树中和为某一值的路径】

题目 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum 22输…

成都爱尔谭娇主任提醒孩子不停揉眼睛是因为什么

孩子总是揉眼睛&#xff0c; 明显眼睛不舒服&#xff0c; 但看着好像没什么? 可孩子不停眨眼流泪&#xff0c; 肯定不对…… 孩子到底怎么了? 孩子可能长了“倒睫”! 孩子出现倒睫毛就是睫毛不朝外长而向内长&#xff0c;是婴幼儿很容易患的一种眼病。 由于孩子的脸颊及鼻梁发…

为什么选择模块化机柜?

模块化机柜是一种使用模块化设计的机柜&#xff0c;它的特点就是可以灵活组合和扩展&#xff0c;方便用户根据实际需求进行定制。 模块化机柜具有以下特点&#xff1a; 可定制性&#xff1a;模块化机柜可以根据用户的具体需求和空间限制&#xff0c;进行自由组合和定制。用户…

无人直播应该这样操作!

随着无人直播带货的迅猛发展&#xff0c;越来越多的商家和个人开始关注如何运营一成功的无人直播带货活动。本文将为您提供一份操作指南&#xff0c;并在此基础上探讨无人直播带货的思考深度和逻辑性。 一、了解无人直播带货的基本概念 无人直播带货是指通过直播平台和…

级联/嵌套查询

在真实业务背景中的系统中&#xff0c;对于用户的认证、授权以及鉴权的问题&#xff0c;通常不只依靠一张用户表来完成。一般还涉及用户角色表&#xff0c;用户-角色关系表&#xff0c;权限表&#xff0c;以及角色-权限关系表。此时查询数据库&#xff0c;除了使用关联查询还有…

基于MATLAB开发AUTOSAR软件应用层Code mapping专题-part 2 Inport和Outports 标签页介绍

上篇我们介绍了Function页的内容,这篇我们介绍Inports和Outports页的内容,这里我们再次强调一个概念,code mapping是以simulink的角度去看的,就是先要在模型中建立simulink模块,在code mapping里映射他要对应的autosar的元素,之后生成代码时的c语言的名字是以Autosar的元…

面试3个月72次全挂,程序员晒凄惨经历,网友:是个狠人

说起面试&#xff0c;对于大多数求职者来说&#xff0c;找到一份真正合适工作的过程&#xff0c;无疑就是一场不断患得患失的煎熬之旅。 为什么这么说呢&#xff1f;因为找工作的漫长过程&#xff0c;不仅需要很大的体力消耗&#xff0c;给心理带来的巨大负担也是让很多人感到…

SRv6 BE实验

以上内容均属原创&#xff0c;如有不详或错误&#xff0c;敬请指出。本文作者&#xff1a; 坏坏 本文链接&#xff1a; http://t.csdn.cn/Q6VaU 版权声明&#xff1a; 本博客所有文章除特别声明外&#xff0c;如需转载&#xff0c;请联系作者注明出处并附带本文链接&#xf…

蓝海创意云×悦乐兔99艺术节直播首秀顺利开播

8月18日&#xff0c;苏州悦乐兔99艺术节直播首秀顺利开播&#xff0c;蓝海创意云为此次直播提供了全程技术支持&#xff0c;使用自主研发的vLive虚拟直播系统嵌入整个直播流程&#xff0c;带给观众一场不一样的全新视觉体验。 蓝海创意云x悦乐兔直播首秀顺利开播 蓝海创意云助力…

计算机竞赛 地铁大数据客流分析系统 设计与实现

文章目录 1 前言1.1 实现目的 2 数据集2.2 数据集概况2.3 数据字段 3 实现效果3.1 地铁数据整体概况3.2 平均指标3.3 地铁2018年9月开通运营的线路3.4 客流量相关统计3.4.1 线路客流量排行3.4.2 站点客流量排行3.4.3 入站客流排行3.4.4 整体客流随时间变化趋势3.4.5 不同线路客…

根据源码,模拟实现 RabbitMQ - 转发规则实现(6)

目录 一、转发规则实现 1.1、需求分析 1.2、实现 Router 转发规则 1.2.1、bindingKey 和 routingKey 参数校验 1.2.2、消息匹配规则 1.2.3、主题交换机匹配规则 一、转发规则实现 1.1、需求分析 这里主要实现 routingKey 和 bindingKey 参数的校验&#xff0c;以及 Topic…

邀请函 | 高质量区块链·元宇宙—标准行系列沙龙(北京站)即将开启

区块链、元宇宙是近年来备受关注的新兴技术&#xff0c;也是推动数字经济发展的重要力量。高质量标准引领高质量发展&#xff0c;加快形成标准引领&#xff0c;充分释放区块链、元宇宙对实体经济牵引赋能效应&#xff0c;推进形成相关产业体系高质量发展新格局刻不容缓。 为进…

AIGC|万字长文!带你了解AI大模型技术演进

一、AI的起源 在下面这张图中&#xff0c;我们可以看到两个人物&#xff1a;图中左边的人物是一位演员&#xff0c;他出演了一部名为《模仿游戏》的电影。而这部电影实际上讲述的是图中右边的人物&#xff0c;他就是是人工智能之父图灵&#xff08;Alan Turing&#xff09;。 …

Python可视化在量化交易中的应用(17)_Seaborn核密度曲线图

Seaborn中核密度图的绘制方法 seaborn中绘制核密度图使用的是sns.kdeplot()函数&#xff1a; sns.kdeplot(x,y,shade,vertical,kernel,bw,gridsize200,cut3,clip,legend,cumulative,shade_lowest,cbar,cbar_ax,cbar_kws,ax,weights,hue,palette,hue_order,hue_norm,multiple‘…

做好产品设计应遵循的5大原则

产品设计原则是产品设计需遵循的基础规则&#xff0c;如果没有遵循设计原则&#xff0c;直接进行产品设计&#xff0c;往往会造成产品设计不稳定、冗杂&#xff0c;不能真正满足用户需求&#xff0c;这为项目带来较大风险&#xff0c;影响项目顺利交付。 一般来说&#xff0c;做…

【实用工具】ScreenToGif 制作GIF

1、介绍 官方地址 ScreenToGif是一款优秀的录屏软件&#xff0c;可将屏幕上的软件操作、会议视频、视频聊天等录制为GIF或MP4格式的文件。 ScreenToGif的启动界面包含屏幕录像机、电脑摄像头录制、画板录制和编辑器4个功能。启动录像机功能后&#xff0c;会有一个录制窗口&am…

【Axure高保真原型】通过输入框动态控制折线图

今天和大家分享通过输入框动态控制折线图的原型模板&#xff0c;在输入框里维护项目数据&#xff0c;可以自动生成对应的折线图&#xff0c;鼠标移入对应折点&#xff0c;可以查看对应数据。使用也非常方便&#xff0c;只需要修改输入框里的数据&#xff0c;或者复制粘贴文本&a…

Docker容器与虚拟化技术:Docker-Compose

目录 一、理论 1.Docker-Compose 二、实验 1. Docker Compose 安装部署 2.Docker Compose撰写nginx 镜像 3.Docker Compose撰写tomcat 镜像 三、问题 1.Docker Compose 和 Dockerfile 的区别 四、总结 一、理论 1.Docker-Compose &#xff08;1&#xff09;使用场景…

【Linux】进程间通信之信号机制2

文章目录 信号阻塞代码验证验证信号的阻塞验证信号的阻塞不影响信号注册验证可靠信号不会丢信号&#xff0c;不可靠信号会丢信号验证9号和19号信号不能被阻塞 用信号解决僵尸进程volatile关键字 信号阻塞代码验证 在上篇详解信号机制的博文中&#xff0c;我们提到了设置阻塞位…