Nod peranti Linux ialah jambatan antara aplikasi dan pemacu peranti; nod peranti dicipta dalam "/dev" dan merupakan hab yang menyambungkan kernel dan lapisan pengguna cakera dan rekod Lokasi dan maklumat peranti perkakasan. Nod peranti membenarkan pengguna berkomunikasi dengan kernel melalui perkakasan, membaca dan menulis peranti dan melakukan operasi lain.
Persekitaran pengendalian tutorial ini: sistem linux5.9.8, komputer Dell G3.
Apakah itu nod peranti
Jambatan komunikasi antara manusia ialah bahasa. Begitu juga, aplikasi dan pemacu peranti juga memerlukan jambatan untuk berkomunikasi. Jambatan ini ialah nod peranti.
Untuk sistem Linux, semua sumber IO ialah fail, termasuk fail, direktori, cakera keras, peranti, dsb. Nah, papan kekunci ialah peranti input dalam sistem komputer, dan sistem pengendalian juga mengabstrakkannya daripada fail Jika anda ingin mendapatkan input data oleh pengguna daripada papan kekunci, anda hanya perlu membaca nod peranti yang disediakan oleh papan kekunci .
Dalam sistem Linux, papan kekunci digunakan sebagai peranti input, dan nod peranti yang sepadan terletak di bawah "/dev/input". Terdapat banyak fail bermula dengan peristiwa dalam folder ini. Ini adalah nod peranti semua peranti input. Bagaimana untuk menentukan nod peranti mana yang merupakan papan kekunci? Sambungkan papan kekunci ke Raspberry Pi, buka terminal, jalankan "sudo cat /dev/input/event0", ketik papan kekunci, jika tiada output, tukar ke nod seterusnya sehingga anda menemui nod dengan output, kemudian nod ini ialah papan kekunci Nod peranti yang sepadan.
Nod peranti dibuat di bawah /dev dan merupakan hab yang menghubungkan kernel dan lapisan pengguna Ini bermakna peranti disambungkan kepada ID antara muka yang sepadan. Ia bersamaan dengan inod cakera keras dan merekodkan lokasi dan maklumat peranti perkakasan
Di Linux, semua peranti disimpan dalam direktori /dev dalam bentuk fail, semuanya dalam bentuk Untuk mengakses, nod peranti ialah abstraksi peranti oleh kernel Linux dan nod peranti ialah fail. Aplikasi mengakses peranti melalui set panggilan piawai yang bebas daripada mana-mana pemacu tertentu. Pemacu bertanggungjawab untuk memetakan panggilan standard ini kepada operasi khusus perkakasan sebenar.
Peranan nod peranti
Nod peranti membenarkan pengguna berkomunikasi dengan kernel melalui perkakasan, membaca dan menulis peranti serta melakukan operasi lain
dalam Linux Peranti wujud seperti fail biasa, dan mengakses peranti adalah seperti mengakses fail
Nombor peranti utama mewakili jenis peranti, dan nombor peranti kecil mewakili individu yang berbeza daripada jenis peranti yang sama yang Mungkin anda tidak tahu bentuk kewujudan nod peranti
Bentuk kewujudan nod peranti
Selain itu, terdapat satu lagi konsep dalam Linux iaitu inode dan blok, iaitu bahagian cakera keras dan nod Inod dalam cakera keras adalah bersamaan dengan fail atau folder . Contohnya, sesetengah sistem bersaiz 4K, dan inode Saiznya terhad, jadi ada pepatah bahawa satu fail tidak boleh melebihi 4G. Dalam pemahaman peribadi saya, nod dalam pemacu Linux boleh dianggap sebagai sesuatu yang serupa dengan inod cakera keras, yang boleh merekodkan lokasi peranti perkakasan dan maklumat lain, dan boleh digunakan apabila pengguna perlu mengaksesnya. Akses peranti dengan merujuk kepada maklumat yang direkodkan dalam nod peranti
Cara mendapatkan data daripada nod peranti
Sebab mengapa sistem pengendalian mengabstraksikan IO ke dalam fail ialah yang terbesar Kelebihannya ialah fail ini boleh diakses melalui antara muka bersatu untuk berkomunikasi dengan peranti yang berbeza. Antara muka bersatu ini ialah satu set panggilan sistem yang disediakan oleh sistem pengendalian untuk operasi fail: fungsi terbuka, fungsi baca, fungsi tulis, dsb. Sebagai contoh, jika anda perlu mendapatkan data daripada peranti, anda hanya perlu memanggil fungsi baca untuk membaca nod peranti yang sepadan dengan peranti Sudah tentu, sebelum membaca, anda mesti memanggil fungsi terbuka terlebih dahulu untuk membukanya. Sekarang mari kita ambil input papan kekunci sebagai contoh.
1 Buka nod peranti
Sebelum membaca data nod peranti, anda mesti memanggil fungsi terbuka untuk membuka nod peranti. Untuk penggunaan khusus fungsi terbuka, sila rujuk pautan. Penerangan ringkas adalah seperti berikut:
Pengisytiharan fungsi:
int open(const char *pathname, int flags);
Fail pengepala untuk disertakan:
#include <fcntl.h>
Parameter:
* pertama parameter (const char *pathname): Menunjukkan laluan fail yang perlu dibuka
* Parameter kedua (int flags): Menunjukkan cara untuk membuka fail, contohnya, "O_RDONLY" - baca sahaja terbuka; "O_WRONLY" - - Terbuka untuk menulis sahaja; "O_RDWR" - terbuka untuk membaca, menulis, dsb.
Nilai pulangan:
Jika pembukaan berjaya, deskriptor fail fail dikembalikan untuk digunakan oleh fungsi seperti baca dan tulis. Jika tidak, -1 dikembalikan.
Jadi, untuk membuka fail peranti papan kekunci (dengan andaian ia adalah "/dev/input/even10"), anda memerlukan kod berikut:
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 nod peranti
Membaca nod peranti memerlukan penggunaan fungsi baca Untuk kaedah penggunaan tertentu, sila rujuk pautan. Pengenalan ringkas adalah seperti berikut:
Pengisytiharan fungsi:
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。
这里需要理解的是:设备节点是设备驱动程序提供的,且设备节点的数据是设备驱动写入的,而且写入时,是以上述结构的规则写入的,这是双方通过
* 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视频教程》
Atas ialah kandungan terperinci apakah nod peranti linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!