久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

linux設備節點的概念是什么

150次閱讀
沒有評論

共計 3606 個字符,預計需要花費 10 分鐘才能閱讀完成。

這篇文章主要介紹了 linux 設備節點的概念是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇 linux 設備節點的概念是什么文章都會有所收獲,下面我們一起來看看吧。

linux 設備節點是應用程序和設備驅動程序溝通的一個橋梁;設備節點被創建在“/dev”,是連接內核與用戶層的樞紐,相當于硬盤的 inode 一樣的東西,記錄了硬件設備的位置和信息。設備節點使用戶可以與內核進行硬件的溝通,讀寫設備以及其他的操作。

本教程操作環境:linux5.9.8 系統、Dell G3 電腦。

什么是設備節點

人和人之間溝通橋梁是語言。同樣,應用程序和設備驅動程序溝通也需要一個橋梁。這個橋梁就是設備節點。

對于 Linux 系統,所有的 IO 資源都是文件,包括文件、目錄、硬盤、設備等。那么,鍵盤作為計算機系統中的一款輸入設備,操作系統同樣也把它抽象了文件,要想獲取用戶從鍵盤上輸入的數據時,只需要讀取鍵盤提供的設備節點即可。

在 Linux 系統中,鍵盤作為輸入設備,其對應的設備節點位于”/dev/input“下。在這個文件夾下有很多以 event 打頭的文件,這些就是所有 input 設備的設備節點。如何確定哪個是鍵盤的設備節點呢?將鍵盤連接到樹莓派上,打開終端,執行“sudo cat /dev/input/event0”,敲擊鍵盤,如果沒有輸出,就換下一個節點,直到找到有輸出的節點,那這個節點就是鍵盤對應的設備節點。

設備節點被創建在 /dev 下,是連接內核與用戶層的樞紐,就是設備是接到對應哪種接口的哪個 ID 上。相當于硬盤的 inode 一樣的東西,記錄了硬件設備的位置和信息

在 Linux 中,所有設備都以文件的形式存放在 /dev 目錄下,都是通過文件的方式進行訪問,設備節點是 Linux 內核對設備的抽象,一個設備節點就是一個文件。應用程序通過一組標準化的調用執行訪問設備,這些調用獨立于任何特定的驅動程序。而驅動程序負責將這些標準調用映射到實際硬件的特有操作。

設備節點的作用

設備節點使得用戶可以與內核進行硬件的溝通,讀寫設備以及其他的操作

在 linux 里面設備就像是普通文件一樣的存在,訪問一個設備就好像是訪問一個文件一樣

主設備號代表著一類設備,次設備號代表著同一類設備的不同個體,說到這里也許并不知道設備節點的存在形式

設備節點的存在形式

另外在 linux 里面還有一個概念,就是 inode 與 block,也就是硬盤一面的塊與節點,硬盤里面的 inode 就相當于一個文件或者文件夾,它記錄下此文件下面的文件位置所在,文件的位置是以 block 大小對齊的,例如有些系統就是 4K 的大小,而 inode 的大小是有限的,所以就有了單個文件不能超過 4G 的說法。而在 linux 的驅動程序里面的節點在我個人的理解也可以看做是一個類似于硬盤的 inode 一樣的東西,里面可以記錄硬件設備的位置以及別的一些信息,在用戶需要進行訪問的時候就參照到設備節點所記錄的信息進行設備的訪問

如何從設備節點中獲取數據

操作系統之所以把 IO 都抽象成了文件,最大的好處就是可以通過統一的接口來訪問這個文件,從而和不同的設備溝通。這些統一的接口就是操作系統針對文件操作對外提供的一組系統調用:open 函數、read 函數、write 函數等。比如,如果需要從一個設備中獲取數據,只需要調用 read 函數去讀取該設備對應的設備節點就可以了,當然在 read 之前,要先調用 open 函數打開。現在以獲取鍵盤輸入為例來介紹。

1、打開設備節點

在讀取設備節點的數據之前,要先調用 open 函數打開設備節點。open 函數的具體用法可以參考鏈接。簡單描述如下:

函數聲明:

int open(const char *pathname, int flags);

需要包含的頭文件:

#include  fcntl.h

參數:

* 第一個參數(const char *pathname):表示需要打開的文件路徑

* 第二個參數(int flags):表示打開文件的方式,比如,”O_RDONLY”——只讀打開;”O_WRONLY”——只寫打開;”O_RDWR”——讀、寫打開,等。

返回值:

如果打開成功,則返回該文件的文件描述符,以供 read,write 等函數使用。否則,返回 -1。

那么,要打開鍵盤的設備文件(假設是”/dev/input/even10“), 則需要以下代碼:

 int keys_fd;
 keys_fd = open(/dev/input/even10 , O_RDONLY);
 if(keys_fd  = 0)
 {
 printf( open /dev/input/event10 device error!\n 
 return -1;
 }

2、讀取設備節點的數據

讀取設備節點需要使用 read 函數,具體使用方法可以參考鏈接。簡單介紹如下:

函數聲明:

ssize_t read(int fd, void *buf, size_t count);

需要包含的頭文件:

#include  unistd.h

參數:

* 第一個參數(int fd):要打開文件的文件描述符,來源一般是上述 open 函數的返回值。

* 第二個參數(void *buf):讀取到的數據存放的起始位置指針

* 第三個參數(size_t count):要讀取的數據字節數

返回值:

* 如果讀取成功,則返回實際讀取到的字節數

* 如果讀取失敗,則返回 -1

* 如果返回值小于第三個參數 count,則表示已經讀取到文件結尾,返回值表示實際讀取的字節數。

在讀取鍵盤的例子中,我們循環讀取鍵盤設備的文件節點,并將設備保存到一個 char buf[24] 的數組中去。具體代碼如下:

char buf[24];
while(1)
 if(read(keys_fd, buf, 24) == 24)
 {
 //  成功的從設備節點中獲取到了 24 個字節
 ...
 }
}

根據 read 函數用法,當要讀取 24 個字節,且 read 函數的返回值是 24 時,表示成功的從設備節點中獲取到了 24 個字節。

3、分析從設備節點獲取的數據

為什么這里要從鍵盤的設備驅動獲取 24 個字節呢?這是因為正常情況下,從鍵盤設備節點獲取的數據實際上是一個 struct input_event 結構。其定義為:

struct input_event {
 struct timeval time;
 __u16 type;
 __u16 code;
 __s32 value;
};

顯然,上述結構體的大小為 24。

這里需要理解的是:設備節點是設備驅動程序提供的,且設備節點的數據是設備驅動寫入的,而且寫入時,是以上述結構的規則寫入的,這是雙方通過 linux/input.h 約定好的,那么應用程序去設備節點中讀取數據之后,也需要按照上述結構去解析數據。那這個結構具體是什么意思呢?

* struct timeval time:其大小為 16 個字節,具體意義暫時不考慮。

* __u16 type:其大小為 2 個字節,表示 input 設備的類型,比如:EV_KEY 表示上報的是鍵盤類型的數據,EV_REL 表示相對路徑,鼠標就屬于這種類型,還是其他等等。

* __u16 code:其大小為 2 個字節,表示事件的代碼。比如,如果 type 為 EV_KEY,那么該代碼 code 為設備鍵盤代碼。code 值實際上是應用程序和驅動程序約定好的一些固定的值,它可取的值位于 include/uapi/linux/input-event-codes.h 中。舉例來講,根據 Linux 源碼下的 include/uapi/linux/input-event-codes.h 文件的第 91 行 #define KEY_Q 16,如果鍵盤上按下或松開了 Q 鍵,那么鍵盤的驅動程序上報的 code 值應該是 16;反之,如果應用程序獲取到的值是 19,那么,表示用戶按下或松開了鍵盤上的 Q 鍵。

* __s32 value:其大小為 4 個字節,事件的值。如果事件的類型代碼是 EV_KEY,當按鍵按下時值為 1,松開時值為 0;

根據上述解釋,我們可以添加以下代碼來解析從設備節點中獲取的數據。

if(t.type == EV_KEY) //  我們只關心 input event 類型為 EV_KEY(按鍵)的消息
 if(t.value == 0 || t.value == 1)
 {
 printf( key %d %s\n , 
 t.code, // t.code 表示按下或松開了哪個按鍵
 (t.value) ?  Pressed  :  Released  // t.value 表示按下還是松開了相應的按鍵
 }

4、關閉設備節點

在從設備節點獲取數據完成后,務必調用 close 函數,來關閉設備節點。即

close(keys_fd);

關于“linux 設備節點的概念是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“linux 設備節點的概念是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-03發表,共計3606字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 城口县| 延长县| 高阳县| 衡阳市| 三明市| 礼泉县| 湖口县| 崇义县| 错那县| 冷水江市| 丰镇市| 明溪县| 茶陵县| 夏津县| 遂昌县| 金湖县| 阳新县| 盘山县| 瑞金市| 犍为县| 桃园县| 容城县| 遵化市| 抚宁县| 遂平县| 宝丰县| 焉耆| 祁连县| 太原市| 景德镇市| 防城港市| 甘德县| 荔波县| 天柱县| 西乌| 永兴县| 雅安市| 申扎县| 肇源县| 汪清县| 福海县|