您的位置:首页 > 运维架构 > Linux

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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: