<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Linux字符設備驅動實例

          共 4470字,需瀏覽 9分鐘

           ·

          2020-12-27 10:21


          globalmem

          linux 設備驅動開發(fā)詳解時,字符設備驅動一章,寫的測試代碼和應用程序,加上自己的操作,對初學者我覺得非常有幫助。

          寫這篇文章的原因是因為我看了我之前發(fā)表的文章,還沒有寫過字符設備相關的,至于里面提到的結構體的作用,有很多詳細的文章說明,我就不做更深的敘述。

          代碼在github上,點擊下面閱讀原文可以直達

          https://github.com/weiqifa0/globalmem/blob/main/README.md

          把這部分放在github上也有好處,后續(xù)可以增加刪除一些東西,以后自己需要使用的時候也方便許多。


          我們討論字符設備驅動,就有必要知道他的結構體和頭文件,像一些后來的封裝什么的,大部分還是脫離不了操作這個結構體里面的東西。


          /*?SPDX-License-Identifier:?GPL-2.0?*/
          #ifndef?_LINUX_CDEV_H
          #define?_LINUX_CDEV_H

          #include?
          #include?
          #include?
          #include?

          struct?file_operations;
          struct?inode;
          struct?module;

          struct?cdev?{
          ?struct?kobject?kobj; /*內嵌kobject結構體,方便以后應用,也會在sys下生成相關設備文件*/
          ?struct?module?*owner;/*所屬于的模塊,正常就是本模塊THIS_MODULE*/
          ?const?struct?file_operations?*ops;/*文件的操作結構體,設備也是一個文件*/
          ?struct?list_head?list;/*字符設備的鏈表頭*/
          ?dev_t?dev;/*設備號*/
          ?unsigned?int?count;
          }?__randomize_layout;
          /*初始化cdev,并建立和file_operation的聯(lián)系*/
          void?cdev_init(struct?cdev?*,?const?struct?file_operations?*);
          /*申請cdev內存*/
          struct?cdev?*cdev_alloc(void);

          void?cdev_put(struct?cdev?*p);

          int?cdev_add(struct?cdev?*,?dev_t,?unsigned);

          void?cdev_set_parent(struct?cdev?*p,?struct?kobject?*kobj);
          int?cdev_device_add(struct?cdev?*cdev,?struct?device?*dev);
          void?cdev_device_del(struct?cdev?*cdev,?struct?device?*dev);

          void?cdev_del(struct?cdev?*);

          void?cd_forget(struct?inode?*);

          #endif



          加載內核模塊insmod globalmem.ko 錯誤需要的修改。

          insmod: can't insert 'globalmem.ko': Device or resource busy


          出錯的原因:

          模塊使用的是靜態(tài)分配設備號的方式,而這個設備號已經被系統(tǒng)中的其他設備所占用。查看未被占用的設備號,需要到pro/devices下面去查看。

          查看設備號的方法:

          # cat /proc/devices


          編譯內核版本

          #uname?-a
          Linux?bsp-ubuntu1804?4.15.0-117-generic?#118-Ubuntu?SMP?Fri?Sep?4?20:02:41?UTC?2020?x86_64?x86_64?x86_64?GNU/Linux

          加載模塊之后使用lsmod查看模塊

          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?insmod?globalmem.koweiqifa@bsp-ubuntu1804:~/c/globalmem$?lsmod?|grep?global
          globalmem??????????????16384??0
          weiqifa@bsp-ubuntu1804:~/c/globalmem$

          weiqifa@bsp-ubuntu1804:~/c/globalmem$?cat?/proc/devices?|grep?global
          230?globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$

          創(chuàng)建設備文件節(jié)點

          使用mknod創(chuàng)建設備節(jié)點的時候,后面跟上的參數需要跟我們在/proc/devices下面看到的對應,也就是我們在驅動里面申請的主設備號。

          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?mknod?/dev/globalmem?c?230?0
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?ls?/dev/globalmem?-al
          crw-r--r--?1?root?root?230,?0?Dec?22?16:19?/dev/globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$

          使用命令讀寫設備文件

          Linux 下的 echo 和cat 命令是十分有用,這兩個命令可以讓在不寫代碼的情況下就可以完成調試讀寫設備。

          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?chmod?777?/dev/globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?echo?"linux"?>?/dev/globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?cat?/dev/globalmem
          linux
          cat:?/dev/globalmem:?No?such?device?or?address
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?cat?/dev/globalmem
          linux
          cat:?/dev/globalmem:?No?such?device?or?address
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?echo?"linuxgdb"?>?/dev/globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?cat?/dev/globalmem
          linuxgdb
          cat:?/dev/globalmem:?No?such?device?or?address
          weiqifa@bsp-ubuntu1804:~/c/globalmem$

          通過代碼來讀寫設備文件

          代碼在下面閱讀原文的鏈接里面。

          weiqifa@bsp-ubuntu1804:~/c/globalmem$?gcc?app-main.c?&&?./a.out
          str:LINUX,GDB
          weiqifa@bsp-ubuntu1804:~/c/globalmem$

          使用傳入參數設置主設備號

          內核模塊參數我覺得是一個比較冷門的知識點,冷門的原因是因為我們在做項目的時候很少使用這個參數,但是實際上這個參數非常有用。


          我們可以把內核模塊當做main函數,main函數是可以接收傳參的,內核模塊也可以在加載的時候接收傳入的參數。


          如下是把主設備號傳給內核模塊,但是需要注意,這個主設備號不能被占用了。


          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?insmod?globalmem.ko?globalmem_major=231
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?cat?/proc/devices?|grep?globalmem
          231?globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$

          增加自動創(chuàng)建設備節(jié)點的驅動文件

          每次手動創(chuàng)建設備文件節(jié)點總是很麻煩,而且在實際編寫設備驅動的時候,不會出現自己手動創(chuàng)建設備節(jié)點這種低端的操作。


          當然了,聰明的內核提供了接口讓我們在注冊驅動的時候也把設備文件節(jié)點注冊上去。


          具體代碼可以查看globalmem2.c里面的代碼。

          weiqifa@bsp-ubuntu1804:~/c/globalmem$?chmod?777?globalmem.ko
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?insmod?globalmem.ko
          [sudo]?password?for?weiqifa:
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?ls?/dev/globalmem
          /dev/globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?ls?/dev/globalmem?-al
          crw-------?1?root?root?238,?0?Dec?22?17:18?/dev/globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$

          /*修改權限后才可以正常進行獨寫操作*/
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?sudo?chmod?777?/dev/globalmem
          weiqifa@bsp-ubuntu1804:~/c/globalmem$?gcc?app-main.c?&&?./a.out
          write?data?ok!
          str:LINUX,GDB
          weiqifa@bsp-ubuntu1804:~/c/globalmem$


          使用lseek操作文件位置

          具體對應的文件是app-main2.c

          weiqifa@bsp-ubuntu1804:~/c/globalmem$?gcc?app-main2.c?&&?./a.out
          file?ret:0
          write?data?ok!?fd:3
          str:123456789ABCDEF10111213141516171819201617181920
          lseek:1
          str:23456789ABCDEF10111213141516171819201617181920
          weiqifa@bsp-ubuntu1804:~/c/globalmem$




          推薦閱讀:
          專輯|Linux文章匯總
          專輯|程序人生
          專輯|C語言
          我的知識小密圈

          瀏覽 71
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色三级在线观看 | 国产精品第一页在线观看 | 亚洲欧洲a片 | 日韩AV中文 | 亚洲国产一级 |