關於IAP程式中函式跳轉以及堆疊合法性判斷的理解

2021-09-25 04:18:12 字數 1154 閱讀 5217

在上文中製作了iap過程中的bootloader,有如下**

if (((*(__io uint32_t*)user_flash_first_page_address) & 0x2ffe0000 ) == 0x20000000)
上面這句話的意思是把使用者**的首位址裡面的資料拿出來,看看是不是以0x20000000開頭。

(x & 0x2ffe0000 ) == 0x20000000 意思是說x是不是在0x20000000與0x2001ffff之間,即棧頂是不是在以0x20000000開始的128k空間,stm32f407zgt6的ram資訊如下圖所示

使用者**的首位址放的是堆疊指標(sp),而堆疊應該指向ram,而ram的首位址是0x20000000,所以這句話用來判斷是不是已經有乙個正確的堆疊指標位址寫在了使用者**的首位址,進一步可以推測是不是有乙個正確的使用者**寫在了使用者**區,如果已經寫入了,就可以跳過去執行,如果沒有寫入,就不跳過去。這是demo程式的判斷邏輯,可以這樣用,也可以不這樣用。

jumpaddress = *(__io uint32_t*) (user_flash_first_page_address + 4);
上面這句話是把使用者**的復位位址賦值給jumpaddress。

__set_msp(*(__io uint32_t*) user_flash_first_page_address);
上面這句話是把使用者**的堆疊位址寫入堆疊指標,msp對應的是主堆疊指標。

總結:要對bootloader的執行順序做到深刻理解,就需要對微控制器的啟動順序做到心中有數,要對startup_stm32f407xx.s檔案的內容有很好的理解。簡要的來講,startup_stm32f407xx.s檔案做了一下幾件事情

設定棧,堆資訊

建立中斷向量表

設定中斷向量服務函式

系統時鐘初始化,使用者堆疊初始化(__main實現)【這些功能是在復位中斷服務函式中完成】

跳轉到使用者main函式

關於VC 程式中 堆和棧的問題

關於 vc 程式中堆和棧的問題 一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式...

關於keil中無法跳轉到函式 變數定義處的問題

keil中無法跳轉到定義的情況有多種情況 1 工程編譯不成功,這種情況肯定跳轉不到定義的,這時只能根據編譯提示資訊檢查程式直到程式正常通過編譯吧。2 工程未編譯或工程清空編譯資訊後未再進行編譯,肯定會跳轉不到定義處,這時一般再編譯一次工程就可以了。3 某些暫存器變數,列舉型別或結構體變數。4 定義的...

關於c 中char char 賦值以及函式的傳值

這個問題通過創造乙個類來體現 首先是標頭檔案 define stack h class stack endif 接下來是定義各種函式的cpp include include stack.h using namespace std stack stack 創造乙個棧類 bool stack empty...