我正在爲操作系統類寫一個「困」的設備驅動程序。linux wake_up_interruptible()沒有效果
它的工作方式是,用戶通過read()
/write()
訪問設備。 當用戶寫入設備時,如下所示:write(fd, &wait, size)
,設備進入睡眠狀態的時間量爲wait
的秒數。如果等待時間到期,則驅動程序的寫入方法返回0,程序結束。但是,如果用戶在進程在等待隊列中休眠時從驅動程序中讀取數據,則驅動程序的寫入方法會立即返回睡眠進程在超時自行發生之前需要等待的秒數。
另一個問題是創建了10個設備實例,並且10個設備中的每個設備都必須是相互獨立的。因此,對設備1的讀取必須僅喚醒設備1上的睡眠過程。
已提供了許多代碼,並且我負責主要爲驅動程序編寫read()
和write()
方法。
我試圖解決保持設備彼此獨立的問題的方式是包含兩個大小爲10的全局靜態數組。其中一個類型爲wait_head_queue_t
,類型爲Int
(布爾標誌)。當我通過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 time\n");
}
}
mutex_unlock(&dev->sleepy_mutex);
return retval;}
不同於在這個話題的例子很多,我切換旗回零馬上打電話給wait_event_interruptible_timeout()
之前,因爲標誌值似乎後續程序的運行之間進行徘徊。下面是我的閱讀方法的代碼:
ssize_t sleepy_read(struct file *filp, char __user *buf, size_t count,
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;}
我想測試程序的方法是有兩個main.c中的,一個用於寫入設備和一個從設備讀取,我只是./a.out
他們在我的ubuntu安裝在虛擬框中單獨的控制檯。另一件事,就是現在設置的方式,無論是寫還是讀a.outs
直到超時發生。我爲代碼的參差不齊的格式表示歉意。我不確定在這裏發生了什麼,所以任何幫助將不勝感激!謝謝!
你有沒有證實wake_up_interruptible(WQS [MINOR(dev亡> cdev.dev)])達到您的超時時間間隔之前調用? – jjb
jjm,你是對的,wake_up_interruptible直到超時後才被調用。 – user1708898