如何?從SD卡更新NK?——(已經實現)

來源:互聯網
上載者:User

作者:gooogleman@foxmail.com    2008-12-04

          在前段時間,songtitan牛人在論壇說了一下使用SD卡更新NK的方法。如下:

http://topic.csdn.net/u/20081009/17/4E0F5E66-C7A0-43D2-B33F-14E132280F70.html

 

在CE下和在bootloader下都可以實現更新NK.
1 在CE下
可以直接用檔案系統API讀出NK.bin,放到記憶體buffer中,在通過DEVICEIOCTL的方式來調用nand驅動的接一些介面來直接對nand flash進行寫操作。

好處:跳過boot section,FAT/FAT32檔案系統的解析;對記憶體大小無要求
缺點:NAND驅動需要暴露讀寫的IOCTL,必須進入OS才能更新OS,如果OS掛了的話,無法更新。

2 bootloader下
直接對SD CONTROLLER操作來對SD卡進行讀寫,解析FAT/FAT32格式,找到NK.BIN,並能將其讀取到記憶體中,再假設NK.BIN如下載一般到記憶體中,將其燒寫到nand flash中。

好處:只要bootloader不掛,就可以對OS進行更新;
缺點:需要自己解析BOOT SECION,FAT/FAT32檔案系統;需要至少和NK.BIN大小相同的剩餘RAM

 

如果BSP本身沒有支援bootloader下的SD更新nk,自己研究還是需要不少工作量的,最好的捷徑就是能“弄到”別的平台的SD更新代碼,改動就只是SD HOST controller部分。

=======================現在我的工作就是詳細弄出怎麼實現這個東西==========================

公司要求在bootloader階段實現SD更新NK,並且說要實現用觸控螢幕操作,我覺得這個在裸奔階段實現觸控螢幕菜單太難了,簡直是不可能的事情。如果非要實現的話就一定要加上GUI,那bootloader搞的這麼大,就沒有什麼意義了。我現在覺得有一種方法可行:就是放棄使用SD卡更新NK的辦法,而是在flash裡面備份一個NK,更新的時候就把備份NK放到啟動的NK上。這樣實現起來bootloader修改簡單,在wince起來之後實現也不困難。現在的flash都已經1G以上了,那點容量犧牲不成問題,並且SD卡也騰出了空間——哈哈,好,就模仿ghost做一個嵌入式還原精靈吧。

====================================================================================

——經過幾天的思索,我覺得在flash上做備份有點不妥當,因為flash有時候不穩定,很容易出問題。現在還是決定採用系統起來後更新NK的方法。很榮幸在這裡找了個很好的老文章——--------------------------------------wince下將flash中的內容全部讀出來

http://topic.csdn.net/u/20080530/10/8A86B2C8-1623-4AB9-ACA7-D5DE24994CF6.html內容經典,摘抄下來。

--------------------------------------------------------------------------

硬體:2410 ,64M nandflash,64M RAM

我現在在想在wince下將難道中的內容從地址0,到nandflash結束,全部讀出來,
該怎麼做!

就好像是給台式電腦做GHOST備份一樣,不同的是NANDFLASH為空白的地方我們也要讀取!

緊急,謝謝

--------------------------------------

要看你的檔案系統是否支援.因為檔案系統只能識別被分區的地方,那沒有分區的空白地區是無法通過WINCE API訪問到的.一般flash都有專用的讀寫器直接複製晶片內容的,也就是生產時用來做母片的工具。

--------------------------------------

恐怕只能自己寫一個簡單的flash driver,從頭到尾讀一遍了。wince的fat檔案系統肯定是不能保證按flash的物理地址順序讀的。

--------------------------------------

NAND上一層是DISK介面了,不會有相應的API供你讀取所有內容的。

如果能修改驅動,那麼就讓驅動開放一個特殊的IOContrl Code給你,輸入位址範圍,輸出是將位址範圍內的資料全部放到指定的buf指標地址去。Nand flash的驅動,修改FMD_OEMIoControl函數

-----------------------------------------------------------------

是標準的流介面,其實還是用DSK驅動就行,只是你自己設計一個原來沒有的IOCONTROL_CODE,通過Device的IOControl()函數傳下去時,在NAND FLASH的驅動中的IOControl直接判斷,如果滿足,就將指定範圍的資料都讀到指定的地址空間。

9樓的有個小錯誤,NAND驅動的讀函數裡已經做了ECC校正了,通過FMD_NAND_READ這樣的函數讀出來的資料是不需要再ECC校正的。

------------------------------------------------------------------------


引用 13 樓 so927 的回複:

引用 12 樓 jlctt 的回複:
修改FMD中FMD_OEMIoControl代碼,開放FMD_ReadSector/FMD_WriteSector介面訪問,然後用DeviceIoControl去訪問整個NAND Flash.

明白您的意思了,我覺得也可以這樣實現,謝謝提醒,

不過還有一個問題,我會不會把壞塊也一起讀出來了,每讀一個塊我是不是都需要檢測一下是不是壞塊呢

是的,需要的

=========================================抄貼結束======================================

 

——這幾天,我首先在學習EVC讀寫SD卡程式,剛開始以為可以像PC一樣malloc幾十M的記憶體,結果實驗發現當讀400K寫字板的時候已經那個非常慢,看來一次性讀寫30M的想法是行不通的。今天終於分段讀寫30M核心檔案成功,下面是關鍵代碼。

C/C++ code
   
  1. //我把30M的檔案讀出來,再存放到一個檔案,已經完全可行。該結貼了,是修改flash驅動的時候了。晚上回去結貼。
  2. //==================從檔案中分段讀出資料,每次30K ,讀1024次,共30M====================
  3.     for (unsigned int count=0;count<READCOUNT;count++)
  4.     {
  5.         SetFilePointer(hFile, m_FilePointer, NULL, FILE_BEGIN);        /* 移動檔案指標到檔案開頭 */    
  6.         if (ret == 0xFFFFFFFF)
  7.         {
  8.             MessageBox(_T("將檔案指標移至檔案指定處失敗!"));
  9.             return;    
  10.         }
  11.         pcharbuff=(char *)malloc(READSIZE);                            //每次申請30K的記憶體
  12.         ret = ReadFile(hFile, pcharbuff, READSIZE, &actlen, NULL);    /* 從檔案中分段讀出資料,每次30K */
  13.         if (ret == FALSE)    
  14.             MessageBox(_T("讀檔案失敗!"));    
  15.     
  16.     
  17.         //--------------------write read file to wogo.nb0-----------------------
  18.         //--讀出30K,就寫30K
  19.         SetFilePointer(hTestFile, m_FilePointer, NULL, FILE_BEGIN);        /* 移動檔案指標到檔案開頭 */    
  20.         if (ret == 0xFFFFFFFF)
  21.         {
  22.             MessageBox(_T("將檔案指標移至檔案指定處失敗!"));
  23.             return;    
  24.         }
  25.         ret = WriteFile(hTestFile, pcharbuff, READSIZE, &writelen, NULL);    /* 將資料寫入檔案中 */
  26.         if (ret == FALSE)    
  27.             MessageBox(_T("寫檔案失敗!"));
  28.         
  29.         free((void *)pcharbuff);//釋放記憶體
  30.     
  31.         
  32.         m_FilePointer=m_FilePointer+READSIZE;//每次檔案指標下移30K
  33.         //if (count==1023)
  34.         //{
  35.         //    MessageBox(_T("讀檔案成功!"));
  36.         //}
  37.     }
——做這個除了瞭解了一下wince 虛擬記憶體申請以外,還得出:不管是二進位檔案還是文字檔,
使用的讀寫函數都一樣,要想把二進位的資料讀出來顯示,不能使用顯示文字檔的方法。
=============================flash驅動修改部分==============================

http://blog.csdn.net/nanjianhui/archive/2008/03/19/2196466.aspx微軟MVP的文章
——應用程式直接控制flash

===========================採用wince運行下更新NK的方法成功===========================

——現在公布要點。

一、在FMD中增加下面代碼

  1. //------------------------------------------------------------------------------
  2. //---------------------------應用程式和flash直接通訊-------希望大家看了有啟發---
  3. //------------------------------------------------------------------------------
  4. static DWORD g_dwStartSector=2*64;
  5. BOOL  FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
  6. {
  7.     
  8.     switch(dwIoControlCode)
  9.     {
  10.         case 0x77777777:
  11.             for(unsigned int i=2;i<=242;i++)//30M NK 佔用240 block
  12.                 FMD_EraseBlock(i);  //察除NK所佔地區30M 
  13.             RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_EraseBlock (0x%x)./r/n"), dwIoControlCode));
  14.              
  15.             break;
  16.         case 0x12345678:
  17.              //寫入NK所佔地區——這個要看eboot中的函數才知道具體起始block
  18.              //RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_WriteSector(0x%x)./r/n"), dwIoControlCode));
  19.              
  20.              RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_WriteSector(0x%x)./r/n"), nInBufSize));
  21.              RETAILMSG(1, (TEXT("FMD_OEMIoControl: nInBufSize=%d./r/n"), nInBufSize));
  22.              //for(unsigned int k=0;k<nInBufSize;k++)
  23.              // {
  24.              //     FMD_WriteSector(g_dwStartSector,pInBuf,NULL,1);
  25.              //     g_dwStartSector=g_dwStartSector+1;
  26.              // }
  27. //FMD_WriteSector函數的參數很關鍵,pInBuf是應用程式傳入,並且大小隻能是一個page
  28. //FMD_WriteSector的代碼推測出,pInBuf只能是一個page
  29.              FMD_WriteSector(g_dwStartSector,pInBuf,NULL,1);
  30.              if(g_dwStartSector<=242*64)
  31.                 g_dwStartSector=g_dwStartSector+1;
  32.              break;
  33.             
  34.                                                         
  35.         default:
  36.             RETAILMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x)./r/n"), dwIoControlCode));
  37.             return(FALSE);
  38.     }
  39.     return TRUE; 
  40. }

轉載請標明:作者wogoyixikexie@gliet.桂林電子科技大學一系科協。如有錯誤,希望能夠留言指出;如果你有更加好的方法,也請在部落格後面留言,我會感激你的批評和分享。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.