update的邏輯流程如下:
然後編寫到rom中。
因為code自己就在rom中,為了防止把自己擦掉,所以update要先把自己拷貝到ram中去執行。
把code從rom拷貝到ram中去本以為要用彙編來寫,其實用c語言就ok了。就是簡單的buf拷貝操作。
因為arm的架構支援統一定址模型:操作device和操作ram沒有任何區別。
但是有個非常有趣的現象。
程式類似與:
//rom中的update位址
src_addr=(int32u*)update;
//ram中的update位址
dst_addr=(int32u*)(0*********);
//指標函式
jump_addr=(jump_func_type)dst_addr;
//拷貝update程式
for(i=0; i*dst_addr++=*src_addr++;
//跳轉到ram中去執行update
(*jump_addr)();
我把程式位址拷貝到偶數字址,就是死活跳轉不過去。。。
我想是不是長跳轉必須用彙編才行?
突然間恍然大悟。因為thumb code指令,pc的最低位必須是1,所以跳轉位址也必須是奇數才行。
修改之後,果然可以跳轉了。本以為這樣萬事大吉了。
但是發現,只要**稍微修改一下,就可能宕機(也就是不能跳轉到update中去了),多增加一點或者減少一點**可能就好了。
很是奇怪。
還好有jtag可以單步除錯。最後發現,跳轉的位址都是對的。
又檢視了生成的彙編檔案。
終於發現了問題的原因了:
但是函式的**實際開始位址是: 0x2000abc0,也就是偶數字址。
也就是說code是2位元組對齊的。thumb指令是16位的。。所以比然是2位元組對齊。
但是為什麼**的呼叫位址是奇數字址呢。因為arm為了區分thumb指令和arm指令,使用pc暫存器的最低位來區分的。如果最低位是1,則是thumb指令,如果是0則是arm指令。
所以跳轉位址是奇數字址,但是實際的**的開始位址是偶數字址。
所以其實我少拷貝了乙個byte的**才導致了這麼奇怪的bug。
把拷貝**從新修改後就ok了。
src_addr=(int32u*)((int32u)update - 1);//位址先減去一,拷貝**的實際開始位置.
dst_addr=(int32u*)(0*********); //當然dst_addr也是偶數字址。
重新修正jump_addr=((int32u)dst_addr+1);//跳轉位址必須是奇數字址(這樣cpu才知道是thumb指令)
for(i=0; i*dst_addr++=*src_addr++;
自己增加部分:
乙個極其討厭的人分享給我的,此人已經掛了,呵呵
記錄一下思路
韌體公升級 A9韌體公升級來啦!!!
期待已久的a9新韌體ver.5.00,終於來了 全新公升級的韌體增強了a9本就有著先天優勢的自動對焦效能,並加入了 實時追蹤對焦 實時眼部對焦 功能。追不上焦?不存在的!當然,除了提公升自動對焦體驗,a9的本次公升級也增加了許多新功能。公升級主要內容 改善及增加的自動對焦功能 1 實時追蹤對焦功能。...
韌體公升級 DFU OTA
dfu device firmware update 裝置韌體更新 ota over the air 空中公升級 wikipedia 用於智慧型硬體的公升級,包括軟體更新 韌體更新和裝置管理等功能。起初,韌體更新需要到裝置廠商指服務中心進行。接收更新的另一種方法是將裝置連入電腦端進行公升級。但這兩種...
Brocade FC Switch 韌體公升級
準備一根網線,連線筆記本網口和光交的管理網口。一 準備ftp server 本地部署ftp伺服器,並上傳合適的新韌體檔案 二 備份配置檔案 光交配置檔案 ftp server 三 公升級fos ftp server韌體 光交 version firmwareshow firmwaredownload...