总线驱动设备

Linux设备模型使用了三个数据结构分别来描述总线、设备和驱动。所有的设备和对应的驱动都必须挂载在某一个总线上,通过总线,可以绑定设备和驱动。
这个属于分离的思想,将设备和驱动分开管理。

1、bus 总线

总线是处理器和设备之间的通道。总线有多种类型,每种总线可以挂载多个设备。
在设备模型中,所有的设备都通过总线相连,以总线来管理设备和驱动函数。总线有bus_type结构表示。

/*linux/device.h*/
struct bus_type {
 const char *name;
 struct bus_attribute *bus_attrs;
 struct device_attribute *dev_attrs;
 struct driver_attribute *drv_attrs;

 int (*match)(struct device *dev, struct device_driver *drv);
 int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
 int (*probe)(struct device *dev);
 int (*remove)(struct device *dev);
 void (*shutdown)(struct device *dev);
总线属性添加和删除:

设置总线的属性后,会在对应的总线目录下增加了一个新的文件,通过对该文件的读写访问,触发相应的函数操作,从而实现/sys/的文件接口与内核设备模型的数据交互。

 struct attribute {
 const char *name; //设定该文件的名字
 struct module *owner; //设定该文件的属主
 mode_t mode; //设定该文件的文件操作权限
 };
/*linux/device.h*/
 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);
 };

bus_attribute中有两个函数指针,show和store。

设置总线属性有两个步骤:
1、创建并初始化bus_attribute结构

使用宏BUS_ATTR
BUS_ATTR(_name, _mode, _show, _store)
该宏会定义一个名叫bus_attr__name的bus_attibute的结构,并且成员name设置为_name,文件权限mode设置为_mode,两个函数调用分别人show和store。

2、将bus_attibute添加到指定的总线上

使用以下调用:

 int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)

该函数失败时返回错误号。
一旦调用该函数,会就在指定bus总线的目录下新建一个名叫_name的文件

2、driver

驱动程序是在CPU运行时,提供操作的软件接口。所有的设备必须有与之配套驱动程序才能正常工作。一个驱动程序可以驱动多个类似或者完全不同的设备。

/*linux/device.h*/
struct device_driver {
 const char *name; //驱动函数的名字,在对应总线的driver目录下显示
 struct bus_type *bus; //指定该驱动程序所操作的总线类型,必须设置,不然会注册失败

 struct module *owner;
 const char *mod_name; /* used for built-in modules */

 int (*probe) (struct device *dev); //探测函数,以后会讲
 int (*remove) (struct device *dev); //卸载函数,当设备从系统中删除时调用,以后讲
 void (*shutdown) (struct device *dev); //当系统关机是调用
 int (*suspend) (struct device *dev, pm_message_t state);
 int (*resume) (struct device *dev);
 struct attribute_group **groups;

 struct dev_pm_ops *pm;

 struct driver_private *p;
 };

和设备不一样的是,在注册驱动函数是必须指定该驱动函数对应的总线,因为驱动函数注册成功后,会存放在对应总线的driver目录下,如果没有总线,注册当然会失败。

注册驱动

1、定义结构体device_driver。

2、调用注册函数:

 int driver_register(struct device_driver *drv)
函数失败返回非零,需要判断返回值来检查注册是否成功。
驱动函数属性:
 struct driver_attribute {
 struct attribute attr;
 ssize_t (*show)(struct device_driver *driver, char</
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值