Linux下platform驱动框架编写

一.  简介

前面一篇文章简单学习了 Linux内核中platform驱动代码。文章地址如下:

Linux下platform驱动简介-CSDN博客

本文学习编写 platform驱动框架代码。

二.  Linux下platform驱动框架编写

1.  编写platform驱动代码的思路

(1) 定义结构体以及实现匹配方法以及 probe 函数

在编写 platform 驱动的时候,首先定义一个 platform_driver 结构体变量。
然后,实现结构体中的各个成员变量,重点是实现匹配方法以及 probe 函数。
当驱动和设备匹配成功以后, probe 函数就会执行,具体的驱动程序在 probe 函数里面编写,比如,字符设备驱动等等。

(2) 向Linux内核注册一个platform驱动

当我们定义并初始化好 platform_driver 结构体变量以后,需要在驱动入口函数里面调用
platform_driver_register 函数 Linux 内核注册一个 platform 驱动。
platform_driver_register 函数 原型如下所示:
int platform_driver_register (struct platform_driver *driver)
函数参数和返回值含义如下:
driver :要注册的 platform 驱动。
返回值: 负数,失败; 0 ,成功。

(3)卸载platform驱动

还需要在驱动卸载函数中,通过 platform_driver_unregister 函数卸载 platform 驱动,
platform_driver_unregister 函数原型如下:
void platform_driver_unregister(struct platform_driver *drv)
函数参数和返回值含义如下:
drv :要卸载的 platform 驱动。
返回值: 无。

二.  platform 驱动框架

platform 驱动框架如下所示:
/* 设备结构体 */
struct xxx_dev{
struct cdev cdev;
/* 设备结构体其他具体内容 */
};struct xxx_dev xxxdev; /* 定义个设备结构体变量 */static int xxx_open(struct inode *inode, struct file *filp)
{ /* 函数具体内容 */return 0;
}static ssize_t xxx_write(struct file *filp, const char __user *buf,
size_t cnt, loff_t *offt)
{/* 函数具体内容 */return 0;
}/*
* 字符设备驱动操作集
*/
static struct file_operations xxx_fops = {.owner = THIS_MODULE,.open = xxx_open,.write = xxx_write,
};/*
* platform 驱动的 probe 函数
* 驱动与设备匹配成功以后,此函数就会执行
*/
static int xxx_probe(struct platform_device *dev)
{ ......cdev_init(&xxxdev.cdev, &xxx_fops); /* 注册字符设备驱动 *//* 函数具体内容 */return 0;
}static int xxx_remove(struct platform_device *dev)
{......cdev_del(&xxxdev.cdev);/* 删除 cdev *//* 函数具体内容 */return 0;
}/* 匹配列表 */
static const struct of_device_id xxx_of_match[] = {
{ .compatible = "xxx-gpio" },
{ /* Sentinel */ }
};/* 
* platform 平台驱动结构体
*/
static struct platform_driver xxx_driver = {.driver = {.name = "xxx",.of_match_table = xxx_of_match,},.probe = xxx_probe,.remove = xxx_remove,
};/* 驱动模块加载 */
static int __init xxxdriver_init(void)
{return platform_driver_register(&xxx_driver);
}/* 驱动模块卸载 */
static void __exit xxxdriver_exit(void)
{platform_driver_unregister(&xxx_driver);
}module_init(xxxdriver_init);
module_exit(xxxdriver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("WeiWuXian");

驱动代码说明如下:
1~27 行,传统的字符设备驱动,所谓的 platform 驱动并不是独立于字符设备驱动、块设备驱动和网络设备驱动之外的其他种类的驱动。 
platform 只是为了驱动的分离与分层而提出来的一种框架,其驱动的具体实现还是需要字符设备驱动、块设备驱动或网络设备驱动。  

33~39 行, xxx_probe 函数,当驱动和设备匹配成功以后此函数就会执行,以前在驱动入口 init 函数里面编写的字符设备驱动程序,就全部放到此 probe 函数里面。比如,注册字符设备 驱动、添加 cdev 、创建类等等。

41~47 行, xxx_remove 函数, platform_driver 结构体中的 remove 成员变量,当关闭 platform
备驱动时,此函数就会执行,以前在驱动卸载 exit 函数里面要做的事情就放到此函数中来。 比如,使用 iounmap 释放内存、删除 cdev ,注销设备号等等。

50~53 行, xxx_of_match 匹配表,如果使用设备树的话,将通过此匹配表进行驱动和设备 的匹配。
51 行设置了一个匹配项,此匹配项的 compatible 值为“ xxx-gpio ”,因此当设备树中 设备节点的 compatible 属性值为“ xxx-gpio ”的时候此设备就会与此驱动匹配。
52 行是一个标记,of_device_id 表最后一个匹配项必须是空的。

58~65 行,定义一个 platform_driver 结构体变量 xxx_driver ,表示 platform 驱动。
59~62 行设置 paltform_driver 中的 device_driver 成员变量的 name of_match_table 这两个属性。
其中 name 属性用于传统的驱动与设备匹配,也就是检查驱动和设备的 name 字段是不是相同。
of_match_table 属性就是用于设备树下的驱动与设备检查。
对于一个完整的驱动程序,必须提供 有设备树和无设备树两种匹配方法。
最后 63 64 这两行设置 probe remove 这两成员变量。

68~71 行,驱动入口函数,调用 platform_driver_register 函数向 Linux 内核注册一个 platform 驱动,也就是上面定义的 xxx_driver 结构体变量。

74~77 行,驱动出口函数,调用 platform_driver_unregister 函数卸载前面注册的 platform 驱动。

三.  总结

总体来说, platform 驱动还是传统的字符设备驱动、块设备驱动或网络设备驱动,只是套上了一张“ platform ”的皮,目的是为了使用总线、驱动和设备这个驱动模型来实现驱动的分 离与分层。

 

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

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

相关文章

第12章 指针

以下内容是学习尚硅谷 12.1 指针基本介绍 1)指针是C语言的精华,也是C语言的难点 2)指针,也就是内存的地址;所谓指针变量,也就是保存了内存地址的变量。关于指针的基本使用,在讲变量的时候做了…

WAPI模块AT指令驱动

一、前言 由于项目更迭,需要将原4G模块更换为国内的WAPI协议模块,主控芯片NRF52840无需改动其他部分,只需要将串口部分的数据格式稍作更改即可。 编程风格和之前的esp8266一致,同样都是AT指令来配置模块,由于主…

Java封装的优点

目录 提高代码可维护性 降低耦合度 保护数据安全性 封装如何提高安全性 数据隐藏 访问控制 限制接口 错误隔离

请解释Redis是什么?它有哪些主要应用场景?Redis支持哪些数据类型?并描述每种数据类型的特性和使用场景。

请解释Redis是什么?它有哪些主要应用场景? Redis是一款内存高速缓存NoSQL数据库,使用C语言编写,它支持丰富的数据类型,如String、list、set、zset、hash等,并且这些数据类型都直接支持数据的原子性操作&…

d2-crud-plus 使用小技巧(四)—— 搜索限制只能输入数字

需求 搜索时有些字段需要限制,比如只能输入数字,不能存在其他字符包括空格。 效果 事情焦点后先触发校验,在触发查询。 代码 crud.js export const crudOptions (vm) > {return {columns: [{title: 号码,key: number,search: { //…

比Let‘s Encrypt更简单更齐全的免费证书申请教程

步骤一 打开JoySSL官网,注册属于你的专属账号; 永久免费SSL证书申请地址真正完全且永久免费!不用您花一分钱,SSL证书免费使用90天,并且还支持连续签发。JoySSL携手全球权威可信顶级根,自研新一代SSL证书&…

打zip包,支持有空文件夹

支持有空文件夹 // 打包String url dir0 File.separator dir1;log.info("将此文件夹打成zip包:"url);String urlZip dir0 File.separator dir1 ".zip";File file new File(url);// 方法2:压缩包内支持空文件夹ZipUtil.zip(F…

【汇编】#3 8086与数据有关的寻址方式

文章目录 操作码与操作数1. 8086处理器的与数据有关的寻址方式1.1 立即数寻址方式1.2 寄存器寻址方式 2. 有效(偏移)地址(effective address,EA)与缺省段寄存器选择tips:段跨越前缀2.1 直接寻址tips:直接寻址与立即寻址…

GitOps实践之Argo CD (2)

argocd 【-1】argocd可以解决什么问题? helm 部署是手动的?依赖流水线。而有时候仅仅更新一个小东西,流水线跑好久,CD真的不应该和CI耦合。不同环境的helm配置不同,手动修改问题多,可以用git管理起来,例如分不同环境用目录区分。argocd创建应用可以不通环境部署到不同集…

Seata 2.x 系列【12】高可用集群部署

有道无术,术尚可求,有术无道,止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址:https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 搭建演…

Linux下新增有root权限的用户

步骤: 1.以 root 用户身份登录到 CentOS 服务器。 2.使用以下命令创建新用户(将 newuser 替换为您想要创建的用户名): sudo adduser username 3.为新用户设置密码: sudo passwd username 按照提示输入新增用户密码 …

计算机基础1-汇编基础

汇编语言是一种低级的计算机语言,它直接与计算机硬件进行交互。在汇编语言中,指令由一系列助记符(mnemonic)组成,用于执行特定的操作,如数据传输、算术运算和控制流程等。每个指令都对应着一条机器码&#…

《数据安全法》关于数据出境的条款

《数据安全法》关于数据出境的条款 《中华人民共和国数据安全法》于2021年6月10日通过,2021年9月1日起实施)。 在《数据安全法》中,第三十一条:“关键信息基础设施的运营者在中华人民共和国境内运营中收集和产生的重要数据的出境…

Golang如何使用命令行-- flag库

参考文献: flag package - flag - Go Packages 使用: import "flag" var nFlag flag.Int("n", 1234, "help message for flag n") 上述方法返回的是一个指针变量nFlag,如果我们要打印,应该使用…

声卡喊话IP喇叭,IP网络吸顶天花喇叭

声卡喊话IP喇叭,IP网络吸顶天花喇叭 SV-7043VP是一款ip/sip网络吸顶喇叭,具有10/100M以太网接口,从网络接口接收网络的音频数据后播放。本网络吸顶喇叭可以与其他广播主机、服务器软件和采播主机配合使用,实现音频的播放&#xf…

大语言模型:Query Rewriting for Retrieval-Augmented Large Language Models

总体思路 作者首先指出大语言模型虽然取得了很好的效果,但是仍然存在幻觉和时间顺序混乱的问题,因此需要额外知识库和LLM内部知识库相结合,来修正;因此优化传统的retriever-reader的方案成为需要;目前的研究方案当中使…

log4cplus在Qt linux中的应用与问题解决

log4cplus在Qt linux中的应用与问题解决 背景log4cplus下载遇到问题:libm.so.6:undefined reference to __strtof128_nanGLIBC_PRIVATE‘解决方案编译生成在Qt工程里面添加对应依赖编译运行成功 背景 最近工作中需要用到log4cplus的日志做一些记录,用了…

html5cssjs代码 010 个人简历模板一

html5&css&js代码 010 个人简历模板一 一、代码二、解释 这段HTML代码定义了一个个人简历的页面布局和样式。页面分为多个部分,包括基本信息、自我评价、工作经历、教育经历、软件产品及著作、未来研究方向等。每个部分都使用section标签包裹,并…

Linux——ELK日志分析系统

实验环境 虚拟机三台CentOS 7.9, 组件包 elasticsearch-5.5.0.rpm elasticsearch-head.tar.gz node-v8.2.1.tar.gz phantomjs-2.1.1-linux-x86_64.tar.bz2 logstash-5.5.1.rpm kibana-5.5.1-x86_64.rpm 初始…

Lombok原理及实例(Java) - 简化JavaBean开发

Lombok 1.作用:简化javabean开发 2.使用:a.下插件 -> 如果是idea2022不用下载了,自带b.导lombok的jar包c.修改设置 1.lombok介绍 Lombok通过增加一些“处理程序”,可以让javabean变得简洁、快速。 Lombok能以注解形式来简化java代码,提高开发效…