成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

SylixOS下基于NUC970的NAND驅(qū)動

開發(fā)環(huán)境

  1. 開發(fā)環(huán)境

    宿主機: Windows7 64bits 系統(tǒng)

    創(chuàng)新互聯(lián)是專業(yè)的大余網(wǎng)站建設(shè)公司,大余接單;提供網(wǎng)站制作、網(wǎng)站設(shè)計,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行大余網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!

    開發(fā)板: 安米MDK972

    軟件環(huán)境: RealEvo-IDE3.0

    NAND Flash: S34ML02G100TF100

  2. S34ML02G100TF100芯片參數(shù)

  • Density:2 Gbit

  • Input / Output Bus Width: 8-bits

  • Page Size:2112 (2048 + 64) bytes; 64 bytes is spare area

  • Block Size: 64 Pages;128k + 4k bytes

  • Plane Size: 1024 Blocks per Plane;128M + 4M bytes

  • Device Size: 2 Planes per Device or 256 Mbyte

NAND控制器結(jié)構(gòu)

NUC970的NAND控制器包含在FMI中。FMI分為DMA單元和FMI單元。對于NAND,支持單一DMA通道和硬件ECC,如圖 2-1所示。

SylixOS下基于NUC970的NAND驅(qū)動

圖 2-1   NUC970 NAND控制器

 

技術(shù)實現(xiàn)

  1. 驅(qū)動框架

    SylixOS中NAND Flsh的驅(qū)動框架如圖 3-1所示。NAND通用驅(qū)動主要在fs/mtd/nand/nand_base.c中,該文件包含了NAND的通用操作。驅(qū)動工程師需要在NAND通用驅(qū)動的基礎(chǔ)上實現(xiàn)與硬件相關(guān)的驅(qū)動層的結(jié)構(gòu)體(nand_chip),該結(jié)構(gòu)體包含了對具體硬件相關(guān)的控制和操作函數(shù),以及相關(guān)硬件參數(shù)和配置信息。MTD層與文件系統(tǒng),SylixOS已經(jīng)完全實現(xiàn),不需要驅(qū)動工程師實現(xiàn)。

    SylixOS下基于NUC970的NAND驅(qū)動

    圖 3-1   NAND驅(qū)動框架

  2. 框架實現(xiàn)

    NAND驅(qū)動需要完成NAND控制器、ECC的配置以及NAND的相關(guān)操作函數(shù)及文件系統(tǒng)掛載,如果使用硬件ECC一般自己定義OOB布局。NUC970驅(qū)動實現(xiàn)的操作如程序清單 3-1所示。

    程序清單 3-1   NAND實現(xiàn)框架

        nandchipNand->cmd_ctrl        = hwControl;
        nandchipNand->cmdfunc         = nandCommand;
        nandchipNand->dev_ready       = devReady;
        nandchipNand->select_chip     = chipSelect;
        nandchipNand->read_byte       = nandReadByte;
        nandchipNand->write_buf       = nandWriteBuf;
        nandchipNand->read_buf        = nandReadBuf;
        nandchipNand->chip_delay      = 50;
        nandchipNand->ecc.mode        = NAND_ECC_HW_OOB_FIRST;
        nandchipNand->ecc.hwctl       = nandEnableHwEcc;
        nandchipNand->ecc.calculate   = nandCalculateEcc;
        nandchipNand->ecc.correct     = nandCorrectData;
        nandchipNand->ecc.write_page  = nandWritePageHwEcc;
        nandchipNand->ecc.read_page   = nandReadPageHwEccOobFirst;
        nandchipNand->ecc.read_oob    = nandReadoobHwEcc;
    nandchipNand->ecc.layout      = &__Gpnuc970nandoob;

     

  3. 控制器初始化

    控制器初始化主要實現(xiàn)了模塊時鐘使能、管腳復(fù)用、時序設(shè)置、片選、解除寫保護、頁大小、軟件復(fù)位等操作。

  4. ECC配置

    ECC配置主要設(shè)置冗余區(qū)大小,保護前3字節(jié),自動寫校驗值到NAND,設(shè)置算法等級,ECC使能等操作。

  5. 函數(shù)cmd_ctrl

    該函數(shù)主要實現(xiàn)對ALE/CLE/nCE的控制,同時用來寫命令和地址。

    程序清單 3-2  命令控制函數(shù)

     

    static VOID hwControl (struct mtd_info  *pMtd, INT  iCmd, UINT  uiCtrl)
    {
        struct nand_chip *pChip = pMtd->priv;
    
        if (uiCtrl & NAND_CTRL_CHANGE) {
            ULONG IO_ADDR_W = (ULONG)REG_NANDDATA;
    
            if ((uiCtrl & NAND_CLE)) {
                IO_ADDR_W = REG_NANDCMD;
            }
            if ((uiCtrl & NAND_ALE)) {
                IO_ADDR_W = REG_NANDADDR;
            }
    
            pChip->IO_ADDR_W = (VOID *)IO_ADDR_W;
        }
    
        if (iCmd != NAND_CMD_NONE) {
            writeb(iCmd, pChip->IO_ADDR_W);
        }
    }
  6. 函數(shù)cmdfunc

    該函數(shù)主要實現(xiàn)向芯片中寫命令的功能,在系統(tǒng)提供的默認(rèn)函數(shù)中通過調(diào)用cmd_ctrl函數(shù)來實現(xiàn)具體寫操作。由于NUC970的控制器需在最后一個地址周期手動設(shè)置EOA位,無法使用默認(rèn)函數(shù),差異代碼如程序清單 3-3所示:

    程序清單 3-3   命令功能函數(shù)差異代碼

    writel((iColumn >> BUS_WIDTH) | NANDADDR_EOA, REG_NANDADDR);

     

  7. 函數(shù)dev_ready

    該函數(shù)主要用來獲得設(shè)備ready/busy引腳狀態(tài)。如果該函數(shù)指針設(shè)置為NULL無法獲得ready/busy引腳狀態(tài),則ready/busy信息需要通過讀取NAND芯片的狀態(tài)寄存器。代碼實現(xiàn)如程序清單 3-4所示。

    程序清單 3-4  獲得NAND狀態(tài)

        return ((readl(REG_NANDINTSTS) & NANDINTSTS_RB0_Status) ? 1 : 0);

     

  8. 函數(shù)read_byte

    該函數(shù)功能為從NAND芯片讀取一個字節(jié),代碼如程序清單 3-5所示。

    程序清單 3-5  從NAND讀一個字節(jié)

     

        return ((UCHAR)readl(REG_NANDDATA));

     

  9. 函數(shù)write_buf

    該函數(shù)功能為從一個緩沖區(qū)寫數(shù)數(shù)據(jù)到NAND芯片。代碼實現(xiàn)如程序清單 3-6。

    程序清單 3-6  寫緩沖區(qū)數(shù)據(jù)到NAND

     

        for (i = 0; i < iLen; i++) {
            writel(pucbuf[i], REG_NANDDATA);
        }

     

  10. 函數(shù)read_buf

    該函數(shù)功能為從NAND芯片讀數(shù)據(jù)到一個緩沖區(qū)。代碼實現(xiàn)如程序清單 3-7所示。

    程序清單 3-7  讀數(shù)據(jù)到緩沖區(qū)

     

        for (i = 0; i < iLen; i++) {
            writel(pucbuf[i], REG_NANDDATA);
        }

     

  11. 函數(shù)ecc.hwctl

    該函數(shù)用于控制硬件ECC發(fā)生器,只有在使用硬件ECC時實現(xiàn)。本例的硬件校驗在傳輸中實現(xiàn),因此該函數(shù)為空實現(xiàn)。

  12. 函數(shù)ecc.calculate

    該函數(shù)用于ECC計算,或從ECC硬件中讀回。本例的硬件校驗在傳輸中實現(xiàn),因此該函數(shù)為空實現(xiàn)。

  13. 函數(shù)ecc.correct

    該函數(shù)用于ECC校正。本例的硬件校驗在傳輸中實現(xiàn),因此該函數(shù)為空實現(xiàn)。

  14. 函數(shù)ecc.write_page

    該函數(shù)主要實現(xiàn)帶ECC的寫一頁數(shù)據(jù)到NAND芯片。在傳輸?shù)倪^程中,ECC電路會自動計算ECC校驗值,并存儲到控制器分配的寄存器組中。完成傳輸后寄存器組中的OOB數(shù)據(jù)會根據(jù)設(shè)置自動寫進NAND芯片。實現(xiàn)流程如程序清單 3-8所示。

    程序清單 3-8  帶硬件ECC的寫頁

    static INT nandWritePageHwEcc (struct mtd_info   *pMtd,
                                   struct nand_chip  *pChip,
                                   const UCHAR       *pucBuf,
                                   INT                iOobRequired)
    {
        UCHAR          *pucEccCalc   = pChip->buffers->ecccalc;
        UINT             uiEccBytes  = pChip->ecc.layout->eccbytes;
        register CHAR     *pcPtr     = (CHAR *)REG_NANDRA0;
    
        memset((VOID *)pcPtr, 0xFF, pMtd->oobsize);
        memcpy((VOID *)pcPtr, (VOID *)pChip->oob_poi,  pMtd->oobsize - pChip->ecc.total);
    
        nandDmaTransfer(pMtd, pucBuf, pMtd->writesize , 0x1);
    
        /*
         *  Copy parity code in SMRA to calc
         */
        memcpy((VOID *)pucEccCalc,
               (VOID *)(REG_NANDRA0 + (pMtd->oobsize - pChip->ecc.total)),
               pChip->ecc.total);
    
        /*
         *  Copy parity code in calc to oob_poi
         */
        memcpy((VOID *)(pChip->oob_poi + uiEccBytes),
                (VOID *)pucEccCalc,
                pChip->ecc.total);
    
        return 0;
    }

     

  15. 函數(shù)ecc.read_page

    該函數(shù)主要實現(xiàn)帶ECC校驗的從NAND芯片讀出一頁數(shù)據(jù)。本例為硬件ECC,需要先讀出OOB區(qū)數(shù)據(jù)到控制器分配的寄存器組中。在數(shù)據(jù)傳輸?shù)倪^程中,ECC電路會計算ECC校驗值,并與寄存器組中的值比較,檢查是否產(chǎn)生錯誤,以及定位和計算校錯值。若產(chǎn)生錯誤,程序需要根據(jù)錯誤位置和錯誤值進行校錯。具體流程如程序清單 3-9所示:

    程序清單 3-9  帶ECC的讀頁

     

    static INT nandReadPageHwEccOobFirst (struct mtd_info   *pMtd,
                                          struct nand_chip  *pChip,
                                          UCHAR             *ucBuf,
                                          INT                iOobRequired,
                                          INT                iPage)
    {
        INT      iEccSize = pChip->ecc.size;
        CHAR    *pcPtr    = (CHAR *)REG_NANDRA0;
    
        /*
         *  At first, read the OOB area
         */
        nandCommand(pMtd, NAND_CMD_READOOB, 0, iPage);
        nandReadBuf(pMtd, pChip->oob_poi, pMtd->oobsize);
    
        /*
         *  Second, copy OOB data to SMRA for page read
         */
        memcpy((VOID *)pcPtr, (VOID *)pChip->oob_poi, pMtd->oobsize);
    
        /*
         *  Third, read data from nand
         */
        nandCommand(pMtd, NAND_CMD_READ0, 0, iPage);
        nandDmaTransfer(pMtd, ucBuf, iEccSize, 0x0);
    
        /*
         *  Fouth, restore OOB data from SMRA
         */
        memcpy((VOID *)pChip->oob_poi, (VOID *)pcPtr, pMtd->oobsize);
    
        return 0;
    }

     

  16. 函數(shù)ecc.read_oob

    該函數(shù)主要實現(xiàn)從芯片中讀取OOB數(shù)據(jù)。實現(xiàn)流程如程序清單 3-10所示。

    程序清單 3-10  帶硬件ECC的讀OOB區(qū)數(shù)據(jù)

     

    static INT nandReadoobHwEcc(struct mtd_info  *pMtd, struct nand_chip  *pChip, INT  iPage)
    {
        CHAR *cPtr = (char *)REG_NANDRA0;
    
        /*
         *  At first, read the OOB area
         */
        nandCommand(pMtd, NAND_CMD_READOOB, 0, iPage);
        nandReadBuf(pMtd, pChip->oob_poi, pMtd->oobsize);
    
        /*
         *  Second, copy OOB data to SMRA for page read
         */
        memcpy ((VOID *)cPtr, (VOID *)pChip->oob_poi, pMtd->oobsize);
    
        return 0;
    }

     

  17. ecc.layout

    nand_ecc為ECC布局控制結(jié)構(gòu)體。通過該結(jié)構(gòu)體配置OOB區(qū)中ECC的位數(shù)和位置,可用位數(shù)和空閑位數(shù)。本例通過調(diào)用程序清單 3-11代碼實現(xiàn)OOB區(qū)的布局控制。

    程序清單 3-11   OOB區(qū)布局

     

    static VOID oobTableLayout ( struct nand_ecclayout  *pNandOOBTbl, INT  iOobSize , INT  iEccBytes)
    {
        pNandOOBTbl->eccbytes     = iEccBytes;
    
        pNandOOBTbl->oobavail     = iOobSize - DEF_RESERVER_OOB_SIZE_FOR_MARKER - iEccBytes ;
    
        pNandOOBTbl->oobfree[0].offset = DEF_RESERVER_OOB_SIZE_FOR_MARKER;     /*  Bad block marker size    */
    
        pNandOOBTbl->oobfree[0].length = iOobSize - iEccBytes - pNandOOBTbl->oobfree[0].offset ;
    }

     

  18. 文件系統(tǒng)掛載

    在SylixOS下NAND Flash通常掛載YAFFS文件系統(tǒng),并分為n0和n1分區(qū),其中n0分區(qū)用作啟動分區(qū),n1作為應(yīng)用分區(qū)。掛載流程如程序清單 3-12所示。

    程序清單 3-12  文件系統(tǒng)掛掛載

     

        yaffs_mtd_drv_install(&__GyaffsdevBootDev);
        yaffs_mtd_drv_install(&__GyaffsdevCommDev);
    
        yaffs_add_device(&__GyaffsdevBootDev);                              /* add to yaffs device table    */
        yaffs_add_device(&__GyaffsdevCommDev);                              /* add to yaffs device table    */
    
        yaffs_mount(cBootDevName);
        yaffs_mount(cCommDevName);

     

參考資料

無。

分享題目:SylixOS下基于NUC970的NAND驅(qū)動
網(wǎng)頁URL:http://jinyejixie.com/article42/pspjhc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、軟件開發(fā)、自適應(yīng)網(wǎng)站、App設(shè)計、網(wǎng)站內(nèi)鏈、靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
十堰市| 乌兰浩特市| 桃园县| 云阳县| 彭山县| 囊谦县| 大竹县| 丹江口市| 团风县| 修武县| 兴城市| 渭源县| 盐亭县| 富裕县| 晋城| 秀山| 滨海县| 大埔区| 婺源县| 孝义市| 南康市| 曲靖市| 旅游| 本溪市| 东阿县| 河源市| 临沧市| 自治县| 彰化市| 尼勒克县| 太谷县| 达尔| 敖汉旗| 枣强县| 哈巴河县| 乐陵市| 万荣县| 吴忠市| 监利县| 宁国市| 台东市|