新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > S3C6410學習——Nand flash陷阱

        S3C6410學習——Nand flash陷阱

        作者: 時間:2016-11-28 來源:網絡 收藏
        當系統以Nand方式啟動時,硬件將Nand Flash的前8KB拷貝到Steppingstone,然后從0地址開始運行程序,在這8KB以內代碼中,我們需要完成必要的硬件初始化,如果代碼超過8K,我們還需要將剩余代碼的搬移到鏈接地址處,一般在SDRAM/DDR中。其中,硬件部分需要初始化系統時鐘、DDR和NAND Flash三部分。這就是S3C6410以Nand方式啟動時的大致流程,看上去跟ARM9(S3C2440)沒有差別,但是如果您親自動手寫一下這個啟動過程,你會發現ARM9跟ARM11還是存在若干差別的,這里我要說的是Nand裸機驅動的問題。述了S3C6410的Nand方式啟動流程,看上去跟ARM9(S3C2440)沒有太大差別,但是如果您親自動手寫一下這個啟動過程,你會發現ARM9跟ARM11還是存在若干差別的,這里我要說的是Nand裸機驅動的問題。

        我的開發板式Tiny6410,配置的Nand flash是K9GAG08U0E,塊空間1M,頁空間8K。于是可以實現nand_read函數:

        本文引用地址:http://www.104case.com/article/201611/322802.htm
        1. intnand_read(unsignedintnand_start,unsignedintddr_start,unsignedintlen)
        2. {
        3. unsignedlongrest=len;
        4. unsignedlongaddr=nand_start;
        5. unsignedlongpage;
        6. unsignedchar*dest=(unsignedchar*)ddr_start;
        7. inti;
        8. nand_select();
        9. while(rest>0){
        10. nand_cmd(0x00);
        11. nand_addr(addr);
        12. nand_cmd(0x30);
        13. nand_ready();
        14. page=rest>PAGE_SIZE?PAGE_SIZE:rest;
        15. for(i=0;i!=page;++i){
        16. *dest++=NFDATA;
        17. }
        18. rest-=page;
        19. addr+=page;
        20. }
        21. nand_deselect();
        22. return0;
        23. }

        如上,我們可以完成必要的硬件初始化后用nand_read(0, 0x50000000, __bss_start-_start)來將完整的代碼從Nand搬移到DDR中,開始我也是這樣想的,但是發現代碼根本無法運行,后來調試了一下發現,這樣只將代碼的前2K拷貝到DDR中,接下來的6K代碼丟失了,而再接下來的代碼是正確的!這很奇怪啊,手冊中明卻指出,該Nand的頁大小為8KB,但為何我實際讀取時卻只能讀取到2KB呢?原來S3C6410啟動時拷貝的8K代碼不是存儲在Nand flash的第一頁上,而是存儲在Nand flash的前4頁上,每頁2K,總共8K,這是S3C6410芯片的硬件結構決定的!也就是說,雖然我們的Nand flash的頁大小是8K,但是S3C6410為了適應各種型號的Nand flash并保證硬件能正確的拷貝Nand flash中的前8K到SRAM中,硬性的加上這一規定。因此,nand2ddr函數應該這樣寫:

        1. voidcopy2ddr(unsignedlonglength){
        2. unsignedlongrest=length;
        3. unsignedlongsize;
        4. unsignedlongi;
        5. for(i=0;i!=4;++i){
        6. size=rest>2048?2048:rest;
        7. nand_read(PAGE_SIZE*i,0x50000000+i*2048,size);
        8. rest-=size;
        9. if(rest==0)
        10. return;
        11. }
        12. nand_read(PAGE_SIZE*4,0x50000000+PAGE_SIZE,rest);
        13. }

        對應還有寫操作,原理一樣,逆著寫回去,這里就不分析原理了,nand_write函數:

        1. voidnand_write(unsignedintnand_start,unsignedchar*buf,unsignedintlen)
        2. {
        3. unsignedlongcount=0;
        4. unsignedlongaddr=nand_start;
        5. inti=nand_start%PAGE_SIZE;
        6. nand_select();
        7. while(count
        8. {
        9. nand_cmd(0x80);
        10. nand_addr(addr);
        11. for(;i
        12. {
        13. NFDATA=buf[count++];
        14. addr++;
        15. }
        16. nand_cmd(0x10);
        17. nand_ready();
        18. i=0;
        19. }
        20. nand_deselect();
        21. }

        store2nand函數應該這樣寫:

        1. voidstore2nand(unsignedlongddr_start,unsignedlonglength){
        2. unsignedchar*src=(unsignedchar*)ddr_start;
        3. unsignedlongrest=length;
        4. unsignedlongsize;
        5. unsignedlongi;
        6. for(i=0;i!=4;++i){
        7. size=rest>2048?2048:rest;
        8. nand_write(PAGE_SIZE*i,src+2048*i,size);
        9. rest-=size;
        10. if(rest==0)
        11. return;
        12. }
        13. nand_write(PAGE_SIZE*4,src+2048*4,rest);
        14. }

        store2nand函數可以用來下載程序時寫nand用,如果不按照這種方式將程序寫入nand,硬件就無法正確加載Nand flash的前8K代碼,程序也就無法正常運行。

        下面是我自己寫的Tiny6410裸機程序,arm-linux-gcc環境,如果需要可以下載了看看,代碼實現了系統時鐘、DDR、Nand flash還有串口的初始化,下面是鏈接地址,以后還會繼續完善:

        下載地址:(前段時間忘了改了)

        http://download.csdn.net/detail/girlkoo/4690705



        關鍵詞: S3C641Nandflash陷

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 资阳市| 抚远县| 拉孜县| 滕州市| 卢氏县| 古交市| 牟定县| 绍兴市| 论坛| 洞头县| 桂林市| 大埔区| 廊坊市| 通榆县| 泗洪县| 潮州市| 漳浦县| 滨海县| 荣成市| 肇源县| 汉中市| 铜梁县| 来凤县| 乾安县| 鹤庆县| 获嘉县| 彩票| 兖州市| 通道| 靖江市| 龙川县| 台东市| 枣阳市| 静乐县| 龙南县| 天峨县| 阳山县| 昭觉县| 资中县| 浦县| 色达县|