天天看點

【linux】驅動-14-異步通知

目錄

前言

14. 異步通知

14.1 異步通知的一些概念

14.2 Linux 信号

14.3 信号接收

14.4 使用流程

14.4.1 參考流程圖

14.4.2 分析&程式設計步驟

14.4.3 使用函數說明

14.4.3.1 相關結構體及參考模型

14.4.3.2 signal 函數

14.4.3.3 kill_fasync 函數

本章内容為驅動基石之一。

驅動隻提供功能,不提供政策。

阻塞與非阻塞是 APP 詢問 驅動裝置。

異步通知是 驅動裝置 主動通知 APP。

原文:https://www.cnblogs.com/lizhuming/p/14918049.html

異步通知:一旦裝置就緒,則主動通知APP,這樣APP就不用輪詢查詢裝置狀态了。

異步IO:APP 發起 IO 請求後,立即傳回。然後再查詢 IO 完成情況,或者 IO 完成後被調回。這個過程叫做 異步IO。

可以使用 信号 來進行程序間通信(IPC)。

Linux信号表:

路徑參考:include\uapi\asm-generic\signal.h

信号

說明

SIGHUP

1

挂起

SIGINT

2

中斷中斷

SIGQUIT

3

終端退出

SIGILL

4

無效指令

SIGTRAP

5

跟蹤陷阱

SIGABRT

6

異常終止信号,和 SIGIOT 同義

SIGIOT

IOT陷阱,和 SIGABRT 同義

SIGBUS

7

BUS錯誤

SIGFPE

8

浮點異常

SIGKILL

9

強制終止

SIGUSR1

10

使用者自定義信号1

SIGSEGV

11

無效的記憶體段處理

SIGUSR2

12

使用者自定義信号2

SIGPIPE

13

半關閉管道的寫操作

SIGALRM

14

計時器到期

SIGTERM

15

終止

SIGSTKFLT

16

堆棧錯誤

SIGCHLD

17

子程序已經停止或退出

SIGCONT

18

如果停止了,繼續執行

SIGSTOP

19

停止執行

SIGTSTP

20

終端停止信号

SIGTTIN

21

背景程序需要從終端讀取輸入

SIGTTOU

22

背景程序需要從終端寫出

SIGURG

23

緊急的套接字事件

SIGXCPU

24

超額使用CPU配置設定的時間

SIGXFSZ

25

檔案尺寸超額

SIGVTALRM

26

虛拟時鐘信号

SIGPROF

27

時鐘信号描述

SIGWINCH

28

出口尺寸變化

SIGIO

29

I/O

SIGPOLL

除了 SIGSTOP 和 SIGKILL 兩個信号外,程序能夠忽略或捕獲其它所有信号。

一個信号被捕獲的意思是當一個信号到達時有相應代碼處理它。

如果一個信号沒有被這程序所捕獲,核心将采取預設行為處理。

流程圖參考韋東山:

【linux】驅動-14-異步通知

分析中的細節部分會在後本節後面說明

分析:

②:綁定信号與回調函數。使用<code>sighandler_t signal(int signum, sighandler_t handler)</code> 。

③:把 APP PID 告訴核心。同時,該 PID 會儲存到該驅動的核心檔案 file 結構體中。

④:讀取該驅動程式檔案的 Flag。

⑤:設定 Flag 裡面的 FASYNC 位為 1。當 FASYNC 位發生變化時,該驅動會調用驅動操作 <code>drv_fasync</code> 函數。

⑥:驅動開發者實作的函數。主要是調用 fasync_helper 函數。

⑦:調用 fasync_helper() 函數,主要是把 驅動程式核心檔案 file 結構體綁定到 button_async-&gt;fa_file 中。而 file 包含了 APP 的 PID。是以發送信号時,隻需要使用 button_async 作為參數即可。

⑩:發送信号給對應的 APP。參數為 button_async。

注:button_async 結構體由驅動開發者建立,維護。

APP 信号程式設計步驟:

①:編寫信号回調函數。

②:綁定信号與回調函數。

③:打開驅動。

④:擷取 PID ,告知核心。

⑤:擷取程序狀态值。

⑥:目前狀态值添加異步功能,觸發調用驅動異步處理函數。

KERNEL 信号程式設計步驟:

①:定義異步結構體。

②:實作異步操作函數,并把該函數填充到裝置核心驅動操作結構體中。

該函數内容主要調用 fasync_helper() 函數,初始化異步結構體。(把 file ,核心PID,交給異步結構體)

③:發送信号。

APP 模型 截段:

fasync_struct:

(在核心源碼中,目前沒有去找核心文檔該結構體内容的相關資訊)

APP 使用。

函數原型:<code>sighandler_t signal(int signum, sighandler_t handler)</code> :

功能:綁定信号與回調函數。

signum:信号類型。除 SIGKILL 和 SIGSTOP 外的任何一種信号。

handler:該參數有三種類型。

①:SIG_IGN 類型。表示忽略該信号。

②:SIG_DFL 類型。表示恢複對信号的系統預設處理。

③:sighandler_t 類型的函數指針。即是回調函數。<code>typedef void (*sighandler_t)(int);</code> 。

注:APP 收到信号執行回調函數時,signum 參數會被傳到回調函數的形參傳遞給回調函數。即是回調函數的形參就是信号類型。

KERNEL 使用。

函數原型:<code>void kill_fasync(struct fasync_struct **fp, int sig, int band)</code> :

功能:發送信号給 fp 參數綁定的程序。(by PID)

參考路徑:linux-5.12.8\fs\fcntl.c

fp:需要操作的 fasync_struct。

sig:信号類型。

band:可讀時設定為 POLL_IN;可寫時設定為 POLL_OUT。當然該參數還可以填

POLL_MSG。以上三個值在應用層接收時,si_code 分别為 0x01、0x02、0x03。

繼續閱讀