LDD3学习笔记(5):字符驱动3

简介:  1、字符设备注册在运行时获得一个独立的cdev结构的代码:Struct cdev* my_cdev=cdev_alloc();My_codev->ops=&my_fops;将cdev结构嵌入自己设备特定的结构:Void cdev_ini...
 

1、字符设备注册

在运行时获得一个独立的cdev结构的代码:

Struct cdev* my_cdev=cdev_alloc();

My_codev->ops=&my_fops;

cdev结构嵌入自己设备特定的结构:

Void cdev_init(struct cdev* cdev , struct file_operations* fops);

Cdev结构建立后,告诉内核:

Int cdev_add(struct cdev*dev dev_t num,unsigned int count);

在驱动完全准备好处理设备上的操作后再调用cdev_add

为系统去除一个字符设备,调用:

Void cdev_del(struct cdev*dev);

1.1scull中的设备注册

Scull的结构struct scull_dev:

struct scull_dev { 

 struct scull_qset *data;  /* Pointer to first quantum set */ 

 int quantum;  /* the current quantum size */ 

 int qset;  /* the current array size */ 

 unsigned long size;  /* amount of data stored here */ 

 unsigned int access_key;  /* used by sculluid and scullpriv */ 

 struct semaphore sem;  /* mutual exclusion semaphore  */ 

 struct cdev cdev; /* Char device structure */

};

设备与内核接口的struct cdev这个结构必须初始化,并添加到系统中,scull处理这个任务的代码是:

static void scull_setup_cdev(struct scull_dev *dev, int index)

{

 int err, devno = MKDEV(scull_major, scull_minor + index);

 cdev_init(&dev->cdev, &scull_fops);

 dev->cdev.owner = THIS_MODULE;

 dev->cdev.ops = &scull_fops;

 err = cdev_add (&dev->cdev, devno, 1);

 /* Fail gracefully if need be */

 if (err)

 printk(KERN_NOTICE "Error %d adding scull%d", err, index);

}

2、openrelease

至此已经快速浏览了这些成员,并在以后scull的函数中使用它们。

2.1open方法

Open应当做的工作:

●     检查设备特定的错误(例如设备没准备好或者类似的硬件错误)

●     如果它第一次打开初始化设备

●     如果需要更新 f_op 指针.

●     分配并填充要放进 filp->private_data 的任何数据结构

Open的原型

Int *open)(struct inode* inode, struct file*filp);

container_of(pointer, container_type, container_field); 

这个宏使用一个指向 container_field 类型的成员的指针它在一个 container_type 类型的结构中

且返回一个指针指向包含结构在 scull_open, 这个宏用来找到适当的设备结构:

struct scull_dev *dev; /* device information */ 

dev = container_of(inode->i_cdev, struct scull_dev, c

filp->private_data = dev; /* for other methods */

2.2release方法

应该实现的任务:

●     释放 open 分配在 filp->private_data 中的任何东西

在最后的 close 关闭设备

3、scull的内存使用

scull 驱动引入 个核心函数来管理 Linux 内核中的内存这些函数定义在 <linux/slab.h>, :

void *kmalloc(size_t size, int flags); 

void kfree(void *ptr);

4、读和写

scull 中的读写代码需要拷贝一整段数据到或者从用户地址空间这个能力由下列内核函数提供

们拷贝一个任意的字节数组并且位于大部分读写实现的核心中.

unsigned long copy_to_user(void __user *to,const void *from,unsigned long count); 

unsigned long copy_from_user(void *to,const void __user *from,unsigned long count); 

目录
相关文章
|
8月前
|
Linux API
字符设备驱动(1):Linux字符设备驱动结构
字符设备驱动(1):Linux字符设备驱动结构
106 1
|
8月前
|
存储 Linux
Linux文件编程(lseek函数和stat函数)
Linux文件编程(lseek函数和stat函数)
126 0
Linux文件编程(lseek函数和stat函数)
|
Linux
Linux驱动开发——(Linux内核GPIO操作库函数)gpio(1)
Linux驱动开发——(Linux内核GPIO操作库函数)gpio(1)
414 0
Linux驱动开发——(Linux内核GPIO操作库函数)gpio(1)
|
机器学习/深度学习 Linux
linux 高级字符设备驱动 ioctl操作介绍 例程分析实现【转】
转自:http://my.oschina.net/u/274829/blog/285014 1,ioctl介绍 ioctl控制设备读写数据以及关闭等。 用户空间函数原型:int ioctl(int fd,unsinged long cmd,...)   fd-文件描述符 cmd-对设备的发出的控制命令 ...表示这是一个可选的参数,存在与否依赖于cmd,如cmd为修改波特率,那么....就表示波特率的值。
1367 0
|
物联网 Linux
用ioctl获取无线网络信息 /usr//include/linux/wireless.h
1、UNIX Network Programming环境搭建 Unix NetWork Programming――环境搭建(解决unp.h等源码编译问题) http://blog.csdn.net/a649518776/article/details/6724121 注:按照连接操作即可,...
2440 0
|
Linux Android开发
I.MX6 Linux、Jni ioctl 差异
/*********************************************************************** * I.MX6 Linux、Jni ioctl 差异 * 声明: * 在使用Jni的ioctl()的过程中,发现不能像普通的Linux函数那样使用, * 必须使用3各参数的ioctl()函数。
1071 0
|
Shell Linux
LDD3学习笔记(3):字符驱动1
1、scull( Simple Character Utility for Loading  Localities)的设计 Scull是一个字符驱动,它操作一块内存区域,就好像它是一个设备,因此在以下的介绍中我们可以互换的使用设备和scull操作的内存区。
901 0
LDD3学习笔记(4):字符驱动2
1、重要的数据结构 注册设备编号仅仅是驱动代码需要完成的任务之一,还有很多基础性的驱动操作需要驱动代码来完成,这里有3个重要的内核数据结构需要了解一下分别是:file_operations、file、inode。
1066 0

热门文章

最新文章