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註冊設備使用方法。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章