private_data改进

为设备驱动支持多个设备个体做准备,针对private_data进行改进

在设备打开操作中通过inode中保存的i_cdev获取代表当前设备的cdev对象

通过代表当前设备的cdev对象得到包含该对象的设备私有数据结构体

将设备私有数据结构体指针保存到struct file的private_data成员中

在其它设备操作中直接使用保存在struct file的private_date成员中的当前设备私有数据结构体

/**

*Copyright (c) 2013.TianYuan

*All rights reserved.

*

*文件名称: char_device_driver06.c

*文件标识: 支持多设备:创建10个设备节点文件,通过cdd_cdev结构中的led变量区分是哪个节点

*#测试: cat /dev/cdd0

*当前版本:1.0

*作者:wuyq

*

*取代版本:xxx

*原作者:xxx

*完成日期:2013-11-28

*/

#include

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

#define CDD_MAJOR200//cat /proc/devices找一个尚未使用的

#define CDD_MINOR0

#define CDD_COUNT10

dev_t dev = 0;

u32 cdd_major = 0;

u32 cdd_minor = 0;

struct class *dev_class = NULL;

struct cdd_cdev{

struct cdev cdev;

struct device *dev_device;

u8 led;

};

struct cdd_cdev *cdd_cdevp = NULL;

int cdd_open(struct inode* inode, struct file *filp)

{

struct cdd_cdev *pcdevp = NULL;

printk("enter cdd_open!\n");

pcdevp = container_of(inode->i_cdev, struct cdd_cdev, cdev);

printk("led = %d\n", pcdevp->led);

filp->private_data = pcdevp;

return 0;

}

int cdd_read(struct file *filp, char __user *buf, size_t count, loff_t *offset)

{

struct cdd_cdev *cdevp = filp->private_data;

printk("enter cdd_read!\n");

printk("led = %d\n", cdevp->led);

return 0;

}

int cdd_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset)

{

struct cdd_cdev *cdevp = filp->private_data;

printk("enter cdd_write!\n");

printk("led = %d\n", cdevp->led);

return 0;

}

int cdd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)

{

printk("enter cdd_ioctl!\n");

return 0;

}

int cdd_release(struct inode *inode, struct file *filp)

{

printk("enter cdd_release!\n");

return 0;

}

struct file_operations cdd_fops = {

.owner = THIS_MODULE,

.open = cdd_open,

.read = cdd_read,

.write = cdd_write,

.ioctl = cdd_ioctl,

.release = cdd_release,

};

int __init cdd_init(void)

{

int ret = 0;

int i = 0;

if(cdd_major){

dev = MKDEV(CDD_MAJOR, CDD_MINOR);//生成设备号

//注册设备号;1、要注册的起始设备号2、连续注册的设备号个数3、名字

ret = register_chrdev_region(dev, CDD_COUNT, "cdd_demo");

}else{

// 动态分配设备号

ret = alloc_chrdev_region(&dev, cdd_minor, CDD_COUNT, "cdd_demo02");

}

if(ret < 0){

printk("register_chrdev_region failed!\n");

goto failure_register_chrdev;

}

//获取主设备号

cdd_major = MAJOR(dev);

printk("cdd_major = %d\n", cdd_major);

cdd_cdevp = kzalloc(sizeof(struct cdd_cdev)*CDD_COUNT, GFP_KERNEL);

if(IS_ERR(cdd_cdevp)){

printk("kzalloc failed!\n");

goto failure_kzalloc;

}

/*创建设备类*/

dev_class = class_create(THIS_MODULE, "cdd_class");

if(IS_ERR(dev_class)){

printk("class_create failed!\n");

goto failure_dev_class;

}

for(i=0; i

/*初始化cdev*/

cdev_init(&(cdd_cdevp[i].cdev), &cdd_fops);

/*添加cdev到内核*/

cdev_add(&(cdd_cdevp[i].cdev), dev+i, 1);

/* “/dev/xxx” */

device_create(dev_class, NULL, dev+i, NULL, "cdd%d", i);

cdd_cdevp[i].led = i;//为led变量赋值,通过led区分是一组设备中的哪个设备

}

return 0;

failure_dev_class:

kfree(cdd_cdevp);

failure_kzalloc:

unregister_chrdev_region(dev, CDD_COUNT);

failure_register_chrdev:

return ret;

}

void __exit cdd_exit(void)

{

/*逆序消除*/

int i = 0;

for(; i < CDD_COUNT; i++){

device_destroy(dev_class, dev+i);

cdev_del(&(cdd_cdevp[i].cdev));

//cdev_del(&((cdd_cdevp+i)->cdev));

}

class_destroy(dev_class);

kfree(cdd_cdevp);

unregister_chrdev_region(dev, CDD_COUNT);

}

module_init(cdd_init);

module_exit(cdd_exit);

linux 查看是否有led设备,linux驱动开发--字符设备:通过cdd_cdev结构中的led变量区分是哪个节点,private_data使用...相关推荐

  1. <Linux开发>--驱动开发-- 字符设备驱动(3) 过程详细记录

    <Linux开发>–驱动开发-- 字符设备驱动(3) 过程详细记录 驱动开发是建立再系统之上的,前面作者也记录了系统移植的过程记录,如果有兴趣,可进入博主的主页查看相关文章,这里就不添加链 ...

  2. linux字符设备驱动架构,linux驱动开发--字符设备:cdd_cdev结构中private_data使用

    private_data改进 为设备驱动支持多个设备个体做准备,针对private_data进行改进 在设备打开操作中通过inode中保存的i_cdev获取代表当前设备的cdev对象 通过代表当前设备 ...

  3. linux open函数_Linux驱动开发 / 字符设备驱动内幕 (1)

    哈喽,我是老吴,继续记录我的学习心得. 一.保持专注的几个技巧 将最重要的事放在早上做. 待在无干扰环境下,比如图书馆. 意识到刚坐下开始投入工作前,有点负面小情绪是特别正常的现象. 让"开 ...

  4. linux的驱动开发——字符设备驱动

    1.字符设备驱动 \qquad字符设备驱动是最基本,最常用的设备.它将千差万别的硬件设备采用统一的接口封装起来,屏蔽了硬件的差异,简化了应用层的操作. 2.描述所有字符设备的结构体 \qquad描述所 ...

  5. STM32MP157驱动开发——字符设备驱动

    一.简介 字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节 流进行读写操作的设备,读写数据是分先后顺序的.比如我们最常见的点灯.按键. IIC. SPI, LCD ...

  6. 正点原子-驱动开发-字符设备驱动

    Linux中的三大类驱动:字符设备.块和网络设备驱动 I2C.SPI.音频等都属于字符设备驱动 的类型 EMMC.NAND.SD卡和 U盘等存储都属于块设备 网卡,WIFI等都属于网络驱动 一个设备可 ...

  7. _Linux驱动开发 / 字符设备驱动内幕 (1)

    哈喽,我是老吴,继续记录我的学习心得. 一.保持专注的几个技巧 将最重要的事放在早上做. 待在无干扰环境下,比如图书馆. 意识到刚坐下开始投入工作前,有点负面小情绪是特别正常的现象. 让"开 ...

  8. linux 驱动开发 --- 字符设备与混杂设备区别

    2019独角兽企业重金招聘Python工程师标准>>> 一.主设备号的生成方式不同 1.所有的混杂设备都被分配一个主设备号10,次设备号系统自动生成 2.字符设备,的主设备号,开发驱 ...

  9. linux驱动开发字符设备,linux驱动开发(三) 字符设备驱动框架

    还是老规矩先上代码 demo.c #include #include#include#include#include int demo_major = 250;int demo_minor = 0;i ...

  10. 【Linux驱动】字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...

最新文章

  1. 十年后,这是25个你会习以为常的AI应用场景
  2. PHP - NetBeans中调试PHP
  3. Gradient descent --梯度下降(to be continued)
  4. OLE和activex
  5. mvc mysql linq_MVC3+Linq to sql 显示数据库中数据表的数据
  6. [转]35个高级Python知识点总结
  7. linux socket通信编程之c语言(客户端和服务器程序)
  8. 通俗易懂地讲解 __block 变量
  9. mac如何清空Recent Places
  10. 使用FIT2CLOUD在青云QingCloud快速部署和管理Kubernetes集群 1
  11. python猜数游戏续_python实现猜数游戏
  12. 像距为什么要大于焦距?
  13. html入门怎么换字体颜色,html怎么改字体颜色
  14. Sketch 快捷键(UE图、思维图、UI设计、矢量设计图)
  15. 如何用迅捷PDF转换器获取PDF文件中的图片
  16. android sdk引入 微信分享_android 调用本地微信自定义多图分享朋友圈,可放在share sdk中一起使用...
  17. 3小时GIS入门教程(三)ArcGIS 10基本操作
  18. 钕铁硼产品磁性能相对检测原理与技术
  19. 计算机常见硬盘名称,我的硬盘我做主:自己给电脑硬盘改个名!
  20. 关于 熬夜的惩罚 一题的思路+代码(几何)

热门文章

  1. Mysql触发器与事务
  2. Sequence operation3397
  3. SQL case when then else end运用
  4. Python设计一个游戏类
  5. 智能优化算法:自私羊群优化算法-附代码
  6. 【python】中 type dtype astype辨析
  7. ArcGIS单波段提取
  8. python数组(矩阵)乘法(点乘、叉乘)
  9. 遥感数字图像处理——第三章——空间域处理方法
  10. 【ArcGIS操作】4 空间分析篇