总线,设备,驱动(基于2.6.30.4内核的)

来源:互联网 发布:c语言多线程编程实例 编辑:程序博客网 时间:2024/06/09 19:17

      最近在学习总线、设备、驱动程序,编写总线设备驱动程序的时候,发现2.6.30.4内核中的struct device已经没有bus_id的成员了,发现了const char *init_name成员。但是,这个成员是不能直接用来设置和读取设备名的。通过查阅资料发现2.6.30.4的内核中对struct device属性的bus_id应经修改了,感觉这挺好的,最起码不会差生歧异。下面的2.6.30.4内核上所做的改变:

内核操作的方法为dev_name和dev_set_name。内核中的定义是:

1) dev_name

static inline const char *dev_name(const struct device *dev)
{
    return kobject_name(&dev->kobj);
}

 

2) dev_set_name

/**
 * dev_set_name - set a device name
 * @dev: device
 * @fmt: format string for the device's name
 */
int dev_set_name(struct device *dev, const char *fmt, ...)
{
    va_list vargs;
    int err;

    va_start(vargs, fmt);
    err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
    va_end(vargs);
    return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);

总线

总线是处理器和一个或多个设备之间的通道,在设备模型中, 所有的设备都通过总线相连, 甚至是内部的虚拟"platform"总线。总线可以相互插入。设备模型展示了总线和它们所控制的设备之间的实际连接。
在 Linux 设备模型中, 总线由 bus_type 结构表示, 定义在 <linux/device.h>,创建一条总线的实例

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


设备

在最底层, Linux 系统中的每个设备由一个 struct device 代表,内核创建一个设备的方实例:

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

驱动

在最底层, Linux 系统中的每个设备驱动程序由device_driver表示,在内核建立驱动文件测试程序代码如下

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

MODULE_AUTHOR("David Xie");
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",
    .bus = &my_bus_type,
    .probe = my_probe,

        .remove    = my_remove,
};

/*
 * Export a simple attribute.
 */
static ssize_t mydriver_show(struct device_driver *driver, char *buf)
{
    return sprintf(buf, "%s\n", "This is my 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);

原创粉丝点击