在linux核心中裝置主要有三種:
1 字元裝置:
•字元裝置的讀寫以位元組為單位,訪問時沒有快取。
•對字元裝置發出讀寫請求時,實際的硬體i/o緊接著就發生了。一般來說,字元裝置不支援隨機訪問。
•典型的字元裝置包括滑鼠、鍵盤及序列口等。
2 塊裝置:
•塊裝置讀寫以塊為單位,典型的塊大小為512或1024位元組。
•利用一塊系統記憶體作為緩衝區,當使用者程序對裝置發出讀寫請求時,驅動程式先察看緩衝區中的內容,若緩衝區中的資料能滿足使用者的要求就返回相應的資料,否則就呼叫相應的請求函式來進行實際的i/o操作,以提高效率。
•塊裝置主要包括硬碟、軟盤、cd-rom等。
3 網路裝置:
•linux的網路系統主要基於bsd unix的socket機制。在系統和驅動程式之間定義有專門的資料結構進行資料的傳遞。系統裡支援對傳送資料和接收資料的快取,提高流量控制機制,提供對多協議的支援。
4 每個裝置對應乙個檔案,放在/dev目錄下
5 每個裝置檔案都對應有兩個裝置號,存放在inode節點中
•主裝置號標示裝置的種類,也標識了該裝置所使用的驅動程式;
•次裝置號標識了使用同一裝置驅動程式的不同硬體裝置。
6 可以通過/proc/devices 來檢視相應的裝置號,通過mknod /dev/*** c major minor 來產生裝置節點,從而將裝置掛接到/dev目錄下。或者在編寫驅動程式時動態的獲取主裝置號以及動態產生裝置節點。
7 下面具體分析乙個led的驅動程式。(該程式沿用了2.6以前版本的驅動程式的書寫方法,後面會介紹新的書寫方法,但是本質是一樣的)。
宣告為static是為了避免資料對內和造成汙染,僅對該模組有效。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//相關的標頭檔案,我們仿照其他模組載入即可。
#define device_name "leds" /* 載入模式後,執行」cat /proc/devices」命令看到的裝置名稱 */
//用於自動產生裝置節點
static struct class *leds_class;
static struct class_device
* leds_class_devs[4];
// led的控制位址
volatile unsigned long *gpfcon = null;
volatile unsigned long *gpfdat = null;
//應用程式執行open時呼叫該函式;
static int first_drv_open(struct inode *inode, struct file *file)
case 1: /* /dev/led1 */
case 2: /* /dev/led2 */
case 3: /* /dev/led3 */
}return 0;
}
// 應用程式執行write時呼叫該函式;
static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
else
break;
}
case 1: /* /dev/led1 */
else
break;
}
case 2: /* /dev/led2 */
else
break;
}
case 3: /* /dev/led3 */
else
break;
}
}
return 0;
}
//驅動程式與核心的介面;
static struct file_operations first_drv_fops = ;
int major; //記錄動態獲取的裝置號
/** 執行insmod命令時就會呼叫這個函式
*/
static int first_drv_init(void)
leds_class = class_create(this_module, "leds"); // 產生節點類,以leds_class宣告的均為同一種裝置
if (is_err(leds_class))
return ptr_err(leds_class);
leds_class_devs[0] = class_device_create(leds_class, null, mkdev(major, 0), null, "leds");
//產生不同的從裝置,並以不同的名字掛接在/dev目錄下;
for (minor = 1; minor < 4; minor++)
gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);//控制暫存器位址
gpfdat = gpfcon + 1; //
0x56000054 //資料暫存器位址。
printk(device_name " initialized\n");
return 0;
}
/*
* 執行rmmod命令時就會呼叫這個函式
*/
static void first_drv_exit(void)
class_destroy(leds_class);
iounmap(gpfcon);
}
module_init(first_drv_init);
module_exit(first_drv_exit);
/* 描述驅動程式的一些資訊,不是必須的 */
module_author("");
module_version("0.1.0");
module_description("led driver");
module_license("gpl");
我們寫應用程式時,開啟相應的裝置/dev/leds , /dev/led1, /dev/led2, /dev/led3 向其中寫1,0 就可以控制全部led或者某個led的亮滅.
linux 驅動程式 高階字元驅動程式
ioctl方法 驅動程式的原型實現 int ioctl struct inode inode,struct file filp,unsigned int cmd,unsigned long arg ioctl 命令選擇 位段結構 number direction ioc read ioc write...
linux裝置驅動程式 字元裝置驅動程式
先留個 有一起學習驅動程式的加qq295699450 字元裝置驅動 這篇比較惱火。載入成功,但是讀不出來資料,有知道怎麼回事的,留個言,一起討論下 資料結構 struct scull mem struct scull dev dev 整個驅動程式 如下 include include include...
Linux裝置驅動程式 字元裝置驅動程式
1.檢視主裝置號,次裝置號 進入 dev目錄執行ls l,第四,五列分別為主次裝置號,10,180,1,5,這些是主裝置號,而60,63這些就是次裝置號 130 shell android dev ls l crw rw r system radio 10,60 1969 12 31 21 00 a...