<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • linux字符設備驅動流程圖(編寫字符設備驅動程序)


    Linux字符設備驅動框架

    1. 設備號

    Linux內核中有很多的字符設備驅動,內核是如何區分它們的? 每個字符設備都有一個唯一的標識 – 設備號,設備號的本質: 32位的無符號整數(dev_t)。

    設備號由兩部分組成:

    1 – 高12位稱為主設備號,表明這個設備屬于哪一類設備。

    2 – 低20位成為次設備號,表明這個設備是同類設備中的具體哪一個。

    設備號的申請方法:

    第一種方法:靜態定義并注冊設備號

    首先查看系統中有哪些設備號沒有被分配給具體的設備,然后確定一個給當前的設備使用(cat /proc/devices可以看哪些號被占用了),定義方法如下:

    dev_t devno = 主設備號<<20 | 次設備號;

    或者使用系統接口進行組合

    如何寫一個最簡單的Linux字符設備驅動?

    注冊設備號 – 使申請的設備號生效并保證設備號在Linux內核中的唯一性,使用下面的接口:

    如何寫一個最簡單的Linux字符設備驅動?

    from: 要注冊的設備號

    count:要注冊多少個設備號,例如count = 3, 主設備號是255, 次設備號是0,那么將按照順序依次注冊三個設備號,分別是(主:255,從:0)、(255,1)、(255,2)

    name:給要注冊的設備命名,注冊成功可以通過cat /proc/devices查看到

    第二種方法:動態申請并注冊設備號

    此方法無需自己去確定哪個設備號可用,內核會查詢哪個設備號沒有被使用,然后分配給當前驅動進行注冊,所以大部分驅動都采用這種注冊方法,使驅動更加具有通用性(如果用靜態注冊,你選的設備號在當前設備上沒有使用,但是當這個驅動移植到其他的設備上,可是其他設備上的某個驅動也使用的這個這個設備號,那么這個驅動就會注冊失敗)。

    如何寫一個最簡單的Linux字符設備驅動?

    功能:申請一個或多個設備號并進行注冊

    dev:要注冊的設備的設備號,輸入參數,內核會尋找沒有使用的設備號,然后填充到這個dev參數中。

    baseminor:主設備號由內核來確定,次設備號由我們自己去確定,baseminor就對應要申請的設備號的次設備號。

    count:可以一次申請多個設備號,count表示要申請的設備號的數量,當申請多個設備號時,他們的主設備號一致,次設備號會在baseminor的基礎上依次加1。

    name:要注冊的設備的名字,注冊成功可以通過cat /proc/devices查看到

    最后,無論通過哪種方式注冊的設備號,在卸載模塊的時候都需要將注冊的設備號資源進行釋放:

    如何寫一個最簡單的Linux字符設備驅動?

    from:要釋放的設備號

    count:要一次釋放的設備號的數量,當釋放多個設備號時,系統會從from開始,依次加1作為新的設備號進行釋放

    2. 字符設備操作集合 – file_operations結構體

    設備驅動有各種各樣的, 鼠標驅動需要獲取用戶的坐標以及單雙擊動作、LCD驅動需要寫framebuffer等等,但是對上層開發調用這些驅動的人來說,他們可能不懂也不關心底層設備是如何工作的,為了簡化上層應用的操作,驅動程序給上層提供了統一的操作接口–open、read、write等,這樣,對應做應用開發的人來說,不管你是什么樣的設備,我只需要去打開(open)你這個設備,然后進行讀寫等操作就可以操作這個設備了。那么,驅動程序如何實現這樣統一的接口呢?需要實現下面的file_operations結構體:

    如何寫一個最簡單的Linux字符設備驅動?

    這里只列出了幾個最基本的成員:

    owner:一般填充THIS_MODULE,表示這個驅動(模塊)歸自己所有(這個概念對于初學者可能難以理解,到后面我會繼續說明)

    open:打開設備驅動的函數指針

    release:關閉設備驅動的函數指針,為了對每個設備驅動的訪問保護,所以用戶必須先打開設備,才能對設備進行讀寫等操作,操作完必須再關掉。

    read:讀設備驅動的函數指針(比如用戶可以通過read接口讀取按鍵驅動的按鍵狀態等)

    write:寫設備驅動的函數指針(比如用戶可以通過write接口寫LCD驅動的framebuffer顯存,將畫面顯示再lcd上)

    用法:

    定義一個屬于自己設備的操作集合xxx_fops,xxx通常命名為設備的名字,例如lcd_fops, key_fops等。

    如何寫一個最簡單的Linux字符設備驅動?

    3. 字符設備的核心 – cdev結構體

    分配、設置、注冊cdev結構體

    內核用cdev結構體來表示一個字符設備,所以每個字符設備驅動,都需要注冊一個cdev結構體。

    如何寫一個最簡單的Linux字符設備驅動?

    owner:一般填充THIS_MODULE,表示這個驅動(模塊)歸自己所有。

    ops:對應這個設備的文件操作集合。

    list:內核中有很多字符設備,每個設備對應一個自己的cdev,這些cdev通過這個list連在一起,當注冊一個新的cdev時,就會通過cdev里面的list掛到內核的cdev鏈表上。

    count:同類設備,可以一次注冊多個cdev,但是他們的操作方法(fops)是一樣的,比如usb設備,多個usb共用一套操作方法(fops),但是每個usb都有自己的cdev。

    如何寫一個最簡單的Linux字符設備驅動?

    注冊cdev結構體 – 添加一個字符設備(cdev)到系統中:

    如何寫一個最簡單的Linux字符設備驅動?

    有注冊同樣也有釋放:

    如何寫一個最簡單的Linux字符設備驅動?

    最后的代碼

    如何寫一個最簡單的Linux字符設備驅動?
    如何寫一個最簡單的Linux字符設備驅動?
    如何寫一個最簡單的Linux字符設備驅動?

    Makefile:

    如何寫一個最簡單的Linux字符設備驅動?

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费