日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

IOCTL函数用法详解

發(fā)布時間:2023/12/1 综合教程 29 生活家
生活随笔 收集整理的這篇文章主要介紹了 IOCTL函数用法详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

ioctl是設(shè)備驅(qū)動程序中對設(shè)備的I/O通道進(jìn)行管理的函數(shù)
。所謂對I/O通道進(jìn)行管理,就是對設(shè)備的一些特性進(jìn)行控制,例如串口的傳輸波特率、馬達(dá)的轉(zhuǎn)速等等。它的調(diào)用個數(shù)如下:?

int ioctl(int fd, ind cmd, …);?

??? 其中fd是用戶程序打開設(shè)備時使用open函數(shù)返回的文件標(biāo)示符,cmd是用戶程序?qū)υO(shè)備的控制命令,至于后面的省略號,那是一些補(bǔ)充參數(shù),一般最多一個,這個參數(shù)的有無和cmd的意義相關(guān)。?

??? ioctl函數(shù)是文件結(jié)構(gòu)中的一個屬性分量,就是說如果你的驅(qū)動程序提供了對ioctl的支持,用戶就可以在用戶程序中使用ioctl函數(shù)來控制設(shè)備的I/O通道。


簡單介紹一下函數(shù):

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

參數(shù):

1)inode和file:ioctl的操作有可能是要修改文件的屬性,或者訪問硬件。要修改

文件屬性的話,就要用到這兩個結(jié)構(gòu)體了,所以這里傳來了它們的指針。

2)cmd:命令,接下來要長篇大論地說。

3)arg:參數(shù),接下來也要長篇大論。

返回值:

1)如果傳入的非法命令,ioctl返回錯誤號-EINVAL。

2)內(nèi)核中的驅(qū)動函數(shù)返回值都有一個默認(rèn)的方法,只要是正數(shù),內(nèi)核就會傻乎乎的認(rèn)為這是正確的返回,并把它傳給應(yīng)用層,如果是負(fù)值,內(nèi)核就會認(rèn)為它是錯誤號了。

Ioctl里面多個不同的命令,那就要看它函數(shù)的實(shí)現(xiàn)來決定返回值了。打個比方,如果ioctl里面有一個類似read的函數(shù),那返回值也就可以像read一樣返回。

當(dāng)然,不返回也是可以的。

ioctl如何實(shí)現(xiàn)
????在驅(qū)動程序中實(shí)現(xiàn)的ioctl函數(shù)體內(nèi),實(shí)際上是有一個switch{case}結(jié)構(gòu),每一個case對應(yīng)一個命令碼,做出一些相應(yīng)的操作。怎么實(shí)現(xiàn)這些操作,這是應(yīng)用程序自己的事情。
在ioctl中命令碼是唯一聯(lián)系用戶程序命令和驅(qū)動程序支持的途徑。
如果有兩個不同的設(shè)備,但它們的ioctl的cmd(命令碼)卻一樣的,哪天有誰不小心打開錯了,并且調(diào)用ioctl,這樣就完蛋了。因?yàn)檫@個文件里面同樣有cmd對應(yīng)實(shí)現(xiàn),故,我們可以自己生成未使用的命令碼。
所以在Linux核心中是這樣定義一個命令碼的。

一個cmd被分為了4個段,每一段都有各自的意義,cmd的定義在<linux/ioctl.h>。注:但實(shí)際上<linux/ioctl.h>中只是包含了<asm/ioctl.h>,這說明了這是跟平臺相關(guān)的,ARM的定義在<arch/arm/include/asm/ioctl.h>,但這文件也是包含別的文件<asm-generic/ioctl.h>,千找萬找,終于找到了。


在<asm-generic/ioctl.h>中,cmd拆分如下:

全部都在
<asm-generic/ioctl.h>

ioctl-number.txt
這兩個文檔有說明

http:/..../linux/include/asm-generic/ioctl.h

?

#define _IOC(dir,type,nr,size) \


??
????
??
(((dir) ?<< _IOC_DIRSHIFT) | \


????
????
((type) << _IOC_TYPESHIFT) | \


???
????
?
((nr) ? << _IOC_NRSHIFT) | \


???
????
?
((size) << _IOC_SIZESHIFT))



____________________________________

| 設(shè)備類型 | 序列號 | 方向 |數(shù)據(jù)尺寸|

|----------|--------|------|--------|

| 8 bit | 8 bit |2 bit |8~14 bit|

|----------|--------|------|--------|


這樣一來,一個命令就變成了一個整數(shù)形式的命令碼;但是命令碼非常的不直觀,所以Linux Kernel中提供了一些宏。這些宏可根據(jù)便于理解的字符串生成命令碼,或者是從命令碼得到一些用戶可以理解的字符串以標(biāo)明這個命令對應(yīng)的設(shè)備類型、設(shè)備序列號、數(shù)據(jù)傳送方向和數(shù)據(jù)傳輸尺寸。

????幻數(shù):說得再好聽的名字也只不過是個0~0xff的數(shù),占8bit(_IOC_TYPEBITS)。這個數(shù)是用來區(qū)分不同的驅(qū)動的,像設(shè)備號申請的時候一樣,內(nèi)核有一個文檔給出一些推薦的或者已經(jīng)被使用的幻數(shù)。在內(nèi)核文件中定義如下:
Ioctl-number.txt (f:\sourceproject\linux-kernel\linux-3.14.26-g2489c02\documentation\ioctl)

點(diǎn)擊(此處)折疊或打開

  1. Code Seq#(hex)????Include File????????Comments
  2. ========================================================
  3. 0x00????00-1F????linux/fs.h????????
  4. 0x00????00-1F????scsi/scsi_ioctl.h????
  5. 0x00????00-1F????linux/fb.h????????
  6. 0x00????00-1F????linux/wavefront.h????
  7. 0x02????all????linux/fd.h
  8. 0x03????all????linux/hdreg.h
  9. 0x04????D2-DC????linux/umsdos_fs.h????Dead since 2.6.11,?but don't reuse these.
  10. 0x06????all????linux/lp.h
  11. 0x09????all????linux/raid/md_u.h
  12. 0x10????00-0F????drivers/char/s390/vmcp.h
  13. 0x10????10-1F????arch/s390/include/uapi/sclp_ctl.h
  14. 0x10????20-2F????arch/s390/include/uapi/asm/hypfs.h
  15. 0x12????all????linux/fs.h
  16. ????????linux/blkpg.h
  17. 0x1b????all????InfiniBand Subsystem????<http://infiniband.sourceforge.net/>
  18. 0x20????all????drivers/cdrom/cm206.h
  19. 0x22????all????scsi/sg.h
  20. '#'????00-3F????IEEE 1394 Subsystem????Block?for?the entire subsystem
  21. '$'????00-0F????linux/perf_counter.h,?linux/perf_event.h
  22. .....................
  23. ....................


四、CMD參數(shù)如何得出

????cmd參數(shù)在用戶程序端由一些宏根據(jù)設(shè)備類型、序列號、傳送方向、數(shù)據(jù)尺寸等生成,這個整數(shù)通過系統(tǒng)調(diào)用傳遞到內(nèi)核中的驅(qū)動程序,再由驅(qū)動程序使用解碼宏從這個整數(shù)中得到設(shè)備的類型、序列號、傳送方向、數(shù)據(jù)尺寸等信息,然后通過switch{case}結(jié)構(gòu)進(jìn)行相應(yīng)的操作。

????Linux內(nèi)核已經(jīng)提供了相應(yīng)的宏來自動生成ioctl命令碼:

_IO(type,nr) ??//無數(shù)據(jù)傳輸
_IOR(type,nr,size)??//從設(shè)備讀數(shù)據(jù)?
_IOW(type,nr,size) ?//向設(shè)備寫數(shù)據(jù)
_IOWR(type,nr,size)??//同時有讀寫數(shù)據(jù)

????上面的命令已經(jīng)定義了方向,我們要傳的是幻數(shù)(type)、序號(nr)和大小(size)。在這里szie的參數(shù)只需要填參數(shù)的類型,如int,上面的命令就會幫你檢測類型的正確然后賦值sizeof(int)。????
????相對的,Linux內(nèi)核也提供了相應(yīng)的宏來從ioctl命令號種解碼相應(yīng)的域值:

_IOC_DIR(nr)??//從命令中提取方向
_IOC_TYPE(nr)?//從命令中提取幻數(shù)
_IOC_NR(nr)??//從命令中提取序數(shù)
_IOC_SIZE(nr) ?//從命令中提取數(shù)據(jù)大小

例:
/*include_cmd.hpp*/
#define LED_IOC_MAGIC 0x13 ?//定義幻數(shù)
#define LED_MAX_NR ? ?3 ? ? ? ? ?//定義命令的最大序數(shù)
#define?LED_GPRS_MAGIC?_IO(LED_IOC_MAGIC,0x00) ?//0x00 ?用”宏+幻數(shù)“來自動生成ioctl命令碼
#define LED_WIFI_MAGIC _IO(LED_IOC_MAGIC,0x01) ?//0x00
#define LED_BT_MAGIC _IO(LED_IOC_MAGIC,0x02) ?//0x00

/*test.cpp*/
fd = open();
ioctl(fd,LED_GPRS_MAGIC,0);
ioctl(fd,LED_GPRS_MAGIC,1);
ioctl(fd,LED_WIFI_MAGIC?,0);
ioctl(fd,LED_WIFI_MAGIC?,1);

/*test_ioctl.c*/
int test_ioctl (struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg)
{
? ? if(_IOC_TYPE(cmd) !=LED_IOC_MAGIC?) return -EINVAL;? ?//提取出幻數(shù)做檢驗(yàn)
????if(_IOC_NR(cmd) >?LED_MAX_NR?) return?-EINVAL; ? ? ? ? ?//提取命令序數(shù)

? ? switch(cmd){
? ? case?LED_GPRS_MAGIC:
? ? ?if(arg==0){
? ? //..........
????}else if(arg ==1){
????//..........
????}
? ? break;
? ? case?LED_WIFI_MAGIC:
????//..........
? ? break;
????}

}

arg參數(shù):

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

不需要檢測的:

[cpp]?view plain?copy?

  1. copy_from_user??
  2. copy_to_user??
  3. get_user??
  4. put_user??

需要檢測
的:

[cpp]?view plain?copy?

  1. __get_user??
  2. __put_user?

總結(jié)

以上是生活随笔為你收集整理的IOCTL函数用法详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 色婷婷国产精品久久包臀 | 亚洲午夜网 | 极品粉嫩小仙女高潮喷水久久 | 日韩一区2区 | 超碰公开免费 | 丰满少妇中文字幕 | 99视频精品 | 视色网| 天堂久久精品忘忧草 | 青青草视频在线观看 | 欧美中字| 日韩在线视频观看免费 | 午夜精品久久 | 久久久91精品国产一区二区三区 | 日本在线色 | 大尺度做爰呻吟62集 | 二色av | 亚洲一区二区色 | 91免费在线看 | 成 人 黄 色 片 在线播放 | 亚洲最大福利视频网 | 麻豆影视网站 | 高h乱l高辣h文短篇h | 亚洲va在线 | 九九热精品 | 国产黄色免费观看 | 国产国语老龄妇女a片 | 黄频在线免费观看 | 永久免费精品 | 日韩免费观看一区二区三区 | 国产精品午夜久久 | 91超碰人人 | 欧美在线观看视频一区 | 日韩色区 | 日本嫩草影院 | 偷偷操网站 | 国产亚洲精品成人a | 黄色一级片免费在线观看 | 老汉av在线 | 天天宗合 | 91久久精品国产 | 狠狠干狠狠操 | 大伊人网| 999在线观看视频 | www.99精品| 在线日韩成人 | 手机天堂网 | 无码黑人精品一区二区 | 阿拉伯性视频xxxx | 成人免费区一区二区三区 | 毛片的网站| 韩国三级视频 | 18无码粉嫩小泬无套在线观看 | 97国产精品久久 | 日韩国产精品一区二区 | 中国黄色录像一级片 | 91视频啊啊啊 | 黄色大片视频网站 | 日本一级二级视频 | 性一交一乱一伧老太 | japanesehdxxxx| 黄页网站免费在线观看 | 日日夜夜精品视频免费 | 99人妻碰碰碰久久久久禁片 | 无码 制服 丝袜 国产 另类 | jizzjizz黄大片| 欧美黄色影院 | 成人免费大片黄在线播放 | 国产欧美一区二区三区在线老狼 | 久久久久久久久99精品 | 精品久久久久久久久久久aⅴ | 国产高清区 | 一二三四区在线 | 天天综合在线视频 | 国产精品久久婷婷 | 五月天丁香社区 | 成人毛片在线免费观看 | 美丽的姑娘在线观看 | 中文字字幕在线中文乱码 | 91黑人精品一区二区三区 | 国产精品久久久久久一区 | 迈开腿让我尝尝你的小草莓 | a级片免费播放 | 成人美女在线观看 | av这里只有精品 | 国产男女无遮挡猛进猛出 | 国产伦精品一区二区三区高清版 | 亚洲精品国产一区二 | 揉我啊嗯~喷水了h视频 | 91麻豆精品国产91久久久更新时间 | 大肉大捧一进一出好爽 | 亚洲综合在线成人 | 玩弄人妻少妇500系列视频 | 免费一区二区三区四区 | jlzzjlzzjlzz亚洲人 | 在线播放少妇奶水过盛 | 久久久久亚洲av无码网站 | 一区二区三区在线免费观看视频 | 无套内谢的新婚少妇国语播放 |