昨天我們檢視了flash寫入失敗的相關代碼。我在懷疑自己是不是在配置的時候選錯了晶片型号。從電路原理圖上看,我們的norflash晶片型号是:am29lv160db/sst39vf1601。
經過一番查找,終于搞明白了。
在 u-boot/board/ 目錄下有很多個檔案夾。每一個檔案夾以闆子的型号指令,比如smdk2400,smdk2410,my2440等。在每一個檔案夾下都有該闆子單獨的裝置 驅動檔案。在my2440這個檔案夾下就有一個flash.c檔案。這個檔案裡定義了norflash驅動函數。
既然我們找到了這個檔案,那麼我們就用axd單步進行調試一下。
單步執行 > protect off all 時,運作到do_protect()函數。我發現在
紅框所地的代碼并沒有執行。我檢視了一下 include/configs/my2440.h檔案,沒有搜到cfg_flash_protection 宏的定義。不知道這會對燒寫u-boot到norflash有無影響。
我還遇到一個問題,為什麼在axd裡調試u-boot,看不到變量裡的值。我記得用ads編寫代碼再用axd調試時都可以看到的嘛。如何解決?
在board/my2440/flash.c檔案中搜尋宏 err_prog_error.
可以搜到兩處使用了err_prog_error宏:
volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
int flash_erase (flash_info_t * info, int s_first, int s_last)
其中write_hword()應該是在指令 “cp.b 0x30000000 0 40000”時出錯的主要原因。看代碼如下:
見l63~64可知,隻有chip的值為err或則從addr位址上讀出來的資料不等于data就會傳回err_prog_error錯誤。
err隻在代碼的44,56兩處出現。但如果執行了44行的代那,那麼chip的值應該是err|tmo=0x03,不等于err。那麼隻有在56行這個有可能。分析一下50~57行代碼的功能:
在40行 result = *addr,從addr位址上讀取一個資料。在50行處檢查result的第5位 ( (result & 0xffff ) & bit_program_error),如果為1則表示寫錯誤。然後在51行再讀取一次,再進行一次檢查。如果資料正常卻将chip置為ready,否則置為err。
為了找到倒底是哪裡出錯,在将在這裡加調試資訊。
編譯後生成u-boot.bin檔案,然後複制到e:u-boot-gdbu-boot.bin。再進行調試。
在終端看到如上:
可見,得到失敗的原因了,是359行處 (*addr != data) 條件不成立。不過有一點問題,如果*addr讀出的值與讀的次數有關就可能不太确定了。還是再小改一下:
結果再次執行,顯示結果:
看來,還真是讀出來的值不一緻引起的。這個該怎麼辦呢?