2017-04-15 82 views
0

計算器您好親愛的參與者投票機制,實施字符設備驅動程序

我新的內核空間開發仍處於道路的起點。 我開發了一個基本的字符設備驅動程序,可以讀取打開關閉等。但找不到合適的來源以及如何爲Poll/select機制示例進行教程。

我寫的代碼示例下面查詢功能:

static unsigned int dev_poll(struct file * file, poll_table *wait) 

{

poll_wait(file,&dev_wait,wait); 
if (size_of_message > 0){ 
    printk(KERN_INFO "size_of_message > 0 returning POLLIN | POLLRDNORM\n"); 
    return POLLIN | POLLRDNORM; 
} 
else { 
    printk(KERN_INFO "dev_poll return 0\n"); 
    return 0; 
} 

}

它工作正常,但不能一已瞭解幾件事情。

當我打電話從用戶空間程序選擇爲

struct timeval time = {5,0 } ; 
select(fd + 1 , &readfs,NULL,NULL,&time); 

在驅動程序中的功能dev_poll調用一次,並以緩衝大小爲零或POLLIN。然後再也沒有打過電話。在用戶空間中,5秒後程序繼續,如果dev_poll返回0. 我無法理解的是在這裏,驅動程序代碼將如何決定並讓用戶空間程序,如果緩衝區中有東西可讀取5秒,如果它被調用一次並立即返回。

反正在內核模塊中收集來自用戶空間的timeval參數信息嗎?

謝謝你從現在開始。

問候,

回答

0

呼叫poll_wait()實際地的一些等待對象到等待隊列,指定爲第二個參數。當等待對象被觸發時(通過等待隊列的wake_up或類似的函數),輪詢函數被再次評估。

內核驅動程序不需要麻煩超時:當時間到了,等待對象將自動從等待隊列中移除。

+0

非常感謝您的回覆,那麼我該如何處理讓內核在超時時有內存數據的情況? 例如,用戶空間呼叫選擇時間爲5秒超時。 在選擇的開始我沒有設備中的數據。然後我有2秒的數據。所以我想喚醒用戶空間程序。我如何實現這一點? – Ozan

+0

正如答案中所寫,當隊列變爲非空時,您需要調用'wake_up'來獲得您正在用於'poll'的等待隊列。 – Tsyvarev

0

你好親愛的好奇的人喜歡我投票。我想出了一個解決方案。

從stackowerflow的另一個話題,一個傢伙說,如果內核需要持續的情況,poll_function會被多次調用。所以基本上我實現了這個代碼。

當輪詢時調用wait_poll(wait_queue_head);當設備具有緩衝數據時(這通常在驅動程序寫入功能中)。 用wait_queue_head參數調用wake_up宏。 所以在這個步驟之後再次調用驅動程序的輪詢函數。 所以在這裏你可以返回你想要返回的任何東西。在這種情況下,POLLIN | POLLRDNORM ..

這是我在驅動程序中寫入和輪詢的示例代碼。

static unsigned int dev_poll(struct file * file, poll_table *wait) 
{ 
    static int dev_poll_called_count = 0 ; 
    dev_poll_called_count ++; 
    poll_wait(file,&dev_wait,wait); 
    read_wait_queue_length++; 
    printk(KERN_INFO "Inside dev_poll called time is : %d read_wait_queue_length %d\n",dev_poll_called_count,read_wait_queue_length); 

    printk(KERN_INFO "After poll_wait wake_up called\n"); 
    if (size_of_message > 0){ 
     printk(KERN_INFO "size_of_message > 0 returning POLLIN | POLLRDNORM\n"); 
     return POLLIN | POLLRDNORM; 
    } 
    else { 
     printk(KERN_INFO "dev_poll return 0\n"); 
     return 0; 
    } 
} 

    static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){ 
    printk(KERN_INFO "Inside write \n");; 
    int ret;  
    ret = copy_from_user(message, buffer, len); 
    size_of_message = len ; 
    printk(KERN_INFO "EBBChar: Received %zu characters from the user\n", size_of_message); 
    if (ret) 
     return -EFAULT; 
    message[len] = '\0'; 
    printk(KERN_INFO "gelen string %s", message); 
    if (read_wait_queue_length) 
    { 
     wake_up(&dev_wait); 
     read_wait_queue_length = 0; 
    } 
    return len; 

}