新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > [ARM筆記]驅(qū)動(dòng)對設(shè)備的識(shí)別過程及實(shí)例——NAND Flash

        [ARM筆記]驅(qū)動(dòng)對設(shè)備的識(shí)別過程及實(shí)例——NAND Flash

        作者: 時(shí)間:2016-12-02 來源:網(wǎng)絡(luò) 收藏

          程序識(shí)別設(shè)備時(shí),有以下兩種方法:

        本文引用地址:http://www.104case.com/article/201612/341049.htm

          (1)程序本身帶有設(shè)備信息,比如開始地址、中斷號(hào)等;加載程序時(shí),就可以根據(jù)這些信息來識(shí)別設(shè)備。

          (2)驅(qū)動(dòng)程序本身沒有設(shè)備信息,但是內(nèi)核中已經(jīng)(或以后)根據(jù)其他方式確定了很多設(shè)備的信息;加載驅(qū)動(dòng)程序時(shí),將驅(qū)動(dòng)程序與這些設(shè)備逐個(gè)比較,確定兩者是否匹配(math)。如果驅(qū)動(dòng)程序與某個(gè)設(shè)備匹配,就可以通過該驅(qū)動(dòng)程序來操作這個(gè)設(shè)備了。

          內(nèi)核常使用第二種方法來識(shí)別設(shè)備,這可以將各種設(shè)備集中在一個(gè)文件中管理,當(dāng)開發(fā)板的配置改變時(shí),便于修改代碼。在內(nèi)核文件include/linux/platform_device.h中,定義了兩個(gè)數(shù)據(jù)結(jié)構(gòu)來表示這些設(shè)備和驅(qū)動(dòng)程序:platform_device結(jié)構(gòu)用來描述設(shè)備的名稱、ID、所占用的資源(比如內(nèi)存地址/大小、中斷號(hào))等;platform_driver結(jié)構(gòu)用來描述各種操作函數(shù),比如枚舉函數(shù)、移除設(shè)備函數(shù)、驅(qū)動(dòng)名稱等。

          內(nèi)核啟動(dòng)后,首先構(gòu)造鏈表將描述設(shè)備的platform_device結(jié)構(gòu)組織起來,得到一個(gè)設(shè)備的列表;當(dāng)加載某個(gè)驅(qū)動(dòng)程序的platform_driver結(jié)構(gòu)時(shí),使用一些匹配函數(shù)來檢查驅(qū)動(dòng)程序能否支持這些設(shè)備,常用的檢查方法很簡單:比較驅(qū)動(dòng)程序和設(shè)備的名稱。

          以S3C2410開發(fā)板為例,在include/arch/arm/mach-s3c2410/mach-smdk2410.c中定義了如下設(shè)備:

          89 static struct platform_device *smdk2410_devices[] __initdata = {

          90 &s3c_device_usb,

          91 &s3c_device_lcd,

          92 &s3c_device_wdt,

          93 &s3c_device_i2c,

          94 &s3c_device_iis,

          95 };

          104 static void __init smdk2410_init(void)

          105 {

          106 platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));

          107 smdk_machine_init();

          108 }

          在include/arch/arm/plat-s3c24xx/common-smdk.c中定義了如下設(shè)備:

          175 static struct platform_device __initdata *smdk_devs[] = {

          176 &s3c_device_nand,

          177 &smdk_led4,

          178 &smdk_led5,

          179 &smdk_led6,

          180 &smdk_led7,

          181 };

          183 void __init smdk_machine_init(void)

          184 {

          185 /* Configure the LEDs (even if we have no LED support)*/

          186

          187 s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);

          188 s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);

          189 s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);

          190 s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);

          191

          192 s3c2410_gpio_setpin(S3C2410_GPF4, 1);

          193 s3c2410_gpio_setpin(S3C2410_GPF5, 1);

          194 s3c2410_gpio_setpin(S3C2410_GPF6, 1);

          195 s3c2410_gpio_setpin(S3C2410_GPF7, 1);

          196

          197 if (machine_is_smdk2443())

          198 smdk_nand_info.twrph0 = 50;

          199

          200 s3c_device_nand.dev.platform_data = &smdk_nand_info;

          201

          202 platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));

          203

          204 s3c2410_pm_init();

          205 }

          627 int __init s3c2410_pm_init(void)

          628 {

          629 printk("S3C2410 Power Management, (c) 2004 Simtec Electronicsn");

          630

          631 suspend_set_ops(&s3c2410_pm_ops);

          632 return 0;

          633 }

          這些設(shè)備在smdk2410_init函數(shù)(對應(yīng)S3C2410)或smdk2440_machine_init函數(shù)(對應(yīng)S3C2440)中,通過plat_add_devices函數(shù)注冊進(jìn)內(nèi)核中。

           Flash設(shè)備s3c2410_device_nand在include/arch/arm/plat-s3c24xx/devs.c中的定義如下:

          201 struct platform_device s3c_device_nand = {

          202 .name = "s3c2410-nand",

          203 .id = -1,

          204 .num_resources = ARRAY_SIZE(s3c_nand_resource),

          205 .resource = s3c_nand_resource,

          206 };

          207

          208 EXPORT_SYMBOL(s3c_device_nand); /*導(dǎo)出符號(hào),以便外部文件引用*/

          對于S3C2440開發(fā)板,s3c_device_nand結(jié)構(gòu)的名字會(huì)在s3c244x_map_io函數(shù)中修改為“s3c2440-nand”,這個(gè)函數(shù)在include/arch/arm/plat-s3c24xx/s3c244x.c中定義如下:

          59 void __init s3c244x_map_io(struct map_desc *mach_desc, int size)

          ...

          68 s3c_device_i2c.name = "s3c2440-i2c";

          69 s3c_device_nand.name = "s3c2440-nand";

          70 s3c_device_usbgadget.name = "s3c2440-usbgadget";

          71 }

          有了 Flash設(shè)備,還要有 Flash驅(qū)動(dòng)程序,內(nèi)核針對S3C2410、S3C2412、S3C2440定義了3個(gè)驅(qū)動(dòng)。它們在include/drivers/mtd/nand/s3c2410.c中的s3c2410_nand_init函數(shù)中注冊進(jìn)內(nèi)核,如下所示:

          890 static int __init s3c2410_nand_init(void)

          891 {

          892 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronicsn");

          893

          894 platform_driver_register(&s3c2412_nand_driver);

          895 platform_driver_register(&s3c2440_nand_driver);

          896 return platform_driver_register(&s3c2410_nand_driver);

          897 }

          其中的S3C2410_nand_driver結(jié)構(gòu)是在include/drivers/mtd/nand/s3c2410.c中定義,如下所示:

          857 static struct platform_driver s3c2410_nand_driver = {

          858 .probe = s3c2410_nand_probe,

          859 .remove = s3c2410_nand_remove,

          860 .suspend = s3c24xx_nand_suspend,

          861 .resume = s3c24xx_nand_resume,

          862 .driver = {

          863 .name = "s3c2410-nand",

          864 .owner = THIS_MODULE,

          865 },

          866 };

          可見,s3c_device_nand結(jié)構(gòu)和s3c2410_nand_driver結(jié)構(gòu)中的name成員相同,都是“s3c2410-nand”。platform_driver_register函數(shù)就是根據(jù)這點(diǎn)確定它們是匹配的,所以調(diào)用s3c2410_nand_probe函數(shù)枚舉NAND Flash設(shè)備s3c2410_device_nand。



        關(guān)鍵詞: NAND 驅(qū)動(dòng)

        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 东台市| 永安市| 晴隆县| 棋牌| 平乐县| 大荔县| 澄迈县| 特克斯县| 淮南市| 邵阳县| 青海省| 岱山县| 宜黄县| 孝昌县| 财经| 彭阳县| 敦煌市| 宁南县| 察雅县| 林芝县| 潜江市| 新津县| 汕头市| 鹤岗市| 青龙| 马尔康县| 樟树市| 尉犁县| 抚州市| 黔南| 宣城市| 综艺| 四会市| 德钦县| 赤城县| 台州市| 荆州市| 中江县| 筠连县| 托里县| 乌什县|