Linux驱动之设备模型(6)
2013-04-23 09:04
411 查看
原文地址: /article/7669646.html
7.设备驱动7.1 设备驱动
l 在Linux设备模型中,设备驱动用device_driver结构来表示
struct device_driver {
constchar *name;
structbus_type *bus;
structmodule *owner;
const structof_device_id *of_match_table;
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;
};
7.2 驱动属性
l 驱动属性由driver_attribute来表示
struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver*driver, char *buf);
ssize_t (*store)(struct device_driver*driver, const char *buf,
size_t count);
};
DRIVER_ATTR(_name,_mode, _show, _store)
l 属性操作
n 创建属性
int driver_create_file(struct device_driver *driver,
const structdriver_attribute *attr);
n 删除属性
void driver_remove_file(struct device_driver*driver,
const structdriver_attribute *attr);
7.3 驱动基本操作
l 驱动注册和注销
intdriver_register(struct device_driver *drv)
voiddriver_unregister(struct device_driver *drv)
l 驱动注册分析
n driver_register
int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
BUG_ON(!drv->bus->p);
if ((drv->bus->probe&&drv->probe) ||
(drv->bus->remove&& drv->remove)||
(drv->bus->shutdown&&drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating -please use "
"bus_type methods\n", drv->name);
other =driver_find(drv->name,drv->bus);
if (other) {
put_driver(other);
}
ret = bus_add_driver(drv);
ret= driver_add_groups(drv, drv->groups);
}
n bus_add_driver
int bus_add_driver(struct device_driver *drv)
{
bus = bus_get(drv->bus);
error=kobject_init_and_add(&priv->kobj,&driver_ktype, NULL,
"%s", drv->name);
if(drv->bus->p->drivers_autoprobe){
error = driver_attach(drv);
}
klist_add_tail(&priv->knode_bus,&bus->p->klist_drivers);
error =driver_create_file(drv,&driver_attr_uevent);
error = driver_add_attrs(bus, drv);
kobject_uevent(&priv->kobj,KOBJ_ADD);
}
n driver_attach
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus,NULL, drv,__driver_attach);
}
遍历总线上的所有设备,当有驱动支持的设备时,调用__driver_attach函数完成相应的工作__driver_attach()->driver_probe_device()->driver_probe_device()->bus->probe()->
drv->probe ()优先调用总线中定义的probe函数,如果bus中未定义probe,则再调用驱动中定义的probe。
7.4 实例分析
#include
#include
#include
#include
#include
extern struct bus_type scbus_type;
static char * Version = "revision1.0,scdriver";
static int sc_probe(struct device *dev)
{
printk("driver found device\n");
return 0;
}
static int sc_remove(struct device *dev)
{
printk("device remove \n");
return 0;
}
struct device_driver scdriver = {
.name = "scdevice0",
.bus =&scbus_type,
.probe =sc_probe,
.remove =sc_remove,
};
static ssize_t driver_show_version(struct device_driver *driver, char *buf)
{
return sprintf(buf, "%s\n", Version);
}
static DRIVER_ATTR(version, S_IRUGO,driver_show_version, NULL);
static int __initscdriver_init(void)
{
int ret;
ret= driver_register(&scdriver);
if(ret)
return ret;
ret= driver_create_file(&scdriver,&driver_attr_version);
if(ret)
goto err_create;
printk("drvierregistered\n");
return 0;
err_create:
driver_unregister(&scdriver);
return ret;
}
static void __exit scdriver_exit(void)
{
driver_remove_file(&scdriver,&driver_attr_version);
driver_unregister(&scdriver);
}
module_init(scdriver_init);
module_exit(scdriver_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("CJOK");
试验结果:
相关文章推荐
- Linux驱动开发———总线设备驱动模型
- Linux设备模型之tty驱动架构分析
- Linux 字符设备驱动模型
- linux ------ 设备驱动模型之二(bus, device, driver)
- Linux内核大讲堂 (一) 设备驱动的基石驱动模型(5)
- 嵌入式学习-驱动开发-lesson3-混杂设备驱动模型与linux中断处理流程
- 嵌入式linux之分离分层概念,总线驱动设备模型
- Linux驱动之设备模型(2)
- linux内核部件分析之——设备驱动模型之class
- linux 设备驱动模型 class 设备结点文件 热插拔
- [快速上手Linux设备驱动]之我看Linux设备模型(总线篇)
- linux内核部件分析(七)——设备驱动模型之driver
- linux设备模型之uart驱动架构分析
- LINUX2.6设备驱动模型详细解释
- linux内核部件分析(九)——设备驱动模型之device-driver
- Linux驱动之设备模型(9)-platform
- 【转】Linux内核大讲堂 (一) 设备驱动的基石驱动模型(1)
- Linux驱动开发-混杂字符设备驱动模型笔记 4
- 转载_Linux驱动程序开发 - 设备驱动模型初探
- linux 2.6up的设备和设备驱动模型