1. 程式人生 > >一步一步學習 Linux 驅動之自動建立裝置節點

一步一步學習 Linux 驅動之自動建立裝置節點

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");