探究linux设备驱动模型之——platform虚拟总线(三)最终章
这篇是最终章了,结束这一章后,对于platform平台总线驱动的使用方法应该是能够无压力掌握。但是这一章涉及的内容会比前面两章多一些。
我们会一步一步地来完善上一章的例子。完善的目的是能够在应用层去控制我们写的这个驱动接口。
第一步,我们得先建立设备节点。看过ldd3(linux设备驱动程序 第三版)的人都知道设备节点是建立在/dev目录下的,但其实在/sys目录下也可以建立设备节点。我们接下来写的驱动使用后者的方法。sys文件系统是一个动态的文件系统,所谓动态即表明该文件系统的所有内容都是保存在内存里面而不是硬盘里面,所以该文件系统里面的内容不能永久保存,断电即消失。
在sys目录下面建立一个设备节点很简单,一般来说用到两个函数,一个是class_create,还有一个是device_create。这两个函数的配合使用在很多驱动程序里面都可以看到。下面给出这两个函数的原形:
class_create函数的原形在内核里面有些绕,我稍作了修改便如读者理解,如下所示:
struct class * class_create(struct module *owner,
const char *name)
第一个参数一般填入THIS_MODULE,第二个参数是给这个class起个名字,在sys目录下面有个class目录,假如我这样调用该函数:class_create(THIS_MODULE,"love");那么你将会在/sys/class目录下面看到一个文件名为love的新目录。
device_create的函数原型如下:
struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)
这个函数原型比较复杂,我们一个一个地来说,第一个是前面介绍的class;第二个的用法到时看实际例子;第三个其实就是设备号,我们不打算在/dev目录下面建立设备节点,所以该参数也可以忽略;第四个是要传进去的私有数据,可以给他NULL;最后一个就是给这个device起名字,这个名字最后会成为新目录的文件名。
我们可以如下所示调用这两个函数:
struct class * love_class;
love_class = class_create(THIS_MODULE,"love");
device_create(love_class,NULL,0,NULL,"haoge");
这样名字为"haoge"的文件夹就会出现在/sys/class/love的目录下了。
第二步就是在/sys下面建立属性文件,所谓属性文件就是驱动程序提供给应用程序的控制接口。属性的数据结构如下:
struct attribute {
const char *name;
mode_t mode;
};
第一个参数当然是给这属性文件起一个文件名,第二个参数设置这个属性文件的读取权限。
但我们更多的是用device_attribute数据结构,如下所示:
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
可以看到attribute结构是device_attribute结构中的一个成员,另外两个成员函数就是对该属性文件进行读取的方法函数。
简单介绍完这些东西后,我们可以看一下最终修改的驱动代码,有三个文件:
第一个文件:
/****driver.c****/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <asm/system.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/mm.h>
struct haoge_data
{
char a[4096];
char * name;
struct device *dev;
}; struct class * haoge_class;
struct device * haoge_dev;
static ssize_t haoge_store(struct device *dev,
struct device_attribute *attr, char *buf,size_t size)
{
if(size>4096)
{
printk(KERN_ALERT "fuck you!");
return 0;
} return sprintf( ((struct haoge_data * )dev->platform_data)->a, buf);
}
static ssize_t haoge_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ return sprintf(buf, ((struct haoge_data * )dev->platform_data)->a);
}
struct device_attribute dev_attr_brightness ={ \
.attr = {.name = "love", .mode = 0644 }, \
.show = haoge_show, \
.store = haoge_store,
\
};
static int haoge_probe(struct platform_device *dev)
{
struct haoge_data * p =(dev->dev).platform_data; haoge_dev =device_create(haoge_class, &(dev->dev), 0, NULL,
"%s", p->name);
p->dev=haoge_dev;
haoge_dev->platform_data=p;
device_create_file(haoge_dev, &dev_attr_brightness); printk(KERN_ALERT "%s",p->a); return 0;
} static int haoge_remove(struct platform_device *dev)
{ //和该驱动匹配的设备被卸载时便会调用haoge_remove函数,但是驱动本身卸载并不会调用
//该函数.
//所以要先卸载设备模块再卸载本驱动模块,否则device_unregister将无法被调用。
struct haoge_data * p =(dev->dev).platform_data;
device_remove_file(p->dev, &dev_attr_brightness);
device_unregister(p->dev); return 0;
} static struct platform_driver haoge_driver = {
.probe = haoge_probe,
.remove = haoge_remove,
.driver = {
.name = "haoge",
.owner = THIS_MODULE,
},
}; static int __init haoge_init(void)
{ haoge_class = class_create(THIS_MODULE,"haoge");
return platform_driver_register(&haoge_driver);
} static void __exit haoge_exit(void)
{ class_destroy(haoge_class);
platform_driver_unregister(&haoge_driver);
} module_init(haoge_init);
module_exit(haoge_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HaoGe");
第二个文件:
/****device1.c****/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <asm/system.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/mm.h>
struct haoge_data
{
char a[];
char * name;
};
struct haoge_data s ={
.name = "haoge_one",
}; struct platform_device haoge_device ={
.name= "haoge",
.id = ,
.dev = { .platform_data = &s,
},
}; static int __init haoge_init(void)
{
sprintf(s.a,"haogeverygood!\n"); platform_device_register(&haoge_device); return ;
} static void __exit haoge_exit(void)
{ platform_device_unregister(&haoge_device);
} module_init(haoge_init);
module_exit(haoge_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HaoGe");
第三个文件:
/****device2.c****/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <asm/system.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/mm.h>
struct haoge_data
{
char a[];
char * name;
};
struct haoge_data s ={
.name = "haoge_two",
}; struct platform_device haoge2_device ={
.name= "haoge",
.id = ,
.dev = {
.platform_data = &s,
},
}; static int __init haoge_init(void)
{
sprintf(s.a,"haoge very handsone!\n"); platform_device_register(&haoge2_device); return ;
} static void __exit haoge_exit(void)
{ platform_device_unregister(&haoge2_device);
} module_init(haoge_init);
module_exit(haoge_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HaoGe");
探究linux设备驱动模型之——platform虚拟总线(三)最终章的更多相关文章
- 探究linux设备驱动模型之——platform虚拟总线(一)
说在前面的话 : 设备驱动模型系列的文章主要依据的内核版本是2.6.32的,因为我装的Linux系统差不多就是这个版本的(实际上我用的fedora 14的内核版本是2.6.35.13的.) ...
- 探究linux设备驱动模型之——platform虚拟总线(二)
上回说到,platform_match是驱动和设备之间的媒人婆,那么platform_match是如何匹配驱动和设备的呢?platform总线定义的匹配条件很简单,主要就是查看驱动结构体和设备结构体的 ...
- Linux设备驱动模型之platform(平台)总线详解
/********************************************************/ 内核版本:2.6.35.7 运行平台:三星s5pv210 /*********** ...
- linux设备驱动模型之Kobject、kobj_type、kset【转】
本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74838165 版权声明:本文为博主原创文章,转载请注明http://blog.c ...
- Linux设备驱动模型简述(源码剖析)
1. Linux设备驱动模型和sysfs文件系统 Linux内核在2.6版本中引入设备驱动模型,简化了驱动程序的编写.Linux设备驱动模型包含设备(device).总线(bus).类(class)和 ...
- Linux设备驱动模型底层架构及组织方式
1.什么是设备驱动模型? 设备驱动模型,说实话这个概念真的不好解释,他是一个比较抽象的概念,我在网上也是没有找到关于设备驱动模型的一个定义,那么今天就我所学.所了解 到的,我对设备驱动模型的一个理解: ...
- LINUX设备驱动模型之class
转自 https://blog.csdn.net/qq_20678703/article/details/52754661 1.LINUX设备驱动模型中的bus.device.driver,.其中bu ...
- Linux 设备驱动模型
Linux系统将设备和驱动归一到设备驱动模型中了来管理 设备驱动程序功能: 1,对硬件设备初始化和释放 2,对设备进行管理,包括实参设置,以及提供对设备的统一操作接口 3,读取应用程序传递给设备文件的 ...
- linux设备驱动模型
尽管LDD3中说对多数程序员掌握设备驱动模型不是必要的,但对于嵌入式Linux的底层程序员而言,对设备驱动模型的学习非常重要. Linux设备模型的目的:为内核建立一个统一的设备模型,从而又一个对系统 ...
随机推荐
- Css3 实现丝带效果
代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- 【Mybatis】参数处理
单个参数:mybatis不会做特殊处理, #{参数名/任意名}:取出参数值. 多个参数:mybatis会做特殊处理. 多个参数会被封装成 一个map, key:param1...paramN,或者参数 ...
- PAT——1028. 人口普查
某城镇进行人口普查,得到了全体居民的生日.现请你写个程序,找出镇上最年长和最年轻的人. 这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,而今天是2014年9月 ...
- djb2:一个产生简单的随机分布的哈希函数
目录 LCG算法 示例代码 djb2 示例代码 为什么选择参数33和 33 was chosen because: 5381 was chosen because 哈希选择参考 LCG算法 djb2与 ...
- 字符型设备驱动程序-first-printf以及点亮LED灯(一)
学习使用 Linux 的 字符型设备驱动 来 进行 . 学习地址:http://edu.51cto.com/lesson/id-25710.html 第一步: 首先写 三个函数 ,2017年5月17 ...
- Spring 事务传播行为的使用
...
- TestNG+Maven+IDEA 自动化测试(一) 环境搭建
示例代码: https://github.com/ryan255/TestNG-Demo 所需环境: 1. IDEA UItimate 2. JDK 3. Maven 创建工程 一开始创建一个普通的m ...
- iOS之利用腾讯Bugly程序调试,测试代码bug、卡顿等情况
1.自己先写一个 Demo 演示一下利用bugly测试崩溃的具体情况. 在ViewController里面实现崩溃代码如下: 运行后 毫无疑问程序报错了! 2.使用到第三方的框架Bugly,官方下载 ...
- Java类和对象详解,以及相关知识点
了解类和对象前,简单提及面向对象程序设计.面向对象程序设计就是通过对象来进行程序设计,对象表示一个可以明确标识的实体.例如:一个人.一本书.一个学校或一台电脑等等.每个对象都有自己独特的标识.状态和行 ...
- Docker安装(yum方式 centos7)
yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://m ...