閱讀466 返回首頁    go 阿裏雲 go 技術社區[雲棲]


深入理解ioctl

《Linux設備驅動程序》ioctl詳解

 


除了讀取和寫入設備之外,大部分驅動程序還需要通過設備驅動程序實行各種類型的硬件控製。簡單的數據傳輸之外,大部分設備還可以執行其他一些操作,比如,用戶空間經常會請求設備鎖門,彈出介質,報告錯誤信息,改變波特率或者執行子破壞,等等。這些操作通常通過ioctl方法來支持。

 

ioctl在用戶空間的原型:

 

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

 

這裏的...代表可變參數,他並不是代表任意數量的一組可變參數,通常,更具cmd來定,如果cmd不需要參數,那麼...就不會被使用,如果cmd需要參數,則就會使用...所以,它隻是代表一個可變參數。習慣上使用 char  *argp來定義。這裏使用...就是為了編譯時防止編譯器進行類型檢查。

 

ioctl命令


每個驅動,都會有自己的ictol命令,那麼在不同的驅動,不同類型設備的驅動之間,這些命令必須唯一標示出來,例如,我們對非串口設備使用設置波特率的命令,如果按照通常意義上將,對ioctl命令從0或者1開始編號,假設1在串口驅動中代表設置波特率,由於其他原因,我們錯誤的在非串口設備中使用1的時候,可能並沒有發生錯誤,隻是進行了其他的操作而已,那麼這是在驅動程序中不允許的。但是如果ioctl命令編號是唯一的,那麼就不會出現這種無意間成功的完成了意想不到的操作。

 

為了方便程序員唯一的創建ioctl命令編號,內核中作了如下規定:

每一個命令號被分為多個字段。新的內核(2.6)中,定義號碼的新方法中使用4個字段來唯一標示一個命令。

 

<linux/ioctl.h>中對個字段的位數做出了定義

 

 

type

         幻數。選擇一個號碼,並在整個驅動程序中使用這個號碼。

 

number

         序數

 

direction

         傳輸方向。_IOC_NONE(沒有數據傳輸),_IOC_READ,_IOC_WRITE以及_IOC_READ|_IOC_WRITE(雙向)這些方向。傳輸方向是站在應用程序的角度來看的。如果應用程序需要從驅動中讀取數據,則方向應該是_IOC_READ。

 

size

      所涉及的用戶數據大小。對於大量數據傳輸可以忽略該字段。

 

以下是<linux/ioctl.h>中對各個字段所占的位數做出了說明

 

#define _IOC_NRBITS     8       //序數占8位
#define _IOC_TYPEBITS   8     //幻數占8位

/*
 * Let any architecture override either of the following before
 * including this file.
 */

#ifndef _IOC_SIZEBITS         //size字段
# define _IOC_SIZEBITS  14 
#endif

#ifndef _IOC_DIRBITS
# define _IOC_DIRBITS   2    //direction 字段
#endif

 

對於自己的驅動,如果需要使用特定的ioctl命令,則必須創建ioctl命令以及編號。內核中給出了創建ioctl命令的宏

 

/* used to create numbers */
#define _IO(type,nr)            _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size)      _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size)      _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size)     _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOR_BAD(type,nr,size)  _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW_BAD(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))

 

 

 


版權申明:
轉載文章請注明原文出處https://blog.csdn.net/feiyinzilgd/archive/2010/03/03/5341173.aspx
並請聯係譚海燕本人或者前往譚海燕個人主頁留言

最後更新:2017-04-02 04:25:59

  上一篇:go magento -- 添加中國省份列表
  下一篇:go svn安裝