我正在为操作系统类写一个“困”的设备驱动程序。
它的工作方式是,用户通过read() / write()访问设备。 当用户像这样write(fd,&wait,size)设备时: write(fd,size) ,设备进入睡眠wait的时间(以秒为单位)。 如果等待时间过期,则驱动程序的写入方法返回0,程序结束。 但是,如果用户在等待队列中进程处于睡眠状态时从驱动程序中读取数据,则驱动程序的写入方法将立即返回睡眠进程在超时发生之前等待的等待秒数。
另一个问题是创build了10个设备实例,并且这10个设备中的每一个必须是相互独立的。 因此,对设备1的读取只能唤醒设备1上的睡眠进程。
已经提供了许多代码,并且我主要负责主要为驱动程序write() read()和write()方法的任务。
在Windows XP上检索详细的USB MIDI设备信息
我在哪里可以find关于Windowsvideo捕捉体系结构,特别是虚拟摄像头驱动程序?
如何为RawInput HID设备获取人类可读的名字?
IoGetDeviceObjectPointer()返回的设备对象上的I / O使用IRP
如何捕获在Linux上的原始HIDinput?
我试图解决保持设备彼此独立的问题的方法是包含两个全局静态数组,其中一个是wait_head_queue_ttypes,另一个是Int (Bool标志)types。 当我通过open()打开设备时,这两个数组都是初始化的。 问题是,当我调用wake_up_interruptible() ,没有任何反应,程序在超时后终止。 这是我写的方法:
ssize_t sleepy_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_pos){ struct sleepy_dev *dev = (struct sleepy_dev *)filp->private_data; ssize_t retval = 0; int mem_to_be_copied = 0; if (mutex_lock_killable(&dev->sleepy_mutex)) { return -EINTR; } // check size if(count != 4) // user must provide 4 byte Int { return EINVAL; // = 22 } // else if the user provided valid sized input... else { if((mem_to_be_copied = copy_from_user(&long_buff[0],buf,count))) { return -EFAULT; } // check for negative wait time entered by user if(long_buff[0] > -1)// "long_buff[]"is global,for Now only holds 1 value { proc_read_flags[MInor(dev->cdev.dev)] = 0; //****** flag array retval = wait_event_interruptible_timeout(wqs[MInor(dev->cdev.dev)],proc_read_flags[MInor(dev->cdev.dev)] == 1,long_buff[0] * HZ) / HZ; proc_read_flags[MInor(dev->cdev.dev)] = 0; // MInor numbers for each // device correspond to array indices // devices 0 - 9 // "wqs" is array of wait queues } else { printk(KERN_INFO "user entered negative value for sleep timen"); } } mutex_unlock(&dev->sleepy_mutex); return retval;}
与关于此主题的许多示例不同,在wait_event_interruptible_timeout()调用之前,我将标志切换回零,因为标志值似乎在随后的程序运行之间挥之不去。 这是我的阅读方法的代码:
ssize_t sleepy_read(struct file *filp,char __user *buf,loff_t *f_pos){ struct sleepy_dev *dev = (struct sleepy_dev *)filp->private_data; ssize_t retval = 0; if (mutex_lock_killable(&dev->sleepy_mutex)) return -EINTR; // switch the flag proc_read_flags[MInor(dev->cdev.dev)] = 1; // again device minor numbers // correspond to array indices // Todo: this is not waking up the process in write! // wake up the queue wake_up_interruptible(&wqs[MInor(dev->cdev.dev)]); mutex_unlock(&dev->sleepy_mutex); return retval;}
我试图testing程序的方式是有两个main.c,一个用于写入设备,另一个用于从设备读取,而我只是./a.out它们放在我的ubuntu安装的单独控制台中的./a.out 。 另一件事,就是现在设置的方式,直到超时发生,写或读a.outs返回。 我为代码的参差不齐格式道歉。 我不确定到底发生了什么事情,所以任何帮助将不胜感激! 谢谢!
devcon禁用不能禁用找不到的设备
将Windows设备pathparsing为驱动器号
在Linux内核模块中获取现有设备类(struct class)的指针
从SetupDiGetClassDevs获取设备接口
等待事件时,您的写入方法会保留sleepy_mutex 。 所以读取方法等待mutex_lock_killable(&dev->sleepy_mutex)同时作者解锁互斥锁。 只有在写入超时时才会发生,写入方法返回。 这是你观察到的行为。
通常,wait_event *在任何关键部分之外执行。 这可以通过使用这样的宏的_lock-后缀变体来实现,或者简单地用spinlock获取/释放对来包装这些宏的cond参数:
int check_cond() { int res; spin_lock(&lock); res = <cond>; spin_unlock(&lock); return res; } ... wait_event_interruptible(&wq,check_cond());
不幸的是,当条件检查应该用一个互斥锁保护时, wait_event- family是不能使用的。 在这种情况下,可以使用带有手动条件检查代码的wait_woken()函数。 或者在条件检查的时候不需要互斥锁/解锁来重写代码。
为达到“读者唤醒作家,如果是睡眠”功能,您可以采用该答案的代码https://stackoverflow.com/a/29765695/3440745 。
作家代码:
//Declare local variable at the beginning of the function int cflag; ... // Outside of any critical section(after mutex_unlock()) cflag = proc_read_flags[MInor(dev->cdev.dev)]; wait_event_interruptible_timeout(&wqs[MInor(dev->cdev.dev)],proc_read_flags[MInor(dev->cdev.dev)] != cflag,long_buff[0]*HZ);
阅读器代码:
// Mutex holding protects this flag's increment from concurrent one. proc_read_flags[MInor(dev->cdev.dev)]++; wake_up_interruptible_all(&wqs[MInor(dev->cdev.dev)]);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。