新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Linux下NAND FLASH驅動開發

        Linux下NAND FLASH驅動開發

        作者: 時間:2016-10-08 來源:網絡 收藏

        【 Nand flash 驅動工作原理】

        在介紹具體如何寫 Nand Flash 驅動之前,我們先要了解,大概的,整個系統,和 Nand Flash 相關的部分的驅動工作流程,這樣,對于后面的驅動實現,才能更加清楚機制,才更容易實現,否則就是,即使寫完了代碼,也還是沒搞懂系統是如何工作的了。

        讓我們以最常見的, Linux 內核中已經有的三星的 Nand Flash 驅動,來解釋 Nand Flash 驅動具體流程和原理。

        此處是參考 2.6.29 版本的 Linux 源碼中的 /drivers/mtd/nand/s3c2410.c ,以 2410 為例。

        1. 在 nand flash 驅動加載后,第一步,就是去調用對應的 init 函數, s3c2410_nand_init, 去將在 nand flash 驅動注冊到 Linux 驅動框架中。

        2. 驅動本身,真正開始,是從 probe 函數, s3c2410_nand_probe->s3c24xx_nand_probe,

        在 probe 過程中,去用 clk_enable 打開 nand flash 控制器的 clock 時鐘,用 request_mem_region 去申請驅動所需要的一些內存等相關資源。然后,在 s3c2410_nand_inithw 中,去初始化硬件相關的部分,主要是關于時鐘頻率的計算,以及啟用 nand flash 控制器,使得硬件初始化好了,后面才能正常工作。

        3. 需要多解釋一下的,是這部分代碼:

        for (setno = 0; setno nr_sets; setno++, nmtd++) {

        pr_debug(initialising set %d (%p, info %p)/n, setno, nmtd, info);

        /* 調用 init chip 去掛載你的 nand 驅動的底層函數到 nand flash 的結構體中,以及設置對應的 ecc mode ,掛載 ecc 相關的函數 */

        s3c2410_nand_init_chip(info, nmtd, sets);

        /* scan_ident ,掃描 nand 設備,設置 nand flash 的默認函數,獲得物理設備的具體型號以及對應各個特性參數,這部分算出來的一些值,對于 nand flash 來說,是最主要的參數,比如 nand falsh 的芯片的大小,塊大小,頁大小等。 */

        nmtd->scan_res = nand_scan_ident(nmtd->mtd,

        (sets) ? sets->nr_chips : 1);

        if (nmtd->scan_res == 0) {

        s3c2410_nand_update_chip(info, nmtd);

        /* scan tail ,從名字就可以看出來,是掃描的后一階段,此時,經過前面的 scan_ident ,我們已經獲得對應 nand flash 的硬件的各個參數,然后就可以在 scan tail 中,根據這些參數,去設置其他一些重要參數,尤其是 ecc 的 layout ,即 ecc 是如何在 oob 中擺放的,最后,再去進行一些初始化操作,主要是根據你的驅動,如果沒有實現一些函數的話,那么就用系統默認的。 */

        nand_scan_tail(nmtd->mtd);

        /* add partion ,根據你的 nand flash 的分區設置,去分區 */

        s3c2410_nand_add_partition(info, nmtd, sets);

        }

        if (sets != NULL)

        sets++;

        }

        4. 等所有的參數都計算好了,函數都掛載完畢,系統就可以正常工作了。

        上層訪問你的 nand falsh 中的數據的時候,通過 MTD 層,一層層調用,最后調用到你所實現的那些底層訪問硬件數據 / 緩存的函數中。

        【 Linux 下 nand flash 驅動編寫步驟簡介】

        關于上面提到的,在 nand_scan_tail 的時候,系統會根據你的驅動,如果沒有實現一些函數的話,那么就用系統默認的。如果實現了自己的函數,就用你的。

        估計很多人就會問了,那么到底我要實現哪些函數呢,而又有哪些是可以不實現,用系統默認的就可以了呢。

        此問題的,就是我們下面要介紹的,也就是,你要實現的,你的驅動最少要做哪些工作,才能使整個 nand flash 工作起來。

        1. 對于驅動框架部分

        其實,要了解,關于驅動框架部分,你所要做的事情的話,只要看看三星的整個 nand flash 驅動中的這個結構體,就差不多了:

        static struct platform_driver s3c2410_nand_driver = {

        .probe = s3c2410_nand_probe,

        .remove = s3c2410_nand_remove,

        .suspend = s3c24xx_nand_suspend,

        .resume = s3c24xx_nand_resume,

        .driver = {

        .name = s3c2410-nand,

        .owner = THIS_MODULE,

        },

        };

        對于上面這個結構體,沒多少要解釋的。從名字,就能看出來:

        ( 1 ) probe 就是系統“探測”,就是前面解釋的整個過程,這個過程中的多數步驟,都是和你自己的 nand flash 相關的,尤其是那些硬件初始化部分,是你必須要自己實現的。

        ( 2 ) remove ,就是和 probe 對應的,“反初始化”相關的動作。主要是釋放系統相關資源和關閉硬件的時鐘等常見操作了。

        (3)suspend 和 resume ,對于很多沒用到電源管理的情況下,至少對于我們剛開始寫基本的驅動的時候,可以不用關心,放個空函數即可。

        2. 對于 nand flash 底層操作實現部分

        而對于底層硬件操作的有些函數,總體上說,都可以在上面提到的 s3c2410_nand_init_chip 中找到:

        static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,

        struct s3c2410_nand_mtd *nmtd,

        struct s3c2410_nand_set *set)

        {

        struct nand_chip *chip = nmtd->chip;

        void __iomem *regs = info->regs;

        chip->write_buf = s3c2410_nand_write_buf ;

        chip->read_buf = s3c2410_nand_read_buf ;

        chip->select_chip = s3c2410_nand_select_chip ;

        chip->chip_delay = 50;

        chip->priv = nmtd;

        chip->options = 0;

        chip->controller = info->controller;

        switch (info->cpu_type) {

        case TYPE_S3C2410:

        /* nand flash 控制器中,一般都有對應的數據寄存器,用于給你往里面寫數據,表示將要讀取或寫入多少個字節 (byte,u8)/ 字 (word,u32) ,所以,此處,你要給出地址,以便后面的操作所使用 */

        chip->IO_ADDR_W = regs + S3C2410_NFDATA;



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 荥经县| 宁明县| 蒙阴县| 盘山县| 塔河县| 南陵县| 禄丰县| 赞皇县| 神农架林区| 泾源县| 巨鹿县| 土默特右旗| 伽师县| 故城县| 泰宁县| 马山县| 常德市| 郁南县| 浦城县| 新昌县| 贵德县| 陆河县| 广饶县| 通州区| 同心县| 荔波县| 兴国县| 固镇县| 留坝县| 武城县| 山阳县| 如皋市| 洛隆县| 山阴县| 象州县| 噶尔县| 泽州县| 集安市| 茶陵县| 双流县| 镇巴县|