linux字符设备驱动架构,linux驱动开发--字符设备:cdd_cdev结构中private_data使用
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 "linux/init.h"
#include "linux/module.h"
#include "linux/fs.h"
#include "linux/cdev.h"
#include "linux/device.h"
#include "linux/slab.h"
MODULE_LICENSE("GPL");
#define CDD_MAJOR 200//cat
/proc/devices找一个尚未使用的
#define CDD_MINOR 0
#define CDD_COUNT 10
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字符设备驱动架构,linux驱动开发--字符设备:cdd_cdev结构中private_data使用相关推荐
- linux网络驱动架构,Linux网络体系架构和网卡驱动设计
Linux网络体系架构 1.Linux的协议栈层次 2.Linux的网络子系统架构 Linux的协议栈层次 Linux的优点之一在于它丰富而稳定的网络协议栈.其范围从协议无关层(例如通用socket层 ...
- linux内核默认imx6速率配置,iTOP-iMX6开发板-设备树内核-缺省文件文件的配置
本文档主要讲解在iTOP-iMX6Q/D/PLUS 开发板的设备树内核(4.1.15)的缺省文件配置. 这里以 imx6q(imx6d 和 plus 的类似)的 qt 系统内核编译为例,Ubuntu1 ...
- linux命令查看cpu架构,Linux下如何查看CPU信息
查看当前操作系统内核信息#uname -a Linux redcat 2.6.31-20-generic #58-Ubuntu SMP Fri Mar 12 05:23:09 UTC 2010 i68 ...
- linux文件系统的总体架构,Linux NFS的整体架构与核心代码解析
前面文章我们从应用层面对NFS进行了介绍,接下来的文章我们将进入实现层面.本文首先从整体上对Linux的NFS软件架构进行介绍,然后介绍代码与实际业务逻辑介绍一下NFS的处理流程. NFS文件系统的架 ...
- Linux和Windows设备驱动架构比较
毕业后一直在学操作系统, 有时候觉得什么都懂了,有时候又觉得好像什么都不懂,但总体来说自认为对操作系统实现机制的了解比周围的人还是要多一些.去年曾花了几个星期的晚上时间断断续续翻译了这篇对Linux和 ...
- Linux设备驱动---OMAP3630 Linux I2C总线驱动分析(1)
原文地址:http://blog.csdn.net/kellycan/article/details/6394737 1 Linux I2C驱动架构 Linux下I2C驱动的架构图如下: 图1.1 L ...
- Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析
关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸机开发 -- IIC总线 ,下面回顾下 IIC 基础概念 一.IIC 基础概念 IIC(Inter-Integrated Ci ...
- Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析 (iic驱动框架,i2c驱动框架)...
转载于 : http://blog.csdn.net/zqixiao_09/article/details/50917655 关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸 ...
- linux open函数_Linux驱动开发 / 字符设备驱动内幕 (1)
哈喽,我是老吴,继续记录我的学习心得. 一.保持专注的几个技巧 将最重要的事放在早上做. 待在无干扰环境下,比如图书馆. 意识到刚坐下开始投入工作前,有点负面小情绪是特别正常的现象. 让"开 ...
最新文章
- 夏俊:深入网站服务端技术(一)——网站并发的问题
- ZOJ Monthly, January 2013
- 泛读:CVPR2014:Discriminative Deep Metric Learning for Face Verification in theWild
- 从玉农业智能蔬菜技术 农业大健康·林裕豪:中国金控斥资打造
- django models索引_Django(生命周期、每部分详解、路由层)
- OpenGL ES之GLSL自定义着色器编程实现粒子效果
- 初步认识注册表(待续)
- [css] 举例说明css有哪些简写的属性和属性值?
- 这个耳机一点不输千元级的AirPods
- mysql 事务 select_mysql 多个select需要放入一个事务吗?
- iPhone 9上架了?5月1日发货?
- 2020 第十一届蓝桥杯大赛软件赛省赛(第一场),C/C++大学B组题解
- android studio技巧之设置monitor窗口模式查看logcat
- 2022_天勤数据结构高分笔记_第二章_算法
- 番茄工作法 计划表格式
- 华为交换机 查ip冲突_怎么查看华为交换机已绑定的ip与mac
- 项目管理-4-运筹帷幄
- thrift 问题梳理
- 抗超大规模DDOS攻击
- 由英雄无敌Online开源 想到的