韌體公升級思路

2021-08-01 16:28:45 字數 1497 閱讀 2273

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...