框架准备
- 基本的框架
- app如何调用驱动机制
- 字符设备驱动编写步骤
- 1. 实现入口函数 XXX_init()和卸载函数 XXX_exit()
- 2. 申请设备号 register_chrdev_region(与内核相关)
- 3. 注册字符设备驱动 cdev_alloc / cdev_init /cdev_add(与内核相关)
- 4. 利用udev/mdev机制创建设备文件(节点)class_create,device_create(与内核相关)
- 5. 硬件部分初始化
- 6. 构建file_operation结构(与内核相关)
- 7. 实现硬件操作方法 XXX_open,XXX_read,XXX_write...(与硬件相关)
- 通用GPIO驱动框架的问题及理解
- setup_timer()函数
- add_timer()函数
- gpio_to_irq()函数或gpiod_to_irq()
- request_irq()函数
- register_chrdev()
- class_create()函数
- device_create()函数
- 通用驱动框架总结
- 所遇到的驱动方面的问题
- 驱动里用的\_IOW()函数有什么用???
- 这几个宏的使用格式
- 嵌入式调试技巧 -- gcc工具
- 1. 打印文件信息
- 2. 字符串化操作符
- 3. ## 连接操作符,详见c_test验证
- 4. 使用do…while的宏定义
- 5. 分级检查机制
知识储备。
基本的框架
在linux系统中,App无法操作硬件的,不具备相应的权限。在mmu(内存管理单元)作了划分的,应用层只能操作属于它的mmu部分。操作硬件只能是通过驱动程序。应用程序与驱动程序之间有严格的界限。驱动程序在内核中。
app如何调用驱动机制
如App使用open函数打开设备时,会先设置某个寄存器,会触发一个异常swi指令(此时由用户态切换到内核态才有更高的权限),此时会有中断服务程序被调用。然后根据先前设置的寄存器判断是什么操作;然后去读写硬件。
字符设备驱动编写步骤
1. 实现入口函数 XXX_init()和卸载函数 XXX_exit()
2. 申请设备号 register_chrdev_region(与内核相关)
静态分配设备号:在事先知道设备主设备号的情况下通过参数函数指定第一个设备号而向系统申请分配一定数目的设备号。
动态分配:alloc_chrdev_region():通过参数仅设置第一个次设备号(通常为0,事先不会知道主设备号)和要分配的设备数目而系统动态分配所需的设备号
3. 注册字符设备驱动 cdev_alloc / cdev_init /cdev_add(与内核相关)
4. 利用udev/mdev机制创建设备文件(节点)class_create,device_create(与内核相关)
5. 硬件部分初始化
io资源映射 ioremao,内核提供gpio库函数(与硬件相关)
注册中断(与硬件相关)
初始化等待队列(与内核相关)
初始化定时器(与内核相关)
6. 构建file_operation结构(与内核相关)
7. 实现硬件操作方法 XXX_open,XXX_read,XXX_write…(与硬件相关)
通用GPIO驱动框架的问题及理解
setup_timer()函数
原型:#define setup_timer(timer, fn, data) \ __setup_timer((timer), (fn), (data), 0)
第一个参数:是struct timer_list类型的变量,此变量用于存放动态定时器,是即将要被初始化的对象,其定义及详细解释参考
第二个参数是定时器到期时将要执行的函数,用于给定时器变量的function字段赋值。
第三个参数用于给定时器变量的data字段赋值
add_timer()函数
将定时器加入到定时器链表,并激活定时器