linux设备驱动笔记——字符设备驱动
2007-01-29 14:03
330 查看
第3章 字符设备驱动程序
※ “全局性”是指,如果打开设备多次,所有打开它的文件描述符共享其中的数据。“持久性”是指,如果设备关闭后再次打开,数据不丢失。
※ 真实的驱动程序利用中断与它们的设备同步
※ 设备编号的内部表达
n 在内核中,dev_t类型(在<linux/types.h>中定义)用来保存设备编号——包括主设备号和次设备号。
n MAJOR(dev_t dev); MINOR(dev_t dev) MKDEV(int major, int minor)
※ 分配和释放设备编号
n <linux/fs.h>:
int register_chrdev_region(dev_t first, unsigned int count, char *name);
※ 动态分配主设备号
n 某些主设备号已经静态地分配给了大部分公用设备。在内核源码树的Documentation/device.txt文件中可以找到这些设备的列表。
n 一旦驱动程序被广泛使用,随机选定的主设备号可能造成冲突和麻烦
n 强烈推荐你不要随便选择一个一个当前不用的设备号做为主设备号,而使用动态分配机制获取你的主设备号。
n 动态分配的缺点是,由于分配给你的主设备号不能保证总是一样的,无法事先创建设备节点。然而这不是什么问题,这是因为一旦分配了设备号,你就可以从/proc/devices读到。为了加载一个设备驱动程序,对insmod的调用被替换为一个简单的脚本,它通过/proc/devices获得新分配的主设备号,并创建节点
n 分配主设备号的最佳方式:默认采用动态分配,同时保留在加载甚至是编译时指定主设备号的余地。
n Here's the code we use in scull 's source to get a major number:
※ The classic way to register a char device driver is with:
※ release方法的作用正好与open相反。这个设备方法有时也称为close。它应该:
n 使用计数减1。
n 释放open分配在filp->private_data中的内存。
n 在最后一次关闭操作时关闭设备。
※ The scull driver introduces two core functions used to manage memory in the Linux kernel. These functions, defined in <linux/slab.h>, are:
void *kmalloc(size_t size, int flags);
void kfree(void *ptr);
※ 在scull中,每个设备都是一个指针链表,其中每个指针都指向一个scull_qset结构。默认情况下,每一个这样的结构通过一个中间指针数组最多可引用4000000个字节。使用了一个有1000个指针的数组,每个指针指向一个4000字节的区域。
※ 量子是什么??P65 每个量子占用4000个字节
※ 使用宏和整数值同时允许在编译期间和加载阶段进行配置,这种方法和前面选择主设备号的方法类似。对于驱动程序中任何不确定的或与策略相关的数值,我们都可以使用这种技巧。
※ read和write
※ 参数buff是指向用户空间的缓冲区,这个缓冲区或者保存要写入的数据,或者是一个存放新读入数据的空缓冲区。
※ 这两个函数还检测用户空间的指针是否有效。
※ Read方法
n 如果返回值等于最为count参数传递给read系统调用的值,所请求的字节数传输就成功完成了。这是最好的情况。
n 如果返回值是正的,但是比count小,只有部分数据成功传送。这种情况因设备的不同可能有许多原因。大部分情况下,程序会重新读数据。例如,如果你用fread函数读数据,这个库库函数会不断调用系统调用直至所请求的数据传输完成。
n 如果返回值为0,它表示已经到达了文件尾。
n 负值意味着发生了错误。值就是错误编码,错误编码在<linux/errno.h>中定义。
※ 与read相似,根据如下返回值规则,write也可以传输少于请求的数据量:
n 如果返回值等于count,则完成了请求数目的字节传送。
n 如果返回值是正的,但小于count,只传输了部分数据。再说明一次,程序很可能会再次读取余下的部分。
n 如果值为0,什么也没写。这个结果不是错误,而且也没有什么缘由需要返回一个错误编码。再说明一次,标准库会重复调用write。以后的章节会介绍阻塞型write,我们会对这种情形最更详尽的考察。
n 负值意味发生了错误;语义与read相同。
※ “全局性”是指,如果打开设备多次,所有打开它的文件描述符共享其中的数据。“持久性”是指,如果设备关闭后再次打开,数据不丢失。
※ 真实的驱动程序利用中断与它们的设备同步
主设备号和次设备号
※ 主设备号标识设备对应的驱动程序;次设备号由内核使用,用于正确确定设备文件所指的设备。我们可以通过次设备号获得一个指向内核设备的直接指针,也可将次设备号当作设备本地数组的索引,不管用哪种方式,除了知道次设备号用来指向驱动程序所实现的设备之外,内核本身基本上不关心关于次设备号的任何其他消息。※ 设备编号的内部表达
n 在内核中,dev_t类型(在<linux/types.h>中定义)用来保存设备编号——包括主设备号和次设备号。
n MAJOR(dev_t dev); MINOR(dev_t dev) MKDEV(int major, int minor)
※ 分配和释放设备编号
n <linux/fs.h>:
int register_chrdev_region(dev_t first, unsigned int count, char *name);
※ 动态分配主设备号
n 某些主设备号已经静态地分配给了大部分公用设备。在内核源码树的Documentation/device.txt文件中可以找到这些设备的列表。
n 一旦驱动程序被广泛使用,随机选定的主设备号可能造成冲突和麻烦
n 强烈推荐你不要随便选择一个一个当前不用的设备号做为主设备号,而使用动态分配机制获取你的主设备号。
n 动态分配的缺点是,由于分配给你的主设备号不能保证总是一样的,无法事先创建设备节点。然而这不是什么问题,这是因为一旦分配了设备号,你就可以从/proc/devices读到。为了加载一个设备驱动程序,对insmod的调用被替换为一个简单的脚本,它通过/proc/devices获得新分配的主设备号,并创建节点
< fa5e /span>
n 分配主设备号的最佳方式:默认采用动态分配,同时保留在加载甚至是编译时指定主设备号的余地。
n Here's the code we use in scull 's source to get a major number:
n
u
u
u
u
u
u
u
u
u
u
u
u
u
n
※ The classic way to register a char device driver is with:
n
u
u
u
u
u
※ release方法的作用正好与open相反。这个设备方法有时也称为close。它应该:
n 使用计数减1。
n 释放open分配在filp->private_data中的内存。
n 在最后一次关闭操作时关闭设备。
※ The scull driver introduces two core functions used to manage memory in the Linux kernel. These functions, defined in <linux/slab.h>, are:
void *kmalloc(size_t size, int flags);
void kfree(void *ptr);
※ 在scull中,每个设备都是一个指针链表,其中每个指针都指向一个scull_qset结构。默认情况下,每一个这样的结构通过一个中间指针数组最多可引用4000000个字节。使用了一个有1000个指针的数组,每个指针指向一个4000字节的区域。
※ 量子是什么??P65 每个量子占用4000个字节
※ 使用宏和整数值同时允许在编译期间和加载阶段进行配置,这种方法和前面选择主设备号的方法类似。对于驱动程序中任何不确定的或与策略相关的数值,我们都可以使用这种技巧。
※ read和write
※ 参数buff是指向用户空间的缓冲区,这个缓冲区或者保存要写入的数据,或者是一个存放新读入数据的空缓冲区。
※ 这两个函数还检测用户空间的指针是否有效。
※ Read方法
n 如果返回值等于最为count参数传递给read系统调用的值,所请求的字节数传输就成功完成了。这是最好的情况。
n 如果返回值是正的,但是比count小,只有部分数据成功传送。这种情况因设备的不同可能有许多原因。大部分情况下,程序会重新读数据。例如,如果你用fread函数读数据,这个库库函数会不断调用系统调用直至所请求的数据传输完成。
n 如果返回值为0,它表示已经到达了文件尾。
n 负值意味着发生了错误。值就是错误编码,错误编码在<linux/errno.h>中定义。
※ 与read相似,根据如下返回值规则,write也可以传输少于请求的数据量:
n 如果返回值等于count,则完成了请求数目的字节传送。
n 如果返回值是正的,但小于count,只传输了部分数据。再说明一次,程序很可能会再次读取余下的部分。
n 如果值为0,什么也没写。这个结果不是错误,而且也没有什么缘由需要返回一个错误编码。再说明一次,标准库会重复调用write。以后的章节会介绍阻塞型write,我们会对这种情形最更详尽的考察。
n 负值意味发生了错误;语义与read相同。
相关文章推荐
- Linux设备驱动开发详解--笔记6--字符设备驱动
- Hasen的linux设备驱动开发学习之旅--支持多设备的字符设备驱动
- 字符设备驱动之笔记-Platform设备驱动机制(1)
- linux字符设备驱动-定时器按键去抖笔记
- Linux设备驱动开发基础---字符设备驱动程序开发之基于中断的按键驱动
- Linux2.6.32驱动笔记(2)字符设备驱动编程模型
- 驱动笔记 - 字符设备常用函数
- Linux设备驱动第三天(字符设备驱动、cdev)
- linux设备驱动第三篇:如何实现一个简单的字符设备驱动
- Linux驱动开发-字符设备驱动笔记 2
- 高级字符设备驱动-Ioctl设备控制笔记
- LDD3笔记:第三章 字符设备驱动
- linux设备驱动(一)---字符设备之led驱动
- linux设备驱动第三篇:写一个简单的字符设备驱动
- linux设备驱动第三篇:写一个简单的字符设备驱动
- 嵌入式学习笔记——字符设备驱动编写
- Linux设备驱动开发基础---字符设备驱动程序开发之mini2440_ADC驱动
- 学习笔记:创建一个简单字符设备驱动的过程
- 字符设备驱动笔记——异步通知(八)
- 字符设备驱动之笔记-Platform设备驱动机制(2)