S3C6410學(xué)習(xí)——Nand flash陷阱
我的開(kāi)發(fā)板式Tiny6410,配置的Nand flash是K9GAG08U0E,塊空間1M,頁(yè)空間8K。于是可以實(shí)現(xiàn)nand_read函數(shù):
本文引用地址:http://m.butianyuan.cn/article/201611/322802.htm- intnand_read(unsignedintnand_start,unsignedintddr_start,unsignedintlen)
- {
- unsignedlongrest=len;
- unsignedlongaddr=nand_start;
- unsignedlongpage;
- unsignedchar*dest=(unsignedchar*)ddr_start;
- inti;
- nand_select();
- while(rest>0){
- nand_cmd(0x00);
- nand_addr(addr);
- nand_cmd(0x30);
- nand_ready();
- page=rest>PAGE_SIZE?PAGE_SIZE:rest;
- for(i=0;i!=page;++i){
- *dest++=NFDATA;
- }
- rest-=page;
- addr+=page;
- }
- nand_deselect();
- return0;
- }
如上,我們可以完成必要的硬件初始化后用nand_read(0, 0x50000000, __bss_start-_start)來(lái)將完整的代碼從Nand搬移到DDR中,開(kāi)始我也是這樣想的,但是發(fā)現(xiàn)代碼根本無(wú)法運(yùn)行,后來(lái)調(diào)試了一下發(fā)現(xiàn),這樣只將代碼的前2K拷貝到DDR中,接下來(lái)的6K代碼丟失了,而再接下來(lái)的代碼是正確的!這很奇怪啊,手冊(cè)中明卻指出,該Nand的頁(yè)大小為8KB,但為何我實(shí)際讀取時(shí)卻只能讀取到2KB呢?原來(lái)S3C6410啟動(dòng)時(shí)拷貝的8K代碼不是存儲(chǔ)在Nand flash的第一頁(yè)上,而是存儲(chǔ)在Nand flash的前4頁(yè)上,每頁(yè)2K,總共8K,這是S3C6410芯片的硬件結(jié)構(gòu)決定的!也就是說(shuō),雖然我們的Nand flash的頁(yè)大小是8K,但是S3C6410為了適應(yīng)各種型號(hào)的Nand flash并保證硬件能正確的拷貝Nand flash中的前8K到SRAM中,硬性的加上這一規(guī)定。因此,nand2ddr函數(shù)應(yīng)該這樣寫(xiě):
- voidcopy2ddr(unsignedlonglength){
- unsignedlongrest=length;
- unsignedlongsize;
- unsignedlongi;
- for(i=0;i!=4;++i){
- size=rest>2048?2048:rest;
- nand_read(PAGE_SIZE*i,0x50000000+i*2048,size);
- rest-=size;
- if(rest==0)
- return;
- }
- nand_read(PAGE_SIZE*4,0x50000000+PAGE_SIZE,rest);
- }
對(duì)應(yīng)還有寫(xiě)操作,原理一樣,逆著寫(xiě)回去,這里就不分析原理了,nand_write函數(shù):
- voidnand_write(unsignedintnand_start,unsignedchar*buf,unsignedintlen)
- {
- unsignedlongcount=0;
- unsignedlongaddr=nand_start;
- inti=nand_start%PAGE_SIZE;
- nand_select();
- while(count
- {
- nand_cmd(0x80);
- nand_addr(addr);
- for(;i
- {
- NFDATA=buf[count++];
- addr++;
- }
- nand_cmd(0x10);
- nand_ready();
- i=0;
- }
- nand_deselect();
- }
store2nand函數(shù)應(yīng)該這樣寫(xiě):
- voidstore2nand(unsignedlongddr_start,unsignedlonglength){
- unsignedchar*src=(unsignedchar*)ddr_start;
- unsignedlongrest=length;
- unsignedlongsize;
- unsignedlongi;
- for(i=0;i!=4;++i){
- size=rest>2048?2048:rest;
- nand_write(PAGE_SIZE*i,src+2048*i,size);
- rest-=size;
- if(rest==0)
- return;
- }
- nand_write(PAGE_SIZE*4,src+2048*4,rest);
- }
store2nand函數(shù)可以用來(lái)下載程序時(shí)寫(xiě)nand用,如果不按照這種方式將程序?qū)懭雗and,硬件就無(wú)法正確加載Nand flash的前8K代碼,程序也就無(wú)法正常運(yùn)行。
下面是我自己寫(xiě)的Tiny6410裸機(jī)程序,arm-linux-gcc環(huán)境,如果需要可以下載了看看,代碼實(shí)現(xiàn)了系統(tǒng)時(shí)鐘、DDR、Nand flash還有串口的初始化,下面是鏈接地址,以后還會(huì)繼續(xù)完善:
下載地址:(前段時(shí)間忘了改了)
http://download.csdn.net/detail/girlkoo/4690705
評(píng)論