linux驱动设备在多进程打开问题
一、问题
一个spi设备,单独一个进程打开读写没有问题,但是多进程打开却死锁了
当然该设备驱动是修改过的,并不是原生态的spi驱动
问题:在用户空间多进程打开一个驱动设备或文件,设备号是共享还是独立的,在内核中又是根据什么来区分两个进程的数据的?
二、探索
int main()
{
int fd;
int pid = 0;
unsigned short i = 0, data = 0;
pid = fork();
if(pid == 0)
{
printf("child process, test w/r fpga\n");
fd = open("/dev/spidev0.0",O_RDWR);
printf("FPGA opened,fd is %d\n",fd);
}
if(pid > 0)
{
printf("father process, test w/r dpll\n");
fd = open("/dev/spidev0.0",O_RDWR);
printf("DPLL opened,fd is %d\n",fd);
}
}
打印输出,两个fd均为3,查过资料后,进程间的 文件描述符是独立的
那么分析一下open操作的过程。
就以spi驱动为例,该函数有两个形参,struct inode *inode 和 struct file *file
其中私有数据部分 filp->private_data = spidev;
spidev又是通过
list_for_each_entry(spidev, &device_list, device_entry) {
if (spidev->devt == inode->i_rdev) {
status = 0;
break;
}
}
查表得来的,而这个表是在内核初始化的时候spi初始化插入到表中的
关于两个数据结构,找到如下信息:http://bbs.csdn.net/topics/240046570
在用户空间,我们知道 文件描述符来表示一个打开的文件。
而在内核空间,来表示文件(或者说对文件操作的)是几个重要的数据结构:
分别是四个数据机构
struct super_block
struct inode
struct file
struct dentry
file表示的是打开的文件,因为一个文件可以多次打开,这个东西代表的是打开了的文件
inode表示的是物理上的文件,这个文件是唯一的,就算是被多次打开,这个东西也是唯一的
fileopteration这个是文件操作符,对应于你在应用程序中传进来的函数方法对应到你内核中的方法
可见,inode是唯一的,即使多进程打开,inode是相同的,
inode->i_rdev是相关设备的设备号,因此同一设备,设备号是相同的
例:{
除了从dev_t得到主设备号和次设备号外,这里还可以使用imajor()和iminor()函数从i_rdev中得到主设备号和次设备号。
imajor()函数在内部调用MAJOR宏,如下代码所示。
- static inline unsigned imajor(const struct inode *inode)
- {
- return MAJOR(inode->i_rdev); /*从inode->i_rdev中提取主设备号*/
- }
同样,iminor()函数在内部调用MINOR宏,如下代码所示。
}
- static inline unsigned iminor(const struct inode *inode)
- {
- return MINOR(inode->i_rdev); ; /*从inode->i_rdev中提取次设备号*/
- }
三、结论
最终得到 filp->private_data是与open函数具体实现相关,因此也要注意其中锁的使用
1.多次打开设备,filp->private_data相同,则要注意数据的保护和死锁
2.多次打开设备,filp->private_data不同,这样影响会小一些
更多推荐
所有评论(0)