回答
ioctl
,這意味着「輸入輸出控制」是一種設備特定的系統調用。在Linux(300-400)中只有少數系統調用,它們不足以表達設備可能具有的所有獨特功能。因此,驅動程序可以定義允許用戶空間應用程序發送訂單的ioctl。然而,ioctl不是很靈活,並且往往會有點混亂(數十個「魔術數字」只能起作用或者不起作用),並且在將緩衝區傳遞到內核時也可能不安全 - 錯誤的處理可能會中斷事情很容易。
另一種是sysfs
界面,在這裏建立了一個文件/sys/
下,讀/寫,從和驅動器獲取信息。如何設置這個了一個例子:
static ssize_t mydrvr_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", DRIVER_RELEASE);
}
static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);
和驅動程序安裝過程中:
device_create_file(dev, &dev_attr_version);
你將不得不爲你的設備中的文件/sys/
,例如,/sys/block/myblk/version
塊驅動程序。
另一種更重用的方法是netlink,它是一種通過BSD套接字接口與您的驅動程序通信的IPC(進程間通信)方法。例如,這由WiFi驅動程序使用。然後,您使用libnl
或libnl3
庫從用戶空間與其通信。
ioctl
功能在實現設備驅動程序以在設備上設置配置時非常有用。例如打印機具有配置選項來檢查和設置字體,字體大小等。ioctl
可用於獲取當前字體以及將字體設置爲另一個字體。在用戶應用程序中,使用ioctl
向打印機發送代碼,告訴其返回當前字體或將字體設置爲新字體。
int ioctl(int fd, int request, ...)
fd
是文件描述符,由開啓request
返回的一個是請求代碼。例如GETFONT將從打印機獲取當前字體,SETFONT將在打印機上設置字體。- 第三個參數是
void *
。根據第二個論點,第三個可能會或可能不存在。 例如如果第二個參數是SETFONT,則第三個參數可能會將字體名稱設置爲ARIAL。
因此,現在int請求不僅僅是一個宏,還需要一個生成請求代碼,用於由用戶應用程序和設備驅動程序模塊使用,以確定設備上的哪個配置必須使用。一個用戶應用程序使用ioctl
發送請求代碼,然後使用設備驅動程序模塊中的請求代碼確定要執行的操作。
的請求的代碼具有4個主要部分
1. A Magic number - 8 bits
2. A sequence number - 8 bits
3. Argument type (typically 14 bits), if any.
4. Direction of data transfer (2 bits).
如果請求代碼是setfont程序設置在打印機上的字體,用於數據傳輸的方向是從用戶的應用程序的設備驅動程序模塊。用戶將字體名稱Arial發送到打印機。如果請求代碼是GETFONT,則方向是從打印機到用戶應用程序。
要生成請求碼的Linux提供一些預定義的函數等的宏。
1. _IO(MAGIC, SEQ_NO)
兩者都是8位,0到255,例如讓我們說我們想暫停打印機。 這不需要ADATA轉移。所以,我們會生成請求代碼如下
#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM)
現在使用的驅動模塊ioctl
作爲
ret_val = ioctl(fd, PAUSE_PRIN);
對應的系統調用將收到的代碼,並暫停打印機。
__IOW(MAGIC, SEQ_NO, TYPE)
MAGIC
和SEQ_NO
同上,但第三部分對下一個參數的類型,回憶的ioctl
第三個參數是void *
。 W的__IOW
指示數據的方向是從用戶應用到驅動模塊。讓我們舉個例子,假設 一個告訴打印機字體設置爲宋體。#define PRIN_MAGIC 'S' #define SEQ_NO 1 #define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)
進一步,
char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font);
現在font
是一個指針,這意味着它是最好的表示爲unsigned long
的地址,因此的_IOW
第三部分提到類型本身。此外,這個字體地址被傳遞給設備驅動模塊中實現的相應系統調用,如unsigned long
,我們需要在使用它之前將其轉換爲適當的類型。內核空間可以訪問用戶空間,因此可以工作。像宏這樣的其他兩個函數分別是__IOR(MAGIC, SEQ_NO, TYPE)
和__IORW(MAGIC, SEQ_NO, TYPE)
,其中數據流的方向將分別從內核空間到用戶空間和兩個方向。
請讓我知道,如果這有助於!
我不知道上面的__IOW,__IOR和__IORW函數是否正確(在某些情況下,我的意思是雙下劃線,在某些情況下,我沒有使用雙下劃線)......感謝您的明確解釋! – jcoppens 2016-05-09 19:24:27
- 1. 設備驅動程序IOCTL傳遞int
- 2. Linux的字符設備驅動程序:阻塞ioctl調用
- 3. Linux設備驅動程序
- 4. Linux驅動程序:ioctl或sysfs?
- 5. Linux設備驅動程序原子GET,然後通過ioctl設置
- 6. Linux i2c-設備驅動程序module_i2c_driver()
- 7. Linux網絡設備驅動程序
- 8. 設備驅動程序在linux中
- 9. 通過IOCTL將結構傳遞給設備驅動程序
- 10. 寫字符設備驅動程序,ioctl()vs正常讀/寫?
- 11. 平臺設備/驅動程序vs i2c設備/驅動程序
- 12. 將虛擬PCI設備與linux設備驅動程序接口
- 13. 創建設備文件:Linux設備驅動程序
- 14. Linux設備驅動程序字符設備「子目錄」
- 15. 初學者設備驅動程序開發的Linux
- 16. Linux設備驅動程序,程序啓動的地方?
- 17. Linux設備驅動程序 - 線程化IRQ處理程序
- 18. Linux設備驅動程序的最簡單驅動程序新手
- 19. 如何使用android/linux電源驅動程序註冊設備驅動程序?
- 20. Linux設備驅動程序:將標誌傳遞給驅動程序
- 21. Wince設備驅動程序
- 22. Windows設備驅動程序
- 23. scull設備驅動程序
- 24. 關於Linux設備驅動
- 25. 在Linux設備驅動程序的簡單程序
- 26. 如何啓動linux系統和設備驅動程序編程
- 27. 需要Linux內核驅動程序定義的ioctl
- 28. Linux內核設備驅動程序設計
- 29. Linux設備驅動程序:從內核複製字符串到用戶空間
- 30. Windows 7驅動程序ioctl調用
這個答案部分地回答了這個問題。 – 2016-11-29 03:44:00