LINUX平台裝置(linux platform_device and platform_driver)

來源:互聯網
上載者:User

 

LINUX平台裝置分為

1 裝置層(主要是描述裝置資源)
2 驅動層(我們寫驅動要實現的)
裝置層:主要定義個裝置的資源。
用platform_device結構體來描述一個平台裝置。定義在(/include/LINUX/platform_device.h)
struct platform_device {
const char * name;//裝置名稱
int   id;
struct device dev;
u32   num_resources;//裝置使用資源的數量
struct resource * resource;//使用的資源
};
例如:/* RTC */
/**************************************************************/
arch/arm/plat-s3c24xx/devs.c中就定義了很多平台裝置,截取RTC的裝置結構
static struct resource s3c_rtc_resource[] = {
[0] = {//IO連接埠資源範圍
   .start = S3C24XX_PA_RTC,
   .end   = S3C24XX_PA_RTC + 0xff,
   .flags = IORESOURCE_MEM,//定義了這個資源的類型(通俗點就是要記憶體映射的類型)/include/linux/ioport.h
},
[1] = {//RTC警示中斷資源
   .start = IRQ_RTC,
   .end   = IRQ_RTC,
   .flags = IORESOURCE_IRQ,//這個資源是中斷類型的
},
[2] = {//TICK節拍時間中斷資源
   .start = IRQ_TICK,
   .end   = IRQ_TICK,
   .flags = IORESOURCE_IRQ,
}
};

struct platform_device s3c_device_rtc = {
.name    = "s3c2410-rtc",//RTC名字(與驅動裡面的name要一樣)
.id    = -1,
.num_resources   = ARRAY_SIZE(s3c_rtc_resource),(對上面的s3c_rtc_resource求值,求出的是定義了幾個資源)
.resource   = s3c_rtc_resource,//對應上面的 struct resource s3c_rtc_resource[]
};

EXPORT_SYMBOL(s3c_device_rtc);
/**************************************************************/
以上定義了RTC所有的裝置資源!然後我們要使用這些資源,就要添加到核心裡面!
開啟arch/arm/mach-s3c2440/mach-smdk2440.c這個ARM 2440平台的系統入口檔案。裡面有這兩個!
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,//因為我們要加入RTC裝置到系統,在這裡加入
};
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);

platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));//這裡是添加裝置的註冊函數!剛好調用上面的smdk2440_devices。
smdk_machine_init();
}
上面就吧裝置資源加入到了核心!
下面就是實現我們的驅動!
具體步驟和RTC驅動的實現參照黃剛前輩的部落格!http://blog.chinaunix.net/u3/101649/showart_2142248.html
我也是個菜鳥,我只是吧我的理解寫下來,便以記憶!
有錯誤,歡迎拍磚,指正!謝謝!
《《《《《《《《《《《《《《驅動部分《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

驅動層用struct platform_driver 結構體來定義驅動。

static struct platform_driver rtc_driver = //定義platform_driver 結構體
{
    .probe   = rtc_probe, /*RTC探測函數,
    .remove = __devexit_p(rtc_remove),/*RTC移除函數,*/
    .suspend = rtc_suspend, /*RTC掛起函數,
    .resume = rtc_resume, /*RTC恢複函數,
    .driver =
    {
        /*注意這裡的名稱一定要和系統中定義平台裝置的地方一致,這樣才能把平台裝置與該平台裝置的驅動關聯起來*/
        .name   = "s3c2410-rtc",
        .owner = THIS_MODULE,
    },
};

static int __init rtc_init(void)
{
    /*將RTC註冊成平台裝置驅動*/
    return platform_driver_register(&rtc_driver);
}

static void __exit rtc_exit(void)
{
    /*登出RTC平台裝置驅動*/
    platform_driver_unregister(&rtc_driver);
}

module_init(rtc_init);
module_exit(rtc_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huang Gang");
MODULE_DESCRIPTION("My2440 RTC driver");
這個地方還跟我們以前寫字元模組驅動一樣,用module_init(),,但是我們把類似於中斷註冊,IO映射等等都都放到rtc_probe裡面實現!所以這裡只是調用return platform_driver_register(&rtc_driver)將RTC註冊成平台裝置驅動。
其實很多地方我也不懂,查查資料,我是這樣理解的:為了保持低功耗,我們只是在用的某個裝置的時候才將其開啟,平時不用的時候我們可以掛起。因為ARM一般都用到消費電子上,所以對功耗有很高的要求!這也是我們採用平台裝置的目的!
開始我以為這裡就是驅動實現函數(類似於open ,read等等)!看到後來才發現不是!介面函數在後面!
註冊完裝置,此時系統只是知道有這個裝置,但是不知道要使用什麼資源!於是rtc_probe這個探測函數出場了!它主要負責探測資源,初始化,(其實裝置的初始化可以放到__init rtc_init()函數裡面進行的)。我們在探測函數裡面註冊中斷(RTC有2個中斷),進行記憶體映射(IOMAP()),就像我們寫字元驅動的初始化一樣!但王剛的註冊中斷在後面的open裡面,iomap在這裡面,我覺得根據實際情況來,其實放哪裡都可以,比如中斷,如果牽扯到共用中斷,還是要放到open裡面來註冊。
probe函數見黃剛前輩的部落格!

一切初始化完後,我們要註冊一個RTC裝置類。
| /*將RTC註冊為RTC裝置類,RTC裝置類在RTC驅動核心部分中由系統定義好的,
|     注意rtcops這個參數是一個結構體,該結構體的作用和裡面的介面函數實現在第③步中。
|     rtc_device_register函數在rtc.h中定義,在drivers/rtc/class.c中實現*/
|    rtc = rtc_device_register("my2440", &pdev->dev, &rtcops, THIS_MODULE);
|    if (IS_ERR(rtc))
|    {
|        /*錯誤處理*/
|        dev_err(&pdev->dev, "cannot attach rtc\n");
|        ret = PTR_ERR(rtc);
|        goto err_nortc;
|    }
|

static const struct rtc_class_ops rtcops = {         / /RTC類的file_operation函數)
.open = rtc_open,
.release         = rtc_release,
.irq_set_freq    = rtc_setfreq,

.irq_set_state   = rtc_setpie,
.read_time       = rtc_gettime,
.set_time        = rtc_settime,
.read_alarm      = rtc_getalarm,
.set_alarm       = rtc_setalarm,
};
//這個是RTC類註冊函數的原型!
struct rtc_device *rtc_device_register(const char *name,
      struct device *dev,
      const struct rtc_class_ops *ops,
      struct module *owner);

我也不太清楚這個類的作用,我理解的是為了統一管理嗎???不清楚!知道的說下!
類註冊的函數裡面有一個struct rtc_class_ops *ops, 這個結構體很重要,他就是我們寫驅動時候那些個(READ ,WRITE等),我們主要來實現這個rtc_class_ops。
struct rtc_class_ops {
int (*open)(struct device *);//開啟
void (*release)(struct device *);//關閉
int (*ioctl)(struct device *, unsigned int, unsigned long);//IOCTL
int (*read_time)(struct device *, struct rtc_time *);//讀時間
int (*set_time)(struct device *, struct rtc_time *);//設定時間
int (*read_alarm)(struct device *, struct rtc_wkalrm *);
int (*set_alarm)(struct device *, struct rtc_wkalrm *);
int (*proc)(struct device *, struct seq_file *);
int (*set_mmss)(struct device *, unsigned long secs);
int (*irq_set_state)(struct device *, int enabled);
int (*irq_set_freq)(struct device *, int freq);
int (*read_callback)(struct device *, int data);
};
看看,跟我們的file_operation是多麼的相似!可以說是完全一樣!我們就是來實現這些函數來操作我們的RTC。目前我是這樣理解的!
差不多就這樣吧!我太菜了!也不是很清楚!

那什麼情況可以使用platform driver機制編寫驅動呢?//下面的話是轉的!!哈哈!

我的理解是只要和核心本身運行依賴性不大的外圍裝置(換句話說只要不在核心運行所需的一個最小系統之內的裝置),相對獨立的,擁有各自獨自的資源(addresses and IRQs),都可以用platform_driver實現。如:lcd,usb,uart等,都可以用platfrom_driver寫,而timer,irq等最小系統之內的裝置則最好不用platfrom_driver機制,實際上核心實現也是這樣的。

截至黃剛的部落格!http://blog.chinaunix.net/u3/101649/showart_2142248.html

RTC在Linux中的整體結構:
就個人理解,RTC在Linux中整體結構分為兩個部分。第一個是部分就是上面所講的作為平台裝置被掛接到系統匯流排中,這裡我把他叫做裝置層(呵呵,可能不是很準確的叫法);第二部分就是驅動部分,這裡叫做驅動層。在Linux中要使一個驅動在不同的平台中都能夠使用似乎是不可能的,所以我們先看2.6.30.4核心驅動中的RTC部分是單獨的一個檔案夾,在檔案夾中包含了很多不同體繫結構的RTC驅動,當然也有S3C2440的RTC驅動,然而在這些驅動中他們都使用了一組檔案裡面的方法,那麼這組檔案就是RTC的核心(注意這裡的核心不是指對RTC硬體的操作,指的是對RTC操作的方法。對硬體寄存器的操作還是在具體的驅動中)。好了,我們還是用圖來說明這種關係吧!!

出處  LINUX平台裝置(linux platform_device and platform_driver)zhuan_lala19861008的空間_百度空間

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.