driver是"驱动"的意思
device是"设备"的意思
//Driver相当于class类,device相当于object实例
miscdevice、platform_device、platform_driver的区别?大侠指教
最近研究Linux设备驱动程序遇到混乱,请大侠过来理理头绪。
Linux设备模型中:bus_type、device、device_driver
《Linux设备驱动程序》的linux设备模型章中说到设备模型中,所有设备都通过总线相连。
添加设备devA,必须指定其device结构体的bus_type域,初始化其他域,然后调用device_register(&devA),将设备devA
注册到指定总线。
添加该设备驱动driverA,也必须指定其device_driver结构体的bus_type域,初始化其他域,然后调用driver_register(&driverA),
将该驱动注册到总线上。
如果驱动driverA和设备devA匹配成功,即调用probe函数成功,则建立他们之间的符号链接,即将设备与驱动捆绑起来。
而实际我看Linux源代码中却大量使用platform_device,
struct platform_device{
constchar *name;
u32 id;
structdevice dev;
u32 num_resources;
structresource *resource;
};
和
struct platform_driver {
int(*probe)(struct platform_device*);
int(*remove)(struct platform_device*);
void(*shutdown)(struct platform_device*);
int(*suspend)(struct platform_device *, pm_message_tstate);
int(*suspend_late)(struct platform_device *, pm_message_t state);
int(*resume_early)(struct platform_device*);
int(*resume)(struct platform_device*);
structdevice_driver driver;
};
从结构体可以看出,platform_device是device派生出,platform_driver是device_driver派生出同样添加设备PlatformDevA,初始化platform_device结构体的dev域时,没有初始化其bus_type域,而实际将该设备添加在sys\bus\platform\devices目录下,在源代码中哪里可以看到这部分代码。
同样添加驱动PlatformDrvA,初始化platform_driver结构体的driver域时,没有初始化其bus_type域,而实际将该驱动添加在sys\bus\platform\drivers目录下,在源代码中哪里可以看到这部分代码。
还有
struct miscdevice {
intminor;
constchar*name;
conststruct file_operations *fops;
structlist_headlist;
structdevice*parent;
structdevice*this_device;
};
与字符型设备
struct cdev {
structkobject kobj;
structmodule *owner;
conststruct file_operations *ops;
structlist_head list;
dev_tdev;
unsignedint count;
};
从结构体可以看出,miscdevice是device派生出,它与platform_device区别:
1、platform_device中有设备使用的资源的信息resource。
2、miscdevice中有该设备的使用方法file_operations。
从设备驱动源代码中:
第一步
static struct platform_device at91sam9260_adc_device = {
.name = "at91_adc",
.id = -1,
.dev = {
.platform_da
},
.resource = adc_resources,
.num_resources = ARRAY_SIZE(adc_resources),
};
static struct resource spi0_resources[] = {
[0] ={
.start = AT91SAM9260_BASE_SPI0,
.end =AT91SAM9260_BASE_SPI0 + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] ={
.start = AT91SAM9260_ID_SPI0,
.end =AT91SAM9260_ID_SPI0,
.flags = IORESOURCE_IRQ,
},
};
//向系统添加此设备,注册设备的资源
platform_device_register(&at91sam9260_adc_device);
第二步:
static struct file_operations at91_adc_fops = {
.owner= THIS_MODULE,
.ioctl = at91_adc_ioctl,
.read = at91_adc_readdata,
.open= at91_adc_open,
.release = at91_adc_release,
};
static struct miscdevice at91_adc_dev ={
.minor= MISC_DYNAMIC_MINOR,
.name= "adc",
.fops= &at91_adc_fops,
};
//向系统添加此设备,注册设备的使用方法
misc_register(&at91_adc_dev);
第三步:
static struct platform_driver at91_i2c_driver = {
.probe = at91_adc_probe,
.remove = __devexit_p(at91_adc_remove),
.suspend =at91_adc_suspend,
.resume = at91_adc_resume,
.driver = {
.name ="at91_adc",
.owner =THIS_MODULE,
},
};
//注册此设备驱动
platform_driver_register(&at91_i2c_driver);
这三个结构体关系:
(基类)
kobject--------------------
/ \ \
/ \ \
device cdev driver
/ \(设备驱动操作方法) \
/ \ \
miscdevice platform_device platform_driver