阅读:2807回复:0
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 { const char * name; u32 id; struct device dev; u32 num_resources; struct resource * 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_t state); int (*suspend_late)(struct platform_device *, pm_message_t state); int (*resume_early)(struct platform_device *); int (*resume)(struct platform_device *); struct device_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 { int minor; const char *name; const struct file_operations *fops; struct list_head list; struct device *parent; struct device *this_device; }; 与字符型设备 struct cdev { struct kobject kobj; struct module *owner; const struct file_operations *ops; struct list_head list; dev_t dev; unsigned int 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_data = &adc_data, }, .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 (设备驱动操作方法) (设备的资源) (设备驱动) 我的疑问: 1、当写字符型设备驱动时,我一般只使用cdev结构体,使用此种方式,好像无法在sysfs中显示出该设备。 2、miscdevice是否支持字符设备和块设备,如果使用它怎么辨别块设备或字符设备。 3、miscdevice、platform_device、platform_driver是否可以作为通用的设备驱动方法,由platform_device注册设备资源 platform_driver注册设备驱动、miscdevice注册设备使用方法。 哪位大侠可以评论我的总结 |
|