午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

ioctl(int fd,unsigned long cmd,...)命令詳解

 Apache丶Rio 2014-03-19

ioctl命令詳解 

相關(guān)資料請(qǐng)參照:ioctl-number.txt、linux/ioctl.h

功能:

大部分驅(qū)動(dòng)除了需要具備讀寫設(shè)備的能力外,還需要具備對(duì)硬件控制的能力。例如,要求設(shè)備報(bào)告錯(cuò)誤信息,改變波特率,這些操作常常通過ioctl方法來實(shí)現(xiàn)。

用戶使用方法:

在用戶空間,使用ioctl系統(tǒng)調(diào)用來控制設(shè)備,原型如下:

int ioctl(int fd,unsigned long cmd,...);

原型中的點(diǎn)表示這是一個(gè)可選的參數(shù),存在與否依賴于控制命令(第二個(gè)參數(shù))是否涉及到與設(shè)備的數(shù)據(jù)交互。

驅(qū)動(dòng)ioctl方法:

ioctl驅(qū)動(dòng)方法有和用戶空間版本不同的原型:

int (*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)

cmd參數(shù)從用戶空間傳下來,可選的參數(shù) arg以一個(gè)unsigned long 的形式傳遞,不管它是一個(gè)整數(shù)或一個(gè)指針。如果cmd命令不涉及數(shù)據(jù)傳輸,則第3個(gè)參數(shù)arg的值無任何意義。從linux-2.6.36把,已經(jīng)由unlocked_ioctl替代原來的ioctl。其中驅(qū)動(dòng)的變化就是函數(shù)參數(shù)去掉inode參數(shù),其它應(yīng)該沒有變化。int ioctl(int fd,unsigned long cmd,...)。

ioctl實(shí)現(xiàn)

如何實(shí)現(xiàn)ioctl方法?

1.定義命令

2.實(shí)現(xiàn)命令

定義命令

在編寫ioctl代碼之前,首先需要定義命令。為了防止對(duì)錯(cuò)誤的設(shè)備使用正確的命令,命令號(hào)應(yīng)該在系統(tǒng)范圍內(nèi)是唯一的中定義。ioctl命令編碼被劃分為幾個(gè)位段,include/asm/ioctl.h定義了這些位字段:類型(幻數(shù)),序號(hào),傳送方向,參數(shù)的大小。

Documentation/ioctl-number.txt文件中羅列了在內(nèi)核中已經(jīng)使用了的幻數(shù)。

定義命令

定義ioctl命令的正確方法是使用4 個(gè)位段,這個(gè)列表中介紹的符號(hào)定義在<linux/ioctl.h>:

Type

幻數(shù)(類型):表明哪個(gè)設(shè)備的命令,在參考了ioctl-number.txt之后選出,8位寬。

Number

序號(hào),表明設(shè)備命令中的第幾個(gè),8位寬。

Direction

數(shù)據(jù)傳送的方向,可能的值是

_IOC_NONE(沒有數(shù)據(jù)傳輸)

_IOC_READ

_IOC_WRITE

數(shù)據(jù)傳送是從應(yīng)用程序的觀點(diǎn)來看待的,_IOC_READ意思是從設(shè)備讀。

size

用戶數(shù)據(jù)的大小。(13/14位寬,視處理器而定)

內(nèi)核提供了下列宏來幫助定義命令:

_IO(type,nr);

沒有 參數(shù)的命令

_IOR(type,nr,datatype)

從驅(qū)動(dòng)中讀取數(shù)據(jù)

_IOW(type,nr,datatype)

寫數(shù)據(jù)到驅(qū)動(dòng)

_IOWR(type,nr,datatype)

雙向傳送,typenumber成員作為參數(shù)被傳遞。

列子(example)

#define MEM_IOC_MAGIC 'm' //定義幻數(shù)

#define MEM_IOCSET _IOW(MEM_IOC_MAGIC,0,int)

#define MEM_IOCGQSET  _IOR(MEM_IOC_MAGIC,1,int)

ioctl函數(shù)實(shí)現(xiàn)

定義好了命令,下一步就是要實(shí)現(xiàn)ioctl函數(shù)了,ioctl函數(shù)的實(shí)現(xiàn)包括如下3個(gè)技術(shù)環(huán)節(jié):

1.返回值

2. 參數(shù)使用

3.命令操作

ioctl函數(shù)實(shí)現(xiàn)(返回值)

ioctl函數(shù)的實(shí)現(xiàn)通常是根據(jù)命令執(zhí)行的一個(gè) switch語(yǔ)句。但是,當(dāng)命令號(hào)不能匹配任何一個(gè)設(shè)備所支持的命令時(shí), 通常返回-EINVAL("非法參數(shù)")

ioctl函數(shù)實(shí)現(xiàn)(參數(shù))

如何使用ioctl中的參數(shù)?

如果是一個(gè)整數(shù),可以直接使用。如果是指針,我們必須確保這個(gè)用戶地址是有效的,因此使用前需進(jìn)行正確的檢查。

ioctl函數(shù)實(shí)現(xiàn)(參數(shù)檢查)

不需要檢測(cè):

copy_from_user

copy_to_user

get_user

put_user

需要檢測(cè):

__get_user

__put_user

參數(shù)檢查函數(shù):

int access_ok(int type,const void *addr,unsigned long size);

type:VERIFY_READ或者VERIFY_WRITE,用來表明是讀用戶內(nèi)存還是寫用戶內(nèi)存。

addr:要操作的用戶內(nèi)存地址

size操作的長(zhǎng)度,如果ioctl需要從用戶空間讀一個(gè)整數(shù),那么size參數(shù)等于sizeof(int)

access_ok返回一個(gè)布爾值:1是成功(存取沒問題)0失敗(存取有問題),如果該函數(shù)返回失敗,則ioctl應(yīng)當(dāng)返回-EFAULT

ioctl 函數(shù)實(shí)現(xiàn)(參數(shù)檢查)

if(_IOC_DIR(cmd) & _IOC_READ)

         err = !access_ok(VERIFY_WRITE,(void __user *)arg,_IOC_SIZE(cmd));

//為什么_IOC_READ對(duì)應(yīng)VERIFY_WRITE??

else if(_IOC_DIR(cmd) & _IOC_WRITE)

         err = !access_ok(VERIFY_READ,(void _user)*arg,_IOC_SEIZE(cmd));

if(err)

   return -EFAULT;

ioctl函數(shù)實(shí)現(xiàn)(命令操作)

switch(cmd)

{

   case MEM_IOCSQUANTUM:

         retval = _get_user(scull_quantum,(int *)arg);

         break;

   case MEM_IOCGQUANTUM:

         retval = _put_user(scull_quantum,(int *)arg);

         break;

      default:

         return -EINVAL;

}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多