《Linux4.0设备驱动开发详解》笔记--第六章:Linux字符设备驱动
来源:互联网 发布:知乎暴力离职 编辑:程序博客网 时间:2024/05/14 10:51
6.1 linux字符设备驱动结构
6.1.1 cdev结构体
- cdev结构体描述一个字符设备
struct cdev { struct kobject kobj; //内嵌的kobject对象 struct module *owner; //所属模块 const struct file_operations *ops;//文件操作结构 struct list_head list; dev_t dev; //设备号,int 类型 unsigned int count; };
- cdev的dev_t成员定义了设备号,高12位为主设备号,低20位为次设备号
- 获取主、次设备号:
- MAJOR(dev_t dev)
- MINOR(dev_t dev)
- 主次设备号生成dev_t:MKDEV(int major,int minor)
- 获取主、次设备号:
- cdev结构体相关的操作函数
void cdev_init(struct cdev *, const struct file_operations *);//建立cdev和file_operation之间的连接struct cdev *cdev_alloc(void); //动态申请一个cdev内存 void cdev_put(struct cdev *p); //释放 int cdev_add(struct cdev *, dev_t, unsigned); //注册设备void cdev_del(struct cdev *);//注销设备
6.1.2 分配和释放设备号
- 在注册设备之前应该先申请设备号
- register_chrdev_region()用于已知设备号
- register_chrdev_region()用于动态申请
int register_chrdev_region(dev_t from,unsigned count,const char *name)int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name)
- 释放设备号
void unregister_chrdev_region(dev_t from,unsigned count)
- 注册与注销字符设备顺序关系如下:
register_chrdev_region()-->cdev_add() //此过程在加载模块中 cdev_del()-->unregister_chrdev_region() //此过程在卸载模块中
6.1.3 字符设备驱动组成
- 字符设备的模块加载与卸载函数
- 字符设备驱动的file_operation结构体中的成员函数,大多数实现以下函数
- read()
- write()
- ioctl()
- copy_from_user():用户空间缓冲区到内核空间
- copy_to_user():内核空间到用户空间缓冲区
- 返回0:成功
- 返回正数:不能被复制的字节数
- 负数:操作失败
- 复制的内容是简单的类型,如int、char、long等,则可以用以下函数
- put_user、get_user
- 上述函数中_user是一个宏,表示其后的指针指向用户空间
- 内核空间访问用户空间缓存时需要合法性检查
- access_ok(type, add, size):确认缓存区确实属于用户空间
- ioctl函数
- 设备类型字段为一个幻数,可以使0-0xff的值,内核中的ioctl-number.txt有推荐的已经存在的幻数,新设备区应该避免与其冲突
- 方向字段表示数据传输的方向
- _IOC_NONE:无数据传输
- _IOC_READ:读
- _IOC_WRITE:写
- _IOC_READ|_IOC_WRITE:双向
预定义命令:内核中预定了一些I/O控制命令,如果某设备中抱哈没了与预定义命令一样的命令码,则这些命令会作为预定义命令被内核处理而不是被设备驱动处理
- FIOCLEX:通知内核当exec()系统调用发生时,自动关闭打开的文件
- FIONCLEX:与FIOCLEX相反,清除由FIOCLEX命令设置的标志
- FIOQSIZE:获得一个文件和目录的大小,当用于设备文件时返回一个ENOTTY错误
- FIONBIO:修改在filp->f_flags中的O_NONBLOCK标志
0 0
- 《Linux4.0设备驱动开发详解》笔记--第六章:Linux字符设备驱动
- 《Linux4.0设备驱动开发详解》笔记--第十章:Linux设备驱动中的中断与时钟
- 《Linux4.0设备驱动开发详解》笔记--第十二章:Linux设备驱动的软件架构思想
- 《Linux4.0设备驱动开发详解》笔记--第十三章:Linux块设备驱动
- 《Linux4.0设备驱动开发详解》笔记--第十五章:Linux I2C核心、总线与设备驱动
- 《Linux4.0设备驱动开发详解》笔记--第二十一章:Linux设备驱动的调试
- 《Linux4.0设备驱动开发详解》笔记--第五章:Linux文件系统与设备文件
- 《Linux4.0设备驱动开发详解》笔记--第七章:Linux设备中的并发控制
- 《Linux4.0设备驱动开发详解》笔记--第十八章:ARM Linux设备树
- 《Linux4.0设备驱动开发详解》笔记--第十四章:Linux网络设备驱动
- 《Linux4.0设备驱动开发详解》笔记--第二十章:Linux芯片级移植及底层驱动
- 《Linux4.0设备驱动开发详解》笔记--第一章:Linux设备驱动概念及基础
- 《Linux4.0设备驱动开发详解》笔记--第八章:linux设备驱动的阻塞与非阻塞
- 《Linux4.0设备驱动开发详解》笔记--第十六章:USB主机、设备与Gadget驱动
- 《Linux4.0设备驱动开发详解》笔记--第二章:Linux内核及内核编程
- 《Linux4.0设备驱动开发详解》笔记--第三章:Linux下的C编程特点
- 《Linux4.0设备驱动开发详解》笔记--第四章:Linux内核模块
- 《Linux4.0设备驱动开发详解》笔记--第十九章:Linux电源管理的系统架构和驱动
- Linux驱动学习心得
- Xcode7.2使用sqlite3数据库的方法
- ValueAnimator实现机制_源码分析
- LeetCode 31. Next Permutation(下一个排列)
- 第十二周项目2—Time类中的运算符重载
- 《Linux4.0设备驱动开发详解》笔记--第六章:Linux字符设备驱动
- 第五周项目二(2)游戏中的角色类
- 消息机制实现_源码分析
- java集合框架
- UE4:本地化弹出框
- find命令详解
- 这四个原则能让你变得幸运
- 【四】——C++容器
- 虚拟机提示物理内存不足