linux驱动模型 - 设备

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值