一步一步學習 Linux 驅動之自動建立裝置節點
阿新 • • 發佈:2019-02-09
extern struct device *device_create(struct class *cls, struct device *parent,
dev_t devt, void *drvdata,
const char *fmt, ...)
__attribute__((format(printf, 5, 6)));</span>
之前寫的字元類裝置驅動,沒有自動建立裝置節點,因為只使用了register_chrdev()函式,只是註冊了這個裝置。然後在系統啟動後,就要自己建立裝置節點mknod,這樣雖然是可行的,但是比較麻煩。於是想在__init函式裡面,自動建立裝置節點。函式功能: 函式device_create()用於動態的建立邏輯裝置,並對新的邏輯裝置類進行相應初始化,將其與函式的第一個引數所代表的邏輯類關聯起來,然後將此邏輯裝置加到linux核心系統的裝置驅動程式模型中。函式能夠自動在/sys/devices/virtual目錄下建立新的邏輯裝置目錄,在/dev目錄下創建於邏輯類對應的裝置檔案 引數說明: struct class cls:與即將建立額邏輯裝置相關的邏輯類。 dev_t dev:裝置號 void *drvdata: void型別的指標,代表回撥函式的輸入引數 const char *fmt: 邏輯裝置的裝置名,即在目錄 /sys/devices/virtual建立的邏輯裝置目錄的目錄名。
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/irq.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #include <linux/poll.h> #include <linux/device.h> static struct class *Myleddrv_class; //自動註冊驅動主裝置 static struct device *Myleddrv_dev; volatile unsigned long *gpbcon = NULL; //控制暫存器 volatile unsigned long *gpbdat = NULL; //資料暫存器 static int Myleddrv_open(void) { printk("Hello Linux World!\n"); return 0; } static int Myleddrv_write(void) { return 0; } static struct file_operations Myleddrv_fops = { .owner = THIS_MODULE, /* 這是一個巨集,推向編譯模組時自動建立的__this_module變數 */ .open = Myleddrv_open, .write = Myleddrv_write, }; static int major; //全域性變數 static int Myleddrv_init(void) { major = register_chrdev(0, "Myleddrv", &Myleddrv_fops); // 註冊, 告訴核心 Myleddrv_class = class_create(THIS_MODULE, "Myleddrv"); Myleddrv_dev = device_create(Myleddrv_class, NULL, MKDEV(major, 0), NULL, "Myleddrv"); /* /dev/Myleddrv */ return 0; } static void Myleddrv_exit(void) { unregister_chrdev(major, "Myleddrv"); // 解除安裝 printk("Myleddrv has been unregistered!\n"); device_unregister(Myleddrv_dev); class_destroy(Myleddrv_class,major); } module_init(Myleddrv_init); module_exit(Myleddrv_exit); MODULE_LICENSE("GPL");