linux驱动模型 - 设备
2014-07-11 17:48
351 查看
TheBasic Device Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~
See the kerneldoc for the struct device.
ProgrammingInterface
~~~~~~~~~~~~~~~~~~~~~
检测到设备的总线驱动使用如下函数将设备注册到内核:
int device_register(struct device * dev);
总线负责初始化device结构的下列域:
- parent
- name
- bus_id
- bus
当设备的reference count变为0时,会从内核中移除. 使用下列函数调整reference count
struct device * get_device(struct device * dev);
void put_device(struct device * dev);
如果reference count还不是0(如果正好处于移除的过程中),get_device()会返回指向传递给它的struct device的指针.
驱动可以使用下列函数访问device结构中的lock:
void lock_device(struct device * dev);
void unlock_device(struct device * dev);
Attributes
~~~~~~~~~~
struct device_attribute {
structattribute attr;
ssize_t(*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev,struct device_attribute *attr, const char *buf, size_t count);
};
驱动可以使用一个类似于procfs(sysfs)的接口来导出设备的属性。有关sysfs如何工作的内容,请参考Documentation/filesystems/sysfs.txt.
设备属性可以通过宏DEVICE_ATTR声明:
#define DEVICE_ATTR(name,mode,show,store)
Example:
DEVICE_ATTR(power,0644,show_power,store_power);
这个宏声明了一个名为'dev_attr_power'的device_attribute结构. 通过下列函数可以将属性添加/移除到设备在/sysfs的目录:
int device_create_file(struct device *device, structdevice_attribute * entry);
void device_remove_file(struct device * dev, structdevice_attribute * attr);
Example:
device_create_file(dev,&dev_attr_power);
device_remove_file(dev,&dev_attr_power);
该文件的名字是'power' ,访问权限为0644 (-rw-r--r--).
警告: 无论何时,当内核允许对一个设备调用device_create_file()和
device_remove_file(), 用户空间对设备属性何时被创建有严格的期望. 当一个新设备注册到内核,会产生一个uevent以提示用户空间(比如udev)有新设备可用. 如果属性在设备注册之后才添加,用户空间则无从了解这个属性.
对于设备驱动而言,在探测(probe)设备时要做的一项重要工作是为设备发布额外的属性. 如果设备驱动只是简单地对传递给它的device结构调用device_create_file(), 那么用户空间永远无法获得新属性的通知. 相反地,设备驱动或许应当在模块入口函数modules_init()中使用class_create() 和 class->dev_attrs创建一个属性列表,而后在
.probe()中使用device_create()创建一个设备,作为被探测到的设备的子设备. 这个新的设备会产生uevent并将新的属性发布到用户空间.
举例来说,如果一个驱动想要增添如下属性:
struct device_attribute mydriver_attribs[] = {
__ATTR(port_count,0444, port_count_show),
__ATTR(serial_number,0444, serial_number_show),
NULL
};
在模块入口函数中应该做:
mydriver_class= class_create(THIS_MODULE, "my_attrs");
mydriver_class.dev_attr= mydriver_attribs;
假设'dev' 是传递到probe()的参数,设备驱动的probe函数则要做:
device_create(&mydriver_class,dev, chrdev, &private_data, "my_name");
~~~~~~~~~~~~~~~~~~~~~~~~~~
See the kerneldoc for the struct device.
ProgrammingInterface
~~~~~~~~~~~~~~~~~~~~~
检测到设备的总线驱动使用如下函数将设备注册到内核:
int device_register(struct device * dev);
总线负责初始化device结构的下列域:
- parent
- name
- bus_id
- bus
当设备的reference count变为0时,会从内核中移除. 使用下列函数调整reference count
struct device * get_device(struct device * dev);
void put_device(struct device * dev);
如果reference count还不是0(如果正好处于移除的过程中),get_device()会返回指向传递给它的struct device的指针.
驱动可以使用下列函数访问device结构中的lock:
void lock_device(struct device * dev);
void unlock_device(struct device * dev);
Attributes
~~~~~~~~~~
struct device_attribute {
structattribute attr;
ssize_t(*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev,struct device_attribute *attr, const char *buf, size_t count);
};
驱动可以使用一个类似于procfs(sysfs)的接口来导出设备的属性。有关sysfs如何工作的内容,请参考Documentation/filesystems/sysfs.txt.
设备属性可以通过宏DEVICE_ATTR声明:
#define DEVICE_ATTR(name,mode,show,store)
Example:
DEVICE_ATTR(power,0644,show_power,store_power);
这个宏声明了一个名为'dev_attr_power'的device_attribute结构. 通过下列函数可以将属性添加/移除到设备在/sysfs的目录:
int device_create_file(struct device *device, structdevice_attribute * entry);
void device_remove_file(struct device * dev, structdevice_attribute * attr);
Example:
device_create_file(dev,&dev_attr_power);
device_remove_file(dev,&dev_attr_power);
该文件的名字是'power' ,访问权限为0644 (-rw-r--r--).
警告: 无论何时,当内核允许对一个设备调用device_create_file()和
device_remove_file(), 用户空间对设备属性何时被创建有严格的期望. 当一个新设备注册到内核,会产生一个uevent以提示用户空间(比如udev)有新设备可用. 如果属性在设备注册之后才添加,用户空间则无从了解这个属性.
对于设备驱动而言,在探测(probe)设备时要做的一项重要工作是为设备发布额外的属性. 如果设备驱动只是简单地对传递给它的device结构调用device_create_file(), 那么用户空间永远无法获得新属性的通知. 相反地,设备驱动或许应当在模块入口函数modules_init()中使用class_create() 和 class->dev_attrs创建一个属性列表,而后在
.probe()中使用device_create()创建一个设备,作为被探测到的设备的子设备. 这个新的设备会产生uevent并将新的属性发布到用户空间.
举例来说,如果一个驱动想要增添如下属性:
struct device_attribute mydriver_attribs[] = {
__ATTR(port_count,0444, port_count_show),
__ATTR(serial_number,0444, serial_number_show),
NULL
};
在模块入口函数中应该做:
mydriver_class= class_create(THIS_MODULE, "my_attrs");
mydriver_class.dev_attr= mydriver_attribs;
假设'dev' 是传递到probe()的参数,设备驱动的probe函数则要做:
device_create(&mydriver_class,dev, chrdev, &private_data, "my_name");
相关文章推荐
- Linux设备模型之tty驱动架构分析
- Linux设备模型(总线、设备、驱动程序和类)之三:device_driver && 多厂家驱动自动识别
- LINUX设备驱动之设备模型四--device&driver&bus(二)
- Linux驱动程序开发 - 设备驱动模型初探(一)
- 慢慢学Linux驱动开发,第五篇,初探设备模型概念
- linux 设备模型详解 驱动
- [转]linux设备模型之uart驱动架构分析(开始做驱动!!)
- LINUX设备驱动之设备模型五--device&driver&bus(三)
- LINUX设备驱动之设备模型一--kobject
- linux 驱动设备模型介绍
- Linux设备模型之tty驱动架构分析
- Linux驱动程序开发 - 设备驱动模型初探
- LINUX2.6设备驱动模型详细解释
- 详细介绍Linux2.6设备的驱动模型[转]
- linux设备模型之uart驱动架构分析
- linux设备模型之uart驱动架构分析
- Linux驱动程序开发 - 设备驱动模型初探
- Linux驱动程序开发 - 设备驱动模型初探
- linux设备模型之uart驱动架构分析
- 慢慢学Linux驱动开发,第五篇,初探设备模型概念