最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【i.MX6ULL】驅(qū)動(dòng)開(kāi)發(fā)2——新字符設(shè)備開(kāi)發(fā)模板

2021-09-08 22:59 作者:碼農(nóng)愛(ài)學(xué)習(xí)-B站  | 我要投稿

上篇文章介紹了字符設(shè)備的開(kāi)發(fā)模板,但那是一種舊版本的驅(qū)動(dòng)開(kāi)發(fā)模式,設(shè)備驅(qū)動(dòng)需要手動(dòng)分配設(shè)備號(hào)再使用 register_chrdev進(jìn)行注冊(cè),加載成功以后還需要手動(dòng)使用mknod命令創(chuàng)建設(shè)備節(jié)點(diǎn),比較麻煩

目前Linux內(nèi)核推薦的新字符設(shè)備驅(qū)動(dòng)API函數(shù),使得驅(qū)動(dòng)的使用更加自動(dòng)化,本篇就來(lái)一起研究下。

1 舊字符設(shè)備驅(qū)動(dòng)的弊端

使用register_chrdev函數(shù)注冊(cè)字符設(shè)備,需要指定一個(gè)設(shè)備號(hào),這就造成:

  • 需要事先確定好哪些主設(shè)備號(hào)沒(méi)有使用

  • 會(huì)將一個(gè)主設(shè)備號(hào)下的所有次設(shè)備號(hào)都使用掉,比如主設(shè)備號(hào)為200,那么 0~1048575(2^20-1)這個(gè)區(qū)間的次設(shè)備號(hào)就全部都被占用了

回顧上一篇的操作,先是加載驅(qū)動(dòng):

加載完,還有手動(dòng)使用mknod指令來(lái)手動(dòng)創(chuàng)建該設(shè)備節(jié)點(diǎn),并且指定驅(qū)動(dòng)程序中寫(xiě)死的設(shè)備號(hào):

本篇,就要使用一種新的字符驅(qū)動(dòng)編寫(xiě)方式,實(shí)現(xiàn)設(shè)備號(hào)的自動(dòng)分配,省去mknod指令操作。

2 新字符設(shè)備驅(qū)動(dòng)原理

2.1 分配和釋放設(shè)備號(hào)

使用設(shè)備號(hào)的時(shí)候向Linux內(nèi)核申請(qǐng),需要幾個(gè)就申請(qǐng)幾個(gè),由Linux內(nèi)核分配設(shè)備可以使用的設(shè)備號(hào)。

使用如下函數(shù)來(lái)申請(qǐng)?jiān)O(shè)備號(hào)(該函數(shù)在上篇提到過(guò)):

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

如果給定了設(shè)備的主設(shè)備號(hào)和次設(shè)備號(hào)就使用如下所示函數(shù)來(lái)注冊(cè)設(shè)備號(hào)即可:

注銷(xiāo)字符設(shè)備之后要釋放設(shè)備號(hào),不管是通過(guò)alloc_chrdev_region函數(shù)的動(dòng)態(tài)分配還是register_chrdev_region函數(shù)手動(dòng)指定的設(shè)備號(hào),統(tǒng)一使用(和上篇使用的一樣)的釋放函數(shù):

新字符設(shè)備驅(qū)動(dòng)下,設(shè)備號(hào)分配示例代碼如下:

2.2 字符設(shè)備注冊(cè)

2.2.1 cdev字符設(shè)備結(jié)構(gòu)

在Linux中使用cdev結(jié)構(gòu)體表示一個(gè)字符設(shè)備,其定義在include/linux/cdev.h文件中:

2.2.2 cdev_init 函數(shù)

定義好cdev變量以后就要使用cdev_init函數(shù)對(duì)其進(jìn)行初始化:

該函數(shù)的使用示例如下:


2.2.3 cdev_add函數(shù)

該函數(shù)用于向Linux系統(tǒng)添加字符設(shè)備,即cdev結(jié)構(gòu)體變量:

2.2.4 cdev_del函數(shù)

卸載驅(qū)動(dòng)的時(shí)候要使用cdev_del函數(shù)從Linux內(nèi)核中刪除字符設(shè)備:


2.3 自動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)

上篇的Linux驅(qū)動(dòng)實(shí)驗(yàn)中,在使用modprobe加載驅(qū)動(dòng)程序以后還需要使用“mknod”命令手動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn),比較麻煩,這里就來(lái)研究一下如何實(shí)現(xiàn)自動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)。

2.3.1 mdev機(jī)制

在Linux下通過(guò)udev來(lái)實(shí)現(xiàn)設(shè)備文件的自動(dòng)創(chuàng)建與刪除。使用busybox構(gòu)建根文件系統(tǒng)的時(shí)候,busybox會(huì)創(chuàng)建一個(gè)udev的簡(jiǎn)化版本mdev。

所以,在嵌入式開(kāi)發(fā)中使用mdev來(lái)實(shí)現(xiàn)設(shè)備節(jié)點(diǎn)文件的自動(dòng)創(chuàng)建與刪除。Linux系統(tǒng)中的熱插拔事件也由mdev 管理,在/etc/init.d/rcS 文件中如下語(yǔ)句:

echo /sbin/mdev > /proc/sys/kernel/hotplug

2.3.2 創(chuàng)建和刪除類(lèi)

自動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)的工作是在驅(qū)動(dòng)程序的入口函數(shù)中完成的,一般在cdev_add函數(shù)后面添 加自動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)相關(guān)代碼。

首先要創(chuàng)建一個(gè)class類(lèi),其實(shí)是個(gè)結(jié)構(gòu)體,定義在include/linux/device.h里面。class_create是類(lèi)創(chuàng)建函數(shù)(宏定義):

卸載驅(qū)動(dòng)程序的時(shí)候需要使用函數(shù)為class_destroy刪除掉類(lèi)


2.3.3 創(chuàng)建設(shè)備

創(chuàng)建好類(lèi)以后還不能實(shí)現(xiàn)自動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn),還需要在這個(gè)類(lèi)下創(chuàng)建一個(gè)設(shè)備。使用device_create函數(shù)創(chuàng)建設(shè)備:

參數(shù)最后的...表示這在是一個(gè)可變參數(shù)的函數(shù)。

2.4 設(shè)置文件私有數(shù)據(jù)

每個(gè)硬件設(shè)備都有一些屬性, 比如主設(shè)備號(hào)(dev_t),類(lèi)(class)、設(shè)備(device)、開(kāi)關(guān)狀態(tài)(state)等等,在編寫(xiě)驅(qū)動(dòng)的時(shí)候你可以將這些屬性全部寫(xiě)成變量的形式:

可以將所有屬性信封裝到結(jié)構(gòu)體中, 并在編寫(xiě)驅(qū)動(dòng)open函數(shù)的時(shí)候?qū)⑵渥鳛樗接袛?shù)據(jù)添加到設(shè)備文件中:

3 驅(qū)動(dòng)程序編寫(xiě)

在上篇的基礎(chǔ)上進(jìn)行修改,因?yàn)橹皇歉鼡Q的驅(qū)動(dòng)程序的編寫(xiě)方式,與應(yīng)用程序無(wú)關(guān),因此只修改驅(qū)動(dòng)程序即可。

3.1 添加一些定義

因?yàn)樯掀恼碌拇a中使用的是chrdevbase這個(gè)名稱(chēng),為了減少修改量,這里僅把結(jié)構(gòu)體類(lèi)型定義為帶有new標(biāo)志的newchr_dev,變量名仍使用chrdevbase這個(gè)名稱(chēng)。


struct newchr_dev chrdevbase; /* 自定義字符設(shè)備 */

3.2 修改open函數(shù)

在上篇程序的基礎(chǔ)上增加了一條“設(shè)置私有數(shù)據(jù)”

3.3 修改init函數(shù)

這個(gè)修改比較大,因?yàn)橐趇nit函數(shù)中使用設(shè)備號(hào)的自動(dòng)分配。

3.4 修改exit函數(shù)

因?yàn)閕nit修改較大,對(duì)應(yīng)的exit也要進(jìn)行大的修改:

至此,修改完畢,其它的與之前的一樣。

3.5 新舊驅(qū)動(dòng)方式對(duì)比

通過(guò)一張圖來(lái)對(duì)比新舊兩種驅(qū)動(dòng)編寫(xiě)方式的區(qū)別

  • 舊方式編寫(xiě)驅(qū)動(dòng)的流程

  • 新方式編寫(xiě)驅(qū)動(dòng)的流程

可以看出主要區(qū)別在驅(qū)動(dòng)的加載和卸載。

4 編譯驅(qū)動(dòng)

和上次編譯驅(qū)動(dòng)的方式一樣,使用makefile,因?yàn)轵?qū)動(dòng)的c文件名由chrdevbase.c改為了newchrdevbase.c,因此makefile文件中也要把名字改掉。

編譯完之后,將編譯出的ko文件先復(fù)制到ubuntu虛擬機(jī)的tftpboot目錄中,為后面的測(cè)序做準(zhǔn)備。

復(fù)制后,看一下tftpboot目錄:

5 程序測(cè)試

5.1 文件發(fā)送到板子

和上篇一樣,使用tftp傳輸,將ubuntu虛擬機(jī)編譯出的ko文件發(fā)送到linux板子中

再來(lái)看下tftp傳輸?shù)挠布h(huán)境示意圖:

然后是傳輸指令以及傳輸結(jié)果,可以看到newchrdevbase.ko已經(jīng)從ubuntu虛擬機(jī)的tftpboot目錄傳輸?shù)搅薼inux板子的/lib/modules/4.1.15目錄中了。

5.2 測(cè)試

輸入如下兩條指令加載 newchrdevbase.ko 驅(qū)動(dòng)模塊:

depmod ? //第一次加載驅(qū)動(dòng)的時(shí)候需要運(yùn)行此命令 ?modprobe newchrdevbase.ko ? //加載驅(qū)動(dòng)

驅(qū)動(dòng)加載成功后,可以看到自動(dòng)申請(qǐng)到的主設(shè)備號(hào)和次設(shè)備號(hào),如下圖,主設(shè)備號(hào)為249。

再輸入ls /dev/chrdevbase -l指令驗(yàn)證/dev/chrdevbase 這個(gè)設(shè)備節(jié)點(diǎn)文件是否存在,如下圖,可以看到設(shè)備存在,注意和上篇舊驅(qū)動(dòng)方式操作上的不同之處,舊的驅(qū)動(dòng)方式需要額外使用mknod指令來(lái)手動(dòng)創(chuàng)建該設(shè)備節(jié)點(diǎn)。

驅(qū)動(dòng)已經(jīng)加載成功,再來(lái)測(cè)試APP程序,理論上和上篇的效果一樣,實(shí)測(cè)也是:

OK,測(cè)試完畢,測(cè)試完使用rmmod指令卸載驅(qū)動(dòng)。

6 總結(jié)

此篇文章針對(duì)上篇文章使用舊字符驅(qū)動(dòng)編寫(xiě)方式存在的不足,介紹了一種新的字符驅(qū)動(dòng)編寫(xiě)方式,對(duì)比兩種方式編寫(xiě)的主要區(qū)別,在上篇驅(qū)動(dòng)代碼的基礎(chǔ)上進(jìn)行修改,并測(cè)試通過(guò),和上篇實(shí)現(xiàn)一樣的效果,但驅(qū)動(dòng)的加載更加方便,不再需要人為指定設(shè)備號(hào)。



【i.MX6ULL】驅(qū)動(dòng)開(kāi)發(fā)2——新字符設(shè)備開(kāi)發(fā)模板的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
治县。| 鹤山市| 公主岭市| 平潭县| 肃宁县| 凌源市| 齐齐哈尔市| 德江县| 霍山县| 杭锦旗| 昌都县| 卓尼县| 扎鲁特旗| 东丰县| 博客| 小金县| 萍乡市| 蒙城县| 黎平县| 蓬莱市| 塘沽区| 额济纳旗| 济源市| 江城| 二手房| 三原县| 武川县| 潮安县| 通道| 松阳县| 龙川县| 安义县| 扬中市| 眉山市| 灵台县| 定陶县| 芒康县| 陵川县| 琼海市| 平定县| 凤冈县|