1.设备文件(设备结点)区别于普通文件
2.设备节点创建
mknod /dev/myled c 250
0
3.设备号:主设备号,次设备号
主设备号:用于应用程序根据些号找到驱动
次设备号:一旦找到驱动,通过次设备号来分区类型的不同的设备个体,比如四个串口对应的设备节点信息
4.向内核申请设备号的方法
1.静态申请
1.cat /proc/dev/deivces 找到一个空闲的主设备号
2.MKDEV(主设备号,次设备号);
3.register_chrdev_region
2.动态申请
1.alloc_chrdev_region让内核帮你分配设备号
5.内核描述字符设备通过struct cdev数据结构
6.内核给字符设备驱动提供了相关的底层操作接口是由结构体
struct
file_operations来描述
7.如果让一个字符设备驱动具有硬件操作的方法,就需要将cdev和file_operations进行关联
cdev->ops =
file_operations(cdev_init)
8.对于一个设备驱动程序关键就是围绕着cdev和file_operations
9.cdev由字符设备驱动通过设备号将要注册的cdev添加到内核的cdev的数组中, 那么应用程序通过
inode->i_rdev(设备号),以设备号索引在cdev数组中找到对应的字符设备驱动cdev(这个过程在sys_open)
找到以后,内核在创建一个file对象,
然后取出cdev中的ops给file->fop, 这样设备文件就有了自己对应
的文件操作方法!最后判断file->fop是否有open,
如果有open调用这个底动驱动的open(led_open),没有
open, 没关系, 直接返回用户空间(成功).
10.struct inode, struct file_operations
11.file_operations
open
release
以上两个接口需要根据需求来指定是否要初始化,如果没有指定,应用程序调用open永远返回成功,
如果底层驱动有open的初始化,应用程序的open的返回值由底层驱动的open的返回值来决定
read:读取数据
write:写设备
char
__user *buf; buf用于缓冲区,所以在内核空间不能直接使用*buf =
1(错误的!),
需要使用如下函数完成用户空间和内核空间的数据转换
拷贝: copy_to_user, copy_from_user, get_user,
put_user