簡體   English   中英

從內核空間到用戶空間的事件通知

[英]Event notification from kernel space to user space

如何在內核空間中發生事件時通知用戶空間應用程序?

當數據到達某個GPIO時,硬件會產生中斷。 此數據將復制到內核緩沖區。 此時,我希望驅動程序通知應用程序它可以調用read函數將數據形式的內核緩沖區復制到用戶空間緩沖區。

我想過使用epoll方法,但epoll表示設備是否可以讀取。 我想要的是, epoll表示每當內核緩沖區已滿。

並且,有沒有辦法修改驅動程序中poll_wait()函數的行為?

(如果在聊天會話中回復,但似乎這應該是一個答案,所以把它放在這里更詳細。)

poll_wait的作用是將驅動程序添加到用戶空間程序等待的文件描述符列表中。 模式是:

  • 用戶程序調用poll / select / epoll_ctl
  • 核心內核調用驅動程序的輪詢入口點
  • 驅動程序調用poll_wait將其等待隊列添加到等待隊列列表中(除非GPIO數據已經可讀,您通過返回值指示)
  • 之后,當設備中斷時,您在等待隊列上調用wake_up,如果它(仍然)在輪詢/選擇呼叫中等待,則會解鎖該進程
  • 用戶模式程序喚醒,調用讀取實際獲取數據

IOW,poll_wait本身不會休眠(或阻塞); 它只是將您的設備添加到可能稍后喚醒進程的程序列表中。 睡眠是在核心內核中完成的(例如,在select系統調用內)。 這樣,用戶程序可以使用select一次在任意數量的設備上等待。

如果您的用戶空間程序在等待時確實沒有其他任何操作,那么您只需讀取用戶程序調用,並讓您的驅動程序設置其等待隊列並調用wait_event_interruptible(或其中一個wait_event_ *變種)。 這將阻止進程,直到你的中斷處理程序調用wake_up; 此時您從內核緩沖區復制到用戶緩沖區。

或者你可以支持這兩種方法。 通常,如果您支持select方法,還可以檢查讀取函數中的O_NONBLOCK文件標志,以便用戶代碼可以選擇不在讀取中阻止。

是的,ISR可以調用wake_up。 這是設備I / O的常見模式:“進程上下文”中的等待/阻塞,“中斷上下文”中的喚醒,然后在返回到進程上下文后完成I / O.

順便說一句,從驅動程序的角度來看,使用select,poll或epoll通常是相同的。 從用戶的角度來看,使用select或poll更容易一些。 這是一次“一次性”交易:“這里有一組文件描述符;阻塞直到其中一個准備好讀取(或寫入等)或直到超時”。

而對於epoll,您首先創建一個epoll描述符,然后單獨添加I / O文件描述符。 但是,“等待”調用只是指定單個epoll描述符。 因此,如果要等待大量文件描述符,則不必在每次系統調用中指定所有這些文件描述符,這會導致每次epoll調用的系統調用開銷降低。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM