鎮(zhèn)江網(wǎng)站建設(shè) 的公司熱點(diǎn)新聞事件
一、前言
打開(kāi)文件是Linux系統(tǒng)中最基本的操作之一,open
函數(shù)可以實(shí)現(xiàn)打開(kāi)文件的功能。下面我將為您介紹open
函數(shù)打通上層到底層硬件的詳細(xì)過(guò)程。
二、open函數(shù)打通軟硬件介紹
open
函數(shù)是系統(tǒng)調(diào)用中的一種,其原型定義在頭文件unistd.h
中:
#include <unistd.h>int open(const char *pathname, int flags, mode_t mode);
其中,pathname
參數(shù)是要打開(kāi)的文件名,flags
參數(shù)是打開(kāi)文件時(shí)的標(biāo)志,mode
參數(shù)是文件的訪問(wèn)權(quán)限。
當(dāng)應(yīng)用程序調(diào)用open
函數(shù)時(shí),該函數(shù)首先會(huì)在內(nèi)存中創(chuàng)建一個(gè)file
結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體表示應(yīng)用程序和文件之間的連接,其中包含了文件的各種屬性,例如文件類型、文件訪問(wèn)權(quán)限、文件長(zhǎng)度等等。這個(gè)file
結(jié)構(gòu)體通常被稱為文件句柄(file handle
)或文件描述符(file descriptor
),用一個(gè)整數(shù)來(lái)表示,該整數(shù)被賦予一個(gè)非負(fù)值。
接著,open
函數(shù)會(huì)調(diào)用文件系統(tǒng)的VFS(Virtual File System
)層,VFS層是Linux文件系統(tǒng)的核心部分,其作用是將文件系統(tǒng)的各種實(shí)現(xiàn)細(xì)節(jié)隱藏起來(lái),為上層應(yīng)用程序提供一個(gè)統(tǒng)一的接口。VFS層通過(guò)查找文件系統(tǒng)的超級(jí)塊(super block
)來(lái)確定文件的類型和位置,并找到相應(yīng)的文件系統(tǒng)對(duì)象(inode
)。
VFS層在找到文件系統(tǒng)對(duì)象后,會(huì)通過(guò)驅(qū)動(dòng)程序中的文件操作函數(shù)(file operations
)實(shí)現(xiàn)文件的打開(kāi)操作,這些函數(shù)通常包括open
、read
、write
、lseek
、ioctl
等等。驅(qū)動(dòng)程序的文件操作函數(shù)被定義在一個(gè)結(jié)構(gòu)體中,這個(gè)結(jié)構(gòu)體通常被稱為file_operations
結(jié)構(gòu)體,其中包含了驅(qū)動(dòng)程序中實(shí)現(xiàn)的各種文件操作函數(shù)指針。
三、驅(qū)動(dòng)中的open函數(shù)
在驅(qū)動(dòng)程序中,實(shí)現(xiàn)文件打開(kāi)操作的函數(shù)通常是open
函數(shù),該函數(shù)的原型定義在頭文件linux/fs.h
中:
int (*open) (struct inode *, struct file *);
open
函數(shù)中的第一個(gè)參數(shù)是文件系統(tǒng)對(duì)象(inode
),第二個(gè)參數(shù)是文件句柄(file
)。
當(dāng)驅(qū)動(dòng)程序的open
函數(shù)被調(diào)用時(shí),它會(huì)根據(jù)文件句柄中保存的文件屬性和訪問(wèn)標(biāo)志(flags
),確定文件打開(kāi)的方式,例如只讀、只寫(xiě)、讀寫(xiě)等。接著,它會(huì)通過(guò)一系列的操作,將文件和硬件設(shè)備打通。
具體來(lái)說(shuō),打開(kāi)文件時(shí),驅(qū)動(dòng)程序的open
函數(shù)會(huì)調(diào)用底層設(shè)備驅(qū)動(dòng)程序的probe
函數(shù),probe
函數(shù)會(huì)根據(jù)設(shè)備的硬件類型和地址,初始化硬件設(shè)備并建立驅(qū)動(dòng)程序和設(shè)備之間的聯(lián)系。在這個(gè)過(guò)程中,驅(qū)動(dòng)程序需要完成一系列的操作,例如打開(kāi)設(shè)備的總線、尋找設(shè)備、初始化設(shè)備、注冊(cè)設(shè)備等等。
在設(shè)備驅(qū)動(dòng)程序和硬件設(shè)備之間建立聯(lián)系后,驅(qū)動(dòng)程序就可以通過(guò)訪問(wèn)設(shè)備寄存器、執(zhí)行設(shè)備指令等方式,向硬件設(shè)備發(fā)送各種命令,從而實(shí)現(xiàn)對(duì)設(shè)備的控制和訪問(wèn)。
當(dāng)應(yīng)用程序通過(guò)調(diào)用read
、write
、ioctl
等函數(shù)來(lái)讀寫(xiě)文件時(shí),這些函數(shù)實(shí)際上是通過(guò)調(diào)用驅(qū)動(dòng)程序中的read
、write
、ioctl
等操作函數(shù)來(lái)實(shí)現(xiàn)的。驅(qū)動(dòng)程序中的這些操作函數(shù)會(huì)將數(shù)據(jù)從應(yīng)用程序空間拷貝到內(nèi)核空間,再將數(shù)據(jù)從內(nèi)核空間拷貝到硬件設(shè)備的寄存器中,實(shí)現(xiàn)數(shù)據(jù)的傳輸和處理。
當(dāng)應(yīng)用程序調(diào)用close
函數(shù)來(lái)關(guān)閉文件時(shí),系統(tǒng)會(huì)調(diào)用驅(qū)動(dòng)程序中的release
函數(shù)來(lái)釋放文件所占用的資源。release
函數(shù)通常用來(lái)做一些清理工作,例如關(guān)閉設(shè)備、釋放內(nèi)存等等。
open
函數(shù)是打通上層應(yīng)用程序和底層硬件設(shè)備的關(guān)鍵,它通過(guò)調(diào)用文件系統(tǒng)、VFS層、設(shè)備驅(qū)動(dòng)程序等一系列操作,將應(yīng)用程序和硬件設(shè)備連接起來(lái),實(shí)現(xiàn)對(duì)硬件設(shè)備的控制和訪問(wèn)。因此,對(duì)于Linux驅(qū)動(dòng)開(kāi)發(fā)工程師來(lái)說(shuō),深入理解open
函數(shù)的實(shí)現(xiàn)原理和內(nèi)部機(jī)制是非常重要的。
四、舉個(gè)例子
下面我將以控制GPIO為例,介紹open
函數(shù)在其中的作用。
GPIO(General Purpose Input/Output
)是一種通用的輸入輸出引腳,可以通過(guò)編程控制來(lái)實(shí)現(xiàn)對(duì)外部設(shè)備的控制和交互。在Linux系統(tǒng)中,GPIO的控制通常是通過(guò)設(shè)備驅(qū)動(dòng)程序來(lái)實(shí)現(xiàn)的,該驅(qū)動(dòng)程序會(huì)提供open
、read
、write
、ioctl
等函數(shù),用于與用戶空間的應(yīng)用程序進(jìn)行交互。
在控制GPIO的程序中,通常需要先打開(kāi)GPIO設(shè)備,然后才能進(jìn)行后續(xù)的讀寫(xiě)操作。當(dāng)調(diào)用open
函數(shù)打開(kāi)GPIO設(shè)備時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用GPIO設(shè)備的設(shè)備驅(qū)動(dòng)程序的open
函數(shù)。在open
函數(shù)中,設(shè)備驅(qū)動(dòng)程序會(huì)根據(jù)傳入的參數(shù),確定GPIO設(shè)備的狀態(tài)和屬性,并將其初始化。
接著,設(shè)備驅(qū)動(dòng)程序會(huì)調(diào)用內(nèi)核中的GPIO子系統(tǒng),通過(guò)GPIO子系統(tǒng)來(lái)訪問(wèn)硬件設(shè)備,例如讀取GPIO的電平狀態(tài)、設(shè)置GPIO的電平狀態(tài)等等。GPIO子系統(tǒng)會(huì)負(fù)責(zé)將內(nèi)核空間的數(shù)據(jù)轉(zhuǎn)換為硬件所需的信號(hào),實(shí)現(xiàn)對(duì)GPIO的控制。
當(dāng)應(yīng)用程序需要對(duì)GPIO進(jìn)行讀寫(xiě)操作時(shí),會(huì)調(diào)用設(shè)備驅(qū)動(dòng)程序中的read
、write
函數(shù)。在read
函數(shù)中,設(shè)備驅(qū)動(dòng)程序會(huì)通過(guò)GPIO子系統(tǒng)讀取GPIO的電平狀態(tài),并將其返回給應(yīng)用程序;在write
函數(shù)中,設(shè)備驅(qū)動(dòng)程序會(huì)通過(guò)GPIO子系統(tǒng)設(shè)置GPIO的電平狀態(tài),實(shí)現(xiàn)對(duì)GPIO的控制。
最后,當(dāng)應(yīng)用程序關(guān)閉GPIO設(shè)備時(shí),會(huì)調(diào)用設(shè)備驅(qū)動(dòng)程序中的release
函數(shù),該函數(shù)會(huì)負(fù)責(zé)釋放GPIO設(shè)備所占用的資源,并將GPIO設(shè)備關(guān)閉。
綜上所述,open
函數(shù)在控制GPIO的程序中起到了連接應(yīng)用程序和底層硬件設(shè)備的作用,它通過(guò)調(diào)用設(shè)備驅(qū)動(dòng)程序的open函數(shù)和內(nèi)核中的GPIO子系統(tǒng),將應(yīng)用程序和GPIO設(shè)備連接起來(lái),實(shí)現(xiàn)對(duì)GPIO的控制和訪問(wèn)。
🔞🔞🔞另外從今天開(kāi)始我將持續(xù)更新 Linux驅(qū)動(dòng)開(kāi)發(fā)100問(wèn) 專題,感興趣的大家可以持續(xù)關(guān)注。