Linux驱动开发 (总线式设备驱动)

1.驱动框架中的总线式设计

在这里插入图片描述

bus_type结构体:

-> 关键是match函数uevent函数 。

struct bus_type {
 
const char		*name;  //总线类型名
struct bus_attribute	*bus_attrs;  //总线属性和导出到sysfs中的方法
struct device_attribute	*dev_attrs;  //设备属性和导出到sysfs中的方法
struct driver_attribute	*drv_attrs;  //驱动程序属性和导出到sysfs中的方法
 
//匹配函数,检验参数2中的驱动是否支持参数1中的设备
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); //关闭函数
 
int (*suspend)(struct device *dev, pm_message_t state);//改变设备供电状态,使其节能
int (*resume)(struct device *dev);  //恢复供电状态,使其正常工作
 
const struct dev_pm_ops *pm;  //关于电源管理的操作符
 
struct bus_type_private *p;  //总线的私有数据
};

内核中 usb总线的定义:

在这里插入图片描述

内核中ac97总线的定义

在这里插入图片描述

总线私有数据:

struct bus type private {
 
struct kset subsys;/*代表该bus子系统,里面的kobj是该bus的主kobj,也就是最顶层*/ 
 
struct kset *drivers kset;/*挂接到该总线上的所有驱动集合*/ 
struct kset *devices kset;/*挂接到该总线上的所有设备集合*/ 
struct klist klist devices;/*所有设备的列表,与devices kset中的1ist相同*/
struct klist klist drivers;/*所有驱动程序的列表,与drivers_kset中的1ist相同*/ 
struct blocking notifier head bus notifier;/**/ 
unsigned int drivers autoprobe:1;/*设置是否在驱动注册时, 自动探测(probe)设备*/ 
struct bus type *bus;/*回指包含自己的总线*/
}

总线属性:

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);//属性写函数
};

2.设备

在Linux设备驱动模型中,每一个设备都由一个device结构体来描述。

device结构体包含了设备所具有的一些通用信息。

对于驱动开发人员来说,当遇到新设备时,需要定义一个新的设备结构体,将device作为新结构体的成员。这样就可以在新结构体中定义新设备的一些信息,而设备通用的信息就使用device结构体来表示。

使用device结构体的另一个好处是,可以通过device轻松地将新设备加入设备驱动模型的管理中。

device中的大多数函数被内核使用,驱动开发人员不用关注。

struct device是硬件设备在内核驱动框架中的抽象。

struct device {
 
struct klist_klist children;        连接子设备的链表
struct device *parent;              指向父设备的指针
struct kobject kobj;				内嵌的kobject结构体
char bus_id[BUS ID SIZE];			连接到总线上的位置
unsigned uevent suppress:1;			是否支持热插拔事件
const char init_name;				设备的初始化名字
struct device_type *type;			设备相关的特殊处理函数
struct bus_type *bus;				指向连接的总线指针
struct device_driver *driver;		指向该设备的驱动程序
void *driver data;					指向驱动程序私有数据的指针
struct dev_pm info power;			电源管理信息
dev t deyt;							设备号
struct class *class;				指向设备所属类
struct attribute_group **groups;	设备的组属性
void (*release) (struct device *dev);释放设备描述符的回调函数
 
}

设备属性:

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

用来在devic目录下创建一个属性文件:

int device_create_file(struct device *dev,  //创建
		       const struct device_attribute *attr)
void device_remove_file(struct device *dev,  //删除
			const struct device_attribute *attr)

3.驱动

-> struct device_driver是驱动程序在内核驱动框架中的抽象。

-> name,驱动程序的名字,很重要,经常被用来作为驱动和设备的匹配依据。

-> probe,驱动程序的探测函数,用来检测一个设备是否可以被该驱动所管理。

struct device_driver {
	const char		*name;//设备驱动程序的名字
	struct bus_type		*bus;//指向驱动属于的总线
 
	struct module		*owner;//设备驱动自身模块
	const char		*mod_name;	/* used for built-in modules */
 
	bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */
 
#if defined(CONFIG_OF)
	const struct of_device_id	*of_match_table;
#endif
 
	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);//恢复正常的方法
	const struct attribute_group **groups;//属性组
 
	const struct dev_pm_ops *pm;//电源管理
 
	struct driver_private *p;//设备驱动私有数据
};

4.类

相关结构体:struct class 和 struct class_device。

class的真正意义在于作为同属于一个class的多个设备的容器。

class是一种人造概念,目的就是为了对各种设备进行分类管理。

struct class {
	const char		*name;
	struct module		*owner;
 
	struct class_attribute		*class_attrs;
	struct device_attribute		*dev_attrs;
	struct kobject			*dev_kobj;
 
	int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
	char *(*devnode)(struct device *dev, mode_t *mode);
 
	void (*class_release)(struct class *class);
	void (*dev_release)(struct device *dev);
 
	int (*suspend)(struct device *dev, pm_message_t state);
	int (*resume)(struct device *dev);
 
	const struct kobj_ns_type_operations *ns_type;
	const void *(*namespace)(struct device *dev);
 
	const struct dev_pm_ops *pm;
 
	struct class_private *p;
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值