plateform driver and device


platform是内核的一个虚拟总线,它不像usb总线、PCI总线那样真实存在的,platform总线完全是虚拟出来的。我们先看看内核是如何定义这个虚拟总线的:

  struct bus_type platform_bus_type = {

  .name  = "platform",

  .dev_attrs = platform_dev_attrs,

  .match  = platform_match,

  .uevent  = platform_uevent,

  .pm  = &platform_dev_pm_ops,

  };

  bus_type是内核的总线结构体,内核所有的总线都是由这个结构体定义的。 我们只关注name和match这两个成员变量,其中name被赋值为"platform",毋庸置疑,这表示定义了一个名为“platform”的总线。match方法在总线、驱动、设备这三者中扮演着十分重要的角色。

  在这里我简单说一下match方法何时被调用(理解这一点对于理解整个设备驱动模型起到一定的帮助)。当一个驱动挂接到该总线的时候,该总线的match方法被调用,在这里,platform总线的match方法被赋值为platform_match,也就是说platform_match将被调用,platform_match将会帮驱动找到匹配的设备。同样的,当一个设备挂接到该总线时,platform_match也会被调用,platform_match也会帮该设备找到匹配的驱动。用一句话来说就是,platform_match既帮驱动找对象,也帮设备找对象。当驱动和对象匹配上了,platform_match可是会收两家的媒婆钱,黑心的很。

  那么对于platform总线来说,驱动和设备如何挂接到该总线上呢。platform总线分别提供了两个函数给驱动和设备使用。如下所示:

  int platform_driver_register(struct platform_driver *drv)

  int platform_device_register(struct platform_device *pdev)

  很显然platform_driver_register 是给驱动使用的,platform_device_register 是给设备用的。


在sys目录下面建立一个设备节点很简单,一般来说用到两个函数,一个是class_create,还有一个是device_create。这两个函数的配合使用在很多驱动程序里面都可以看到。下面给出这两个函数的原形:

  class_create函数的原形在内核里面有些绕,我稍作了修改便如读者理解,如下所示:

  struct class * class_create(struct module *owner,

  const char *name)

  第一个参数一般填入THIS_MODULE,第二个参数是给这个class起个名字,在sys目录下面有个class目录,假如我这样调用该函数:class_create(THIS_MODULE,"love");那么你将会在/sys/class目录下面看到一个文件名为love的新目录。

  device_create的函数原型如下:

  struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)

  这个函数原型比较复杂,我们一个一个地来说,第一个是前面介绍的class;第二个的用法到时看实际例子;第三个其实就是设备号,我们不打算在/dev目录下面建立设备节点,所以该参数也可以忽略;第四个是要传进去的私有数据,可以给他NULL;最后一个就是给这个device起名字,这个名字最后会成为新目录的文件名。

  我们可以如下所示调用这两个函数:

  struct class * love_class;

  love_class = class_create(THIS_MODULE,"love");

  device_create(love_class,NULL,0,NULL,"haoge");

  这样名字为"haoge"的文件夹就会出现在/sys/class/love的目录下了。

  第二步就是在/sys下面建立属性文件,所谓属性文件就是驱动程序提供给应用程序的控制接口。属性的数据结构如下:

  struct attribute {

  const char  *name;

  mode_t   mode;

  };

  第一个参数当然是给这属性文件起一个文件名,第二个参数设置这个属性文件的读取权限。

  但我们更多的是用device_attribute数据结构,如下所示:

  struct device_attribute {

  struct attribute 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);

  };

  可以看到attribute结构是device_attribute结构中的一个成员,另外两个成员函数就是对该属性文件进行读取的方法函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值