資源描述:
《linux高級字符設(shè)備驅(qū)動》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、Linux高級字符設(shè)備驅(qū)動設(shè)備Ioctl控制1.Ioctl用來做什么?大部分驅(qū)動除了需要具備讀寫設(shè)備的能力外,還需要具備對硬件控制的能力。例如,要求設(shè)備報告錯誤信息,改變波特率,這些操作常常通過ioctl方法來實現(xiàn)。1.1用戶使用方法在用戶空間,使用ioctl系統(tǒng)調(diào)用來控制設(shè)備,原型如下:????????intioctl(intfd,unsignedlongcmd,...)原型中的點表示這是一個可選的參數(shù),存在與否依賴于控制命令(第2個參數(shù))是否涉及到與設(shè)備的數(shù)據(jù)交互。1.2驅(qū)動ioctl方法???????ioctl驅(qū)
2、動方法有和用戶空間版本不同的原型:???????int(*ioctl)(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg)???????cmd參數(shù)從用戶空間傳下來,可選的參數(shù)arg以一個unsignedlong的形式傳遞,不管它是一個整數(shù)或一個指針。如果cmd命令不涉及數(shù)據(jù)傳輸,則第3個參數(shù)arg的值無任何意義。2.Ioctl實現(xiàn)2.1實現(xiàn)Ioctl方法的步驟:?????1)?定義命令??????2.)?實現(xiàn)命令2.2定義命令???????
3、在編寫ioctl代碼之前,首先需要定義命令。為了防止對錯誤的設(shè)備使用正確的命令,命令號應(yīng)該在系統(tǒng)范圍內(nèi)是唯一的。ioctl命令編碼被劃分為幾個位段,include/asm/ioctl.h中定義了這些位字段:類型(幻數(shù)),序號,傳送方向,參數(shù)的大小。Documentation/ioctl-number.txt文件中羅列了在內(nèi)核中已經(jīng)使用了的幻數(shù)。???????定義ioctl命令的正確方法是使用4個位段,這個列表中介紹的符號定義在中:1)?Type?????幻數(shù)(類型):表明哪個設(shè)備的命令,在
4、參考了ioctlnumber.txt之后選出,8位寬。2)25?Number?????序號,表明設(shè)備命令中的第幾個,8位寬3)?Direction????數(shù)據(jù)傳送的方向,可能的值是_IOC_NONE(沒有數(shù)據(jù)傳輸),_IOC_READ,_IOC_WRITE。數(shù)據(jù)傳送是從應(yīng)用程序的觀點來看待的,_IOC_READ意思是從設(shè)備讀。4)?Size用戶數(shù)據(jù)的大小。(13/14位寬,視處理器而定)內(nèi)核提供了下列宏來幫助定義命令:1)?_IO(type,nr)???沒有參數(shù)的命令2)?_IOR(type,nr,datatype)?
5、??從驅(qū)動中讀數(shù)據(jù)3)?_IOW(type,nr,datatype)??寫數(shù)據(jù)到驅(qū)動4)?_IOWR(type,nr,datatype)??雙向傳送,type和number成員作為參數(shù)被傳遞。定義命令(范例)#defineMEM_IOC_MAGIC‘m’//定義幻數(shù)#defineMEM_IOCSET_IOW(MEM_IOC_MAGIC,0,int)#defineMEM_IOCGQSET_IOR(MEM_IOC_MAGIC,1,int)2.3Ioctl函數(shù)實現(xiàn)???????定義好了命令,下一步就是要實現(xiàn)Ioctl函數(shù)了,
6、Ioctl函數(shù)的實現(xiàn)包括如下3個技術(shù)環(huán)節(jié):??????1)?返回值???????2)參數(shù)使用??????3)命令操作?2.3.1Ioctl函數(shù)實現(xiàn)(返回值)???????Ioctl函數(shù)的實現(xiàn)通常是根據(jù)命令執(zhí)行的一個switch語句。但是,當(dāng)命令號不能匹配任何一個設(shè)備所支持的命令時,通常返回-EINVAL(“非法參數(shù)”)。2.3..2Ioctl函數(shù)實現(xiàn)(參數(shù))????????如何使用Ioctl中的參數(shù)?????????如果是一個整數(shù),可以直接使用。如果是指針,我們必須確保這個用戶地址是有效的,因此使用前需進(jìn)行正確的檢查。
7、2.3.3Ioctl函數(shù)實現(xiàn)(參數(shù)檢查)???????25不需要檢測:???????1)?copy_from_user???????2)?copy_to_user???????3)?get_user???????4)?put_user???????需要檢測:??????1)?__get_user??????2)?__put_user????????intaccess_ok(inttype,constvoid*addr,unsignedlongsize)???????第一個參數(shù)是VERIFY_READ或者VERIFY_W
8、RITE,用來表明是讀用戶內(nèi)存還是寫用戶內(nèi)存。addr參數(shù)是要操作的用戶內(nèi)存地址,size是操作的長度。如果ioctl需要從用戶空間讀一個整數(shù),那么size參數(shù)等于sizeof(int)。access_ok返回一個布爾值:1是成功(存取沒問題)和0是失敗(存取有問題),如果該函數(shù)返回失敗,則Ioctl應(yīng)當(dāng)返回–EFAULT。3.I