我有一个关于 char 驱动程序的问题。使用 GPIO 引脚与硬件设备通信的字符驱动程序,包括中断接口。缺少驱动程序的“release()”方法。功能元素应该按什么顺序排列?
A. 删除 cdev 并注销设备
B. 免费 GPIO 资源
C. 释放 IRQ 资源
D. Unregistrer 主要/次要编号
“release()”方法中的顺序是什么?
谢谢
我有一个关于 char 驱动程序的问题。使用 GPIO 引脚与硬件设备通信的字符驱动程序,包括中断接口。缺少驱动程序的“release()”方法。功能元素应该按什么顺序排列?
A. 删除 cdev 并注销设备
B. 免费 GPIO 资源
C. 释放 IRQ 资源
D. Unregistrer 主要/次要编号
“release()”方法中的顺序是什么?
谢谢
根据我的理解,正确的顺序看起来像 C、B、A 和 D :-)。说明:需要释放 IRQ,因为 gpio 引脚(用作中断引脚),IRQ 编号是通过将此 gpio 引脚传递给gpio_to_irq 获得的,之后您才能继续释放 gpio 的东西。在删除 cdev 之后,对哪个文件操作,设备节点信息(dev_t,32 位无符号整数。其中 12 位用于主要编号,其余 20 位用于次要编号)和次要编号信息(次要无开始值和要求的次要没有数)相关联。最后继续取消注册驱动程序。
实际上,其中一些事情可能在release()
函数中完成,而其中一些事情必须在module_exit()
函数中完成。这完全取决于你在哪里做什么。
首先,一些术语: module_init()
在使用 insmod 加载模块时调用。相反的函数是module_exit()
在使用 rmmod 卸载模块时调用的。 open()
当用户进程尝试使用系统调用打开设备文件时调用,当打开设备文件的进程(以及从该原始进程分支的所有进程)调用系统调用时open()
调用相反的函数文件描述符。release()
close()
module_exit() 函数与 module_init() 函数相反。假设您使用的是 CDev API,在模块 init 函数中,您必须alloc_chrdev_region()
先使用或register_chrdev_region()
在将 cdev 添加到系统之前注册一个主要/次要编号 (D) cdev_init()
,然后使用cdev_add()
.
按理说,当module_exit()
被调用时,你应该以相反的顺序撤销你所做的;即先删除 cdev cdev_del()
,然后使用 . 注销主要/次要编号unregister_chrdev_region()
。
在module_init()
函数中的某个时刻,您可以request_mem_region()
使用&请求 GPIO 资源ioremap()
,然后使用 请求 IRQ 资源request_irq()
。另一方面,您可以open()
在函数中请求 GPIO 资源和 IRQ 资源。
如果你在module_init()
函数中请求这些资源,那么你应该在函数中释放这些资源module_exit()
。但是,如果你这样做,open()
那么你应该跟踪有多少进程打开了设备文件,当所有进程都释放了设备文件时,释放release()
函数中的资源。
同样,无论您请求资源的顺序是什么,通常您都应该以相反的顺序释放资源。然而,我会说,在释放 IRQ 资源之前释放内存资源(在你的情况下是 GPIO 资源)几乎总是不正确的,因为 IRQ 很可能想要与硬件对话,无论是在上半部分还是在下半部处理程序。
总而言之,顺序取决于您如何实现驱动程序以首先请求资源,但是,如果您像我一样实现驱动程序,那么通常执行 C 然后 B in release()
,然后执行 A 然后 D in module_exit()
。