1. open函数
int open(struct inode *inode, struct file *fp);
2. release函数
int release(struct inode *inode, struct file *fp);
3. read/write函数
ssize_t read(struct file *fp, char __user *buf, size_t count, loff_t *offp);
ssize_t write(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
用户空间和内核空间之间的数据传递:
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 file *fp, char __user *buf, size_t count, loff_t *f_pos) { ... copy_to_user(buf, ..., ...); ... } //写设备模版 ssize_t xxx_write(struct file *fp, const char __user *buf, size_t count, loff_t *f_pos) { ... copy_from_user(..., buf, ...); ... }4. ioctl函数
int ioctl(srutct inode *inode, struct file *fp, unsigned int cmd, unsigned long arg);
cmd参数的定义:
设备类型(type) | 序列号(number) | 方向(direction) | 数据尺寸(size) |
8bit | 8bit | 2bit | 13/14bit |
type、number位字段通过参数传入,而size位字段通过对datatype参数取sizeof获得。
构造命令编号的宏:
//ioctl函数模版 int xxx_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, unsigned long arg) { ... switch(cmd) { case XXX_CMD1: ... break; case XXX_CMD2: ... break; default: //不能支持的命令 return -ENOTTY; } return 0; }5. 字符设备驱动结构