在linux系统的fsysfs中创建总线,以及为总线增加设备和驱动
2012-09-20 17:07
405 查看
注册总线三步曲:
注册总线
bus_register(&my_bus_type);
创建属性文件
bus_create_file(&my_bus_type, &bus_attr_version);
注册总线设备
device_register(&my_bus);
总线由struct bus_type结构来表示,如第一步的my_bus_type, 定义在<linux/device.h>中
该结构管理着总线的名字,总线设备匹配,总线内设备的热插拔等事情,如
struct bus_type my_bus_type = {
.name = "my_bus",
.match = my_match,
.hotplug = my_hotplug,
};
总线的名字就是显示在/sys/bus/目录下的名字,如上面的my_bus。当总线上有新设备或新驱动被添加时,会一次或多次调用match函数。 在为用户空间产生热插拔事件前,可以通过hotplug函数添加环境变量,这个工作不是必要的。
总线属性由 struct bus_attribute结构来描述,在代码中使用
#define BUS_ATTR(_name, _mode, _show, _store)
来创建和初始化。
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *bus, char *buf);
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
比如要在my_bus目录下定义一个属性文件version,代表bus的版本,则可以这样写:
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);
if (bus_create_file(&my_bus_type, &bus_attr_version))
printk(KERN_NOTICE "Fail to create version attribute!\n");
每一个总线本身也是一个设备,所以也需要注册总线设备,在linux2.6.32及以后的内核中,总线设备的名字由init_name来表示,以及dev_name() 和 dev_set_name() 来获取和设置设备名称。
由于总线设备是顶层总线,所以其parent和bus成员是NULL,而release方法不做任何实质性的工作。
总线创建成功以后,在新的总线目录下有devices和drivers目录,这两个目录分别包含总线下的设备和设备驱动。
在总线下创建设备
初始化设备
dev_set_name(&my_dev, "my_dev");
...
注册设备
device_register(&my_dev);
创建属性文件
device_create_file(&my_dev, &dev_attr_dev);
如果需要把一个设备注册到某个总线之下,则需要把总线相关的信息与该设备关联起来,这是通过定义设备的父设备和总线的bus_type,设备的父设备使用总线名称来表示。如总线的名称是my_bus,总线的bus_type是my_bus_type。则:
struct device my_dev = {
.bus = &my_bus_type,
.parent = &my_bus,
.release = my_dev_release,
};
在总线下创建驱动
注册驱动
driver_register(&my_driver);
创建属性文件
driver_create_file(&my_driver, &driver_attr_drv);
驱动程序由以下结构来定义
struct device_driver{
char *name; /*驱动的名字*/
struct bus_type *bus; /*属于哪个总线*/
struct kobject kobj;
struct list_head devices;
int (* probe) (struct device *dev); /*驱动的probe*/
int (* remove) (struct device *dev);/*驱动的remove*/
void (* shutdown) ( struct device *dev);/*当关机时,调用该函数*/
…
};
驱动与总线的所属关系是通过 *bus联系起来的,name是驱动的名称,总线的match方法就是通过设备驱动名称与设备名称比较来实现的。
如在my_bus总线下增加一个名称为my_dev的驱动,则该结构应该包括以下部分:
struct device_driver my_driver = {
.name = "my_dev",
.bus = &my_bus_type,
.probe = my_probe,
.remove = my_remove,
};
注册总线
bus_register(&my_bus_type);
创建属性文件
bus_create_file(&my_bus_type, &bus_attr_version);
注册总线设备
device_register(&my_bus);
总线由struct bus_type结构来表示,如第一步的my_bus_type, 定义在<linux/device.h>中
该结构管理着总线的名字,总线设备匹配,总线内设备的热插拔等事情,如
struct bus_type my_bus_type = {
.name = "my_bus",
.match = my_match,
.hotplug = my_hotplug,
};
总线的名字就是显示在/sys/bus/目录下的名字,如上面的my_bus。当总线上有新设备或新驱动被添加时,会一次或多次调用match函数。 在为用户空间产生热插拔事件前,可以通过hotplug函数添加环境变量,这个工作不是必要的。
总线属性由 struct bus_attribute结构来描述,在代码中使用
#define BUS_ATTR(_name, _mode, _show, _store)
来创建和初始化。
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *bus, char *buf);
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
比如要在my_bus目录下定义一个属性文件version,代表bus的版本,则可以这样写:
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);
if (bus_create_file(&my_bus_type, &bus_attr_version))
printk(KERN_NOTICE "Fail to create version attribute!\n");
每一个总线本身也是一个设备,所以也需要注册总线设备,在linux2.6.32及以后的内核中,总线设备的名字由init_name来表示,以及dev_name() 和 dev_set_name() 来获取和设置设备名称。
由于总线设备是顶层总线,所以其parent和bus成员是NULL,而release方法不做任何实质性的工作。
总线创建成功以后,在新的总线目录下有devices和drivers目录,这两个目录分别包含总线下的设备和设备驱动。
在总线下创建设备
初始化设备
dev_set_name(&my_dev, "my_dev");
...
注册设备
device_register(&my_dev);
创建属性文件
device_create_file(&my_dev, &dev_attr_dev);
如果需要把一个设备注册到某个总线之下,则需要把总线相关的信息与该设备关联起来,这是通过定义设备的父设备和总线的bus_type,设备的父设备使用总线名称来表示。如总线的名称是my_bus,总线的bus_type是my_bus_type。则:
struct device my_dev = {
.bus = &my_bus_type,
.parent = &my_bus,
.release = my_dev_release,
};
在总线下创建驱动
注册驱动
driver_register(&my_driver);
创建属性文件
driver_create_file(&my_driver, &driver_attr_drv);
驱动程序由以下结构来定义
struct device_driver{
char *name; /*驱动的名字*/
struct bus_type *bus; /*属于哪个总线*/
struct kobject kobj;
struct list_head devices;
int (* probe) (struct device *dev); /*驱动的probe*/
int (* remove) (struct device *dev);/*驱动的remove*/
void (* shutdown) ( struct device *dev);/*当关机时,调用该函数*/
…
};
驱动与总线的所属关系是通过 *bus联系起来的,name是驱动的名称,总线的match方法就是通过设备驱动名称与设备名称比较来实现的。
如在my_bus总线下增加一个名称为my_dev的驱动,则该结构应该包括以下部分:
struct device_driver my_driver = {
.name = "my_dev",
.bus = &my_bus_type,
.probe = my_probe,
.remove = my_remove,
};
相关文章推荐
- Linux SPI总线和设备驱动架构之一:系统概述
- 乾坤合一:Linux设备驱动之I2C核心、总线以及设备驱动
- 访问eeprom设备的方法三(理解iic总线接口应用以及创建sysfs文件系统的bin文件访问接口(新的访问设备的文件接口))
- Linux驱动开发之四-----LED改进测试(增加自动创建设备节点)
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- stm32usb功能设备以及在linux下的USB相关总线、设备驱动笔记
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux ALSA声卡驱动之四:Control设备的创建
- Linux系统中设备节点可以创建在?
- linux驱动开发--字符设备:创建一组设备节点
- Linux SPI总线设备驱动模型详解
- Linux设备驱动开发详解-Note(10)--- Linux 文件系统与设备文件系统(2)
- 【Linux开发】【DSP开发】Linux设备驱动之——PCI 总线
- linux 总线 设备 驱动
- linux驱动学习--第八天:第五章 Linux 文件系统与设备文件系统(二) 之 Linux 文件系统