mini6410 设备模型三驾马车之bus.device.driver

</pre><span style="font-size:14px;">设备模型是2.6内核引入的特征</span><p></p><p><span style="font-size:24px;">一、总线</span></p><p><span style="font-size:14px;">总线是处理器与设备之间的通道,包括某些嵌入式处理器的外设,内核也可以用虚拟的platform连接他们</span></p><p></p><pre name="code" class="html"><span style="font-size:14px;">/linux/device.h</span>


<span style="font-size:14px;">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);

	int (*suspend)(struct device *dev, pm_message_t state);
	int (*resume)(struct device *dev);

	const struct dev_pm_ops *pm;

	struct subsys_private *p;
};</span>
内核中用bus_type来描述总线

初始化时主要需要定义其中的name、match、remove、还可以定义属性

总线的注册和删除

<span style="font-size:14px;">int bus_register(struct bus_type *bus)</span>
<span style="font-size:14px;">void bus_unregister(struct bus_type *bus);</span>


设置总线属性的两个步骤

1、下面的宏创建一个名为bus_attr__name的bus_attibute结构,并设置成员名为name、mode、读取属性文件的show函数和写入属性文件的store函数

<pre name="code" class="html"><span style="font-size:14px;">BUS_ATTR(_name, _mode, _show, _store)</span>
 

 
2、将属性文件添加到相应的bus上 
<span style="font-size:14px;">int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)</span>

删除属性

<span style="font-size:14px;">void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr)
</span>

 其实device和driver定义和属性文件的添加也是类似的方法,将上述函数中的bus改为device或者driver即可


二、设备

内核用一个device结构来描述设备

<span style="font-size:14px;">struct device {
	struct device		*parent;

	struct device_private	*p;

	struct kobject kobj;
	const char		*init_name; /* initial name of the device */
	struct device_type	*type;

	struct mutex		mutex;	/* mutex to synchronize calls to
					 * its driver.
					 */
	struct bus_type	*bus;		/* type of bus device is on */
	struct device_driver *driver;	/* which driver has allocated this
					   device */
	void		*platform_data;	/* Platform specific data, device
					   core doesn't touch it */
	struct dev_pm_info	power;


	u64		*dma_mask;	/* dma mask (if dma'able device) */
	u64		coherent_dma_mask;/* Like dma_mask, but for
					     alloc_coherent mappings as
					     not all hardware supports
					     64 bit addresses for consistent
					     allocations such descriptors. */

	struct device_dma_parameters *dma_parms;

	struct list_head	dma_pools;	/* dma pools (if dma'ble) */

	struct dma_coherent_mem	*dma_mem; /* internal for coherent mem
					     override */
	/* arch specific additions */
	struct dev_archdata	archdata;

	dev_t			devt;	/* dev_t, creates the sysfs "dev" */

	spinlock_t		devres_lock;
	struct list_head	devres_head;

	struct klist_node	knode_class;
	struct class		*class;
	const struct attribute_group **groups;	/* optional groups */

	void	(*release)(struct device *dev);
};
</span>

其中至少要定义init_name(这里没有看到资料上说的bus_id)、bus、和release函数

设备的注册和注销和bus_(un)register类似

<span style="font-size:14px;">int device_register(struct device *dev)
函数失败返回非零,需要判断返回值来检查注册是否成功。</span>

<span style="font-size:14px;">void device_unregister(struct device *dev)</span>

属性的添加和总线类似


三、驱动程序

驱动的结构体

<span style="font-size:14px;">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 */

	int (*probe) (struct device *dev);
	int (*remove) (struct device *dev);
	void end) (struct device *dev, pm_message_t state);
	int (*r(*shutdown) (struct device *dev);
	int (*suspesume) (struct device *dev);
	const struct attribute_group **groups;

	const struct dev_pm_ops *pm;

	struct driver_private *p;
};
</span>
一遍需要初始化的有 name、bus、probe 函数

驱动的注册和注销采用下列函数

<span style="font-size:14px;">int driver_register(struct device_driver *drv)
函数失败返回非零,需要判断返回值来检查注册是否成功。
设备注销函数:
 void driver_unregister(struct device_driver *drv)</span>
<span style="font-size:14px;">
</span>
<span style="font-size:14px;">属性的添加和总线类似</span>
<span style="font-size:14px;">
</span>

借用从别的博客上看来的一段话:

归纳起来就是四个函数一个属性结构体

属性结构体:xx_attribute

注册函数:xx_register

注销函数:xx_unregister

创建属性文件函数:xx_create_file

删除属性文件函数:xx_remove_file

其中xx可以是总线(bus)、设备(device)或者驱动函数(deriver)

一但注册成功,就会在/sys目录下相应的地方创建一个自己命名的目录。其中,设备和驱动函数还可以添加到指定的bus目录下。

总线的成功注册后会在/sys/bus目录下创建相应的目录。

设备的成功注册后会在/sys/device目录下创建相应的目录,如果指定总线,会在指定总线目录/sys/bus/xx/device下创建一个指向/sys/device目录的软连接。

驱动函数的公共注册会在/sys/bus/xx/driver目录下创建相应的目录。

属性文件提供了shoestore两个函数调用,当读写文件时会触发相应的函数调用,实现内核sysfs与用户空间的数据交互。



四、其他

struct bus_type bus  中的match函数用来比对挂接在该总线上的驱动和设备,当两者或者别的匹配时,返回 1 。代表两者配对成功、

struct device_driver中的probe 探针函数、当match函数配对成功后、内核就会调用该函数来查询设备是否可以别该驱动操作,如果可以,就会调用该函数,

所以说。真正的驱动函数的入口在probe中



引用:http://blog.chinaunix.net/uid-25014876-id-110295.html





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值