现在的位置: 首页 > 综合 > 正文

总线设备驱动框架程序

2013年05月17日 ⁄ 综合 ⁄ 共 8710字 ⁄ 字号 评论关闭

总线设备驱动框架程序  

装载自:http://blog.csdn.net/sjwangjinbao/article/details/6077236

这里总结下简单的总线设备驱动的框架程序。

 

0、建立文件夹busdevdrv

1、总线

     在文件夹内建立总线文件bus.c,代码如下。

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>

MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");

static char *Version = "$Revision: 1.0 $";

static int my_match(struct device *dev, struct device_driver *driver)
{
    return !strncmp(dev_name(dev), driver->name, strlen(driver->name) );
}

static void my_bus_release(struct device *dev)
{
    printk("my bus release/n");
}

struct device my_bus = {
    .release  = my_bus_release
};

struct bus_type my_bus_type = {
    .name = "my_bus",
    .match = my_match,
};

EXPORT_SYMBOL(my_bus);
EXPORT_SYMBOL(my_bus_type);

/*
* Export a simple attribute.
*/
static ssize_t show_bus_version(struct bus_type *bus, char *buf)
{
    return snprintf(buf, PAGE_SIZE, "%s/n", Version);
}

static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);

static int __init my_bus_init(void)
{
    int ret;

    /*注册总线*/
    ret = bus_register(&my_bus_type);
    if (ret)
    {
        return ret;
    }

    /*创建属性文件*/
    if (bus_create_file(&my_bus_type, &bus_attr_version))
    {
        printk("Fail to create version attribute!/n");
    }

    /*初始化总线设备*/
    dev_set_name(&my_bus, "my_bus0");

    /*注册总线设备*/
    ret = device_register(&my_bus);
    if (ret)
    {
        printk("Fail to register device:my_bus!/n");
    }

    return ret;
}

static void my_bus_exit(void)
{
    device_unregister(&my_bus);
    bus_unregister(&my_bus_type);
}

module_init(my_bus_init);
module_exit(my_bus_exit);

 

2、设备

     在文件夹下建立设备文件dev.c,代码如下。

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>

MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");

extern struct device my_bus;
extern struct bus_type my_bus_type;

static void my_dev_release(struct device *dev)
{

}

struct device my_dev = {
    .bus = &my_bus_type,
    .parent = &my_bus,
    .release = my_dev_release,
};

/*
* Export a simple attribute.
*/
static ssize_t mydev_show(struct device *dev,struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s/n", "This is sjwangjinbao device!");
}

static DEVICE_ATTR(dev, S_IRUGO, mydev_show, NULL);

static int __init my_device_init(void)
{
    int ret = 0;

    /*初始化设备*/
    dev_set_name(&my_dev, "my_dev");

    /*注册设备*/
    device_register(&my_dev);

    /*创建属性文件*/
    device_create_file(&my_dev, &dev_attr_dev);

    return ret;

}

static void my_device_exit(void)
{
    device_unregister(&my_dev);
}

module_init(my_device_init);
module_exit(my_device_exit);

 

3、驱动

     在文件夹下建立驱动文件drv.c,代码如下。

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>

MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");

extern struct bus_type my_bus_type;

static int my_probe(struct device *dev)
{
    printk("Driver found device which my driver can handle!/n");
    return 0;
}

static int my_remove(struct device *dev)
{
    printk("Driver found device unpluged!/n");
    return 0;
}

struct device_driver my_driver = {
    .name = "my_dev",
    .probe = my_probe,
};

/*
* Export a simple attribute.
*/
static ssize_t mydriver_show(struct device_driver *driver, char *buf)
{
    return sprintf(buf, "%s/n", "This is sjwangjinbao driver!");
}

static DRIVER_ATTR(drv, S_IRUGO, mydriver_show, NULL);

static int __init my_driver_init(void)
{
    int ret = 0;

    /*注册驱动*/
    driver_register(&my_driver);

    /*创建属性文件*/
    driver_create_file(&my_driver, &driver_attr_drv);

    return ret;

}

static void my_driver_exit(void)
{
    driver_unregister(&my_driver);
}

module_init(my_driver_init);
module_exit(my_driver_exit);

 

4、Makefile

     在文件夹下建立Makefile,如下。

ifneq ($(KERNELRELEASE),)

obj-m := bus.o dev.o drv.o

else

KDIR := /usr/src/linux-2.6.33.2

all:
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif

 

5、make

     在文件夹下执行make命令,将得到bus.ko, dev.ko, drv.ko三个文件。

6、添加模块

     使用root用户依次调用如下命令添加3个模块:

     insmod bus.ko

     insmod dev.ko

     insmod.drv.ko

 

     这时候,会在/sys/bus下面发现my_bus已经存在了。到/sys/bus/my_bus/devices/看看,发现我们的my_dev设备已 经存在了;到/sys/bus/my_bus/drivers/看看,发现我们的my_dev驱动也存在了。在到/sys/bus/my_bus /devices/my_dev/driver去瞧瞧,发现my_dev驱动已经存在了,这说明我们的 my_dev设备和my_dev驱动已经联系在一起了。同样,在/sys/bus/my_bus/drivers/my_dev下也会发现有个
my_dev的设备,这也说明我们的 my_dev设备和my_dev驱动已经联系在一起了。

 

    另外,我们也可以查看他们的属性。

    1)  在/sys/bus/my_bus下,我们发现有个version文件,用cat查看它,得到输出为:

         $Revision: 1.9 $

         这正是我们在程序中指定的。

    2) 在/sys/bus/my_bus/devices/my_dev下,我们会发现有个 dev文件,用cat查看它,结果为:

         This is my device!

         这也正是我们程序中指定的。

   3) 在/sys/bus/my_bus/drivers/my_dev下,我们也会发现drv文件,用cat查看结果为:

        This is my driver!

        当然,这也是我们在程序中指定的。

 

装载自:http://blog.csdn.net/sjwangjinbao/article/details/6077236

这里总结下简单的总线设备驱动的框架程序。

 

0、建立文件夹busdevdrv

1、总线

     在文件夹内建立总线文件bus.c,代码如下。

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>

MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");

static char *Version = "$Revision: 1.0 $";

static int my_match(struct device *dev, struct device_driver *driver)
{
    return !strncmp(dev_name(dev), driver->name, strlen(driver->name) );
}

static void my_bus_release(struct device *dev)
{
    printk("my bus release/n");
}

struct device my_bus = {
    .release  = my_bus_release
};

struct bus_type my_bus_type = {
    .name = "my_bus",
    .match = my_match,
};

EXPORT_SYMBOL(my_bus);
EXPORT_SYMBOL(my_bus_type);

/*
* Export a simple attribute.
*/
static ssize_t show_bus_version(struct bus_type *bus, char *buf)
{
    return snprintf(buf, PAGE_SIZE, "%s/n", Version);
}

static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);

static int __init my_bus_init(void)
{
    int ret;

    /*注册总线*/
    ret = bus_register(&my_bus_type);
    if (ret)
    {
        return ret;
    }

    /*创建属性文件*/
    if (bus_create_file(&my_bus_type, &bus_attr_version))
    {
        printk("Fail to create version attribute!/n");
    }

    /*初始化总线设备*/
    dev_set_name(&my_bus, "my_bus0");

    /*注册总线设备*/
    ret = device_register(&my_bus);
    if (ret)
    {
        printk("Fail to register device:my_bus!/n");
    }

    return ret;
}

static void my_bus_exit(void)
{
    device_unregister(&my_bus);
    bus_unregister(&my_bus_type);
}

module_init(my_bus_init);
module_exit(my_bus_exit);

 

2、设备

     在文件夹下建立设备文件dev.c,代码如下。

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>

MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");

extern struct device my_bus;
extern struct bus_type my_bus_type;

static void my_dev_release(struct device *dev)
{

}

struct device my_dev = {
    .bus = &my_bus_type,
    .parent = &my_bus,
    .release = my_dev_release,
};

/*
* Export a simple attribute.
*/
static ssize_t mydev_show(struct device *dev,struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s/n", "This is sjwangjinbao device!");
}

static DEVICE_ATTR(dev, S_IRUGO, mydev_show, NULL);

static int __init my_device_init(void)
{
    int ret = 0;

    /*初始化设备*/
    dev_set_name(&my_dev, "my_dev");

    /*注册设备*/
    device_register(&my_dev);

    /*创建属性文件*/
    device_create_file(&my_dev, &dev_attr_dev);

    return ret;

}

static void my_device_exit(void)
{
    device_unregister(&my_dev);
}

module_init(my_device_init);
module_exit(my_device_exit);

 

3、驱动

     在文件夹下建立驱动文件drv.c,代码如下。

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>

MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");

extern struct bus_type my_bus_type;

static int my_probe(struct device *dev)
{
    printk("Driver found device which my driver can handle!/n");
    return 0;
}

static int my_remove(struct device *dev)
{
    printk("Driver found device unpluged!/n");
    return 0;
}

struct device_driver my_driver = {
    .name = "my_dev",
    .probe = my_probe,
};

/*
* Export a simple attribute.
*/
static ssize_t mydriver_show(struct device_driver *driver, char *buf)
{
    return sprintf(buf, "%s/n", "This is sjwangjinbao driver!");
}

static DRIVER_ATTR(drv, S_IRUGO, mydriver_show, NULL);

static int __init my_driver_init(void)
{
    int ret = 0;

    /*注册驱动*/
    driver_register(&my_driver);

    /*创建属性文件*/
    driver_create_file(&my_driver, &driver_attr_drv);

    return ret;

}

static void my_driver_exit(void)
{
    driver_unregister(&my_driver);
}

module_init(my_driver_init);
module_exit(my_driver_exit);

 

4、Makefile

     在文件夹下建立Makefile,如下。

ifneq ($(KERNELRELEASE),)

obj-m := bus.o dev.o drv.o

else

KDIR := /usr/src/linux-2.6.33.2

all:
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif

 

5、make

     在文件夹下执行make命令,将得到bus.ko, dev.ko, drv.ko三个文件。

6、添加模块

     使用root用户依次调用如下命令添加3个模块:

     insmod bus.ko

     insmod dev.ko

     insmod.drv.ko

 

     这时候,会在/sys/bus下面发现my_bus已经存在了。到/sys/bus/my_bus/devices/看看,发现我们的my_dev设备已 经存在了;到/sys/bus/my_bus/drivers/看看,发现我们的my_dev驱动也存在了。在到/sys/bus/my_bus /devices/my_dev/driver去瞧瞧,发现my_dev驱动已经存在了,这说明我们的 my_dev设备和my_dev驱动已经联系在一起了。同样,在/sys/bus/my_bus/drivers/my_dev下也会发现有个
my_dev的设备,这也说明我们的 my_dev设备和my_dev驱动已经联系在一起了。

 

    另外,我们也可以查看他们的属性。

    1)  在/sys/bus/my_bus下,我们发现有个version文件,用cat查看它,得到输出为:

         $Revision: 1.9 $

         这正是我们在程序中指定的。

    2) 在/sys/bus/my_bus/devices/my_dev下,我们会发现有个 dev文件,用cat查看它,结果为:

         This is my device!

         这也正是我们程序中指定的。

   3) 在/sys/bus/my_bus/drivers/my_dev下,我们也会发现drv文件,用cat查看结果为:

        This is my driver!

        当然,这也是我们在程序中指定的。

 

抱歉!评论已关闭.