- 打开
- int open(struct inode *inode,struct file *filp);
- 模块使用计数加1
- 识别次设备号
- 硬件操作
- 检查设备相关错误(诸如设备未就绪或类似的硬件问题)
- 如果设备是首次打开,则对其初始化
- 如果有中断操作,申请中断处理程序
- 关闭
- int release(struct inode *inode,struct file *filp);
- 模块使用计数减1
- 释放由open分配的,保存在filp>private_data里的所有内容。
- 硬件操作:
- 如果申请了中断,则释放中断中中断处理程序。
- 在最后一次关闭操作时关闭设备。
- read/write
- ssize_t read(struct file *filp,char __user *buff,sieze_t count,loff_t *offp);
- ssize_t write(struct file *filp,const char __user *buff,size_t count,loff_t *offp);
- 用户空间和内核空间之间的数据拷贝过程
- 不能简单的用指针操作或者memcpy来进行数据的拷贝
- 用户空间的数据是可以被换出的,会产生一个页面失效的异常
- 用户空间的地址无法在内核空间中使用。
- 用户空间和内核空间之间进行数据拷贝的函数
- unsigned long copy_from_user(void *to,const void __user *from,unsigned long count);
- unsigned long copy_to_user(void __user *to,const void *from,unsigned long count);
- 读设备模板
ssize_t xxx_read(struct *filp,char __user *buf,size_t count,loff_t*f_fpos)
{
copy_to_user(buf,---)
}
-
- 写设备模板
ssize_t xxx_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_ops)
{
copy_from_user(--,buf,--);
}
- ioctl函数
- 为设备驱动程序执行命令提供了一个特有的入口点
- 用来设置或者读取设备的属性信息
- int ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);
- cmd参数的定义
- 不推荐使用0x1,0x2之类的值
- linux对ioctl()的cmd参数有特殊的定义
- 设别号(type) 序列号(number) 方向(direction) 数据尺寸(size)
- 8bit 8bit 2bit 13/14bit
- 构造命令编号的宏:
- _IO(type,nr)用于构造物参数的命令编号;
- _IOR(type,nr,datatype)用于构造从驱动程序中读取数据的命令编号;
- _IOw(type,nr,datatype)用于写入数据的命令
- _IOWR(type,nr,datatype)用于双向传输。
- type,nr通过参数传入,而size位字段通过对datatype参数的sizeof获得。
- ioctl函数模板
int xxx_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
-----
switch(cmd)
{
case xxx_cmd1:
----
break;
case xxx_cmd2:
----
break;
default:
return -ENOTTY;
}
return 0;
}
- 字符设备驱动结构: