miscdevice、platform_device區別?(轉)
最近研究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註冊設備使用方法。
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註冊設備使用方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.