app和bootloader跳轉 MSP與PSP


1.不要把跳轉函數放在中斷中,如此導致在跳轉后的app或者bootloder都是在中斷狀態,只要你一開啟該中斷,就可能出現硬件中斷了

2.如果你的APP使用了ucos系統,在跳轉函數中還需要增加__set_CONTROL(0);//把psp修改成msp;這樣是為了把ucos系統中的psp置回msp,否則容易出現硬件中斷

MSP和PSP 的含義是Main_Stack_Pointer 和Process_Stack_Pointer,在邏輯地址上他們都是R13

這意味着同一個邏輯地址,實際上有兩個物理寄存器,一個為MSP,一個為PSP,在不同的工作模式調用不同的物理寄存器

沒有操作系統內核PSP與MSP模式:

R13的值與MSP值相同,內核使用MSP

帶UCOSII操作系統內核PSP與MSP模式:

 

帶操作系統運行任務的時候R13值與PSP相同,內核使用PSP

帶操作系統進入中斷的時候R13值與MSP相同,內核使用MSP

所以內核是PSP還是MSP總結為:

1)不使用OS時: 只用到MSP(中斷和非中斷都使用MSP);
2)使用OS時(如UCOSII): main函數和中斷使用MSP; 各個Task(線程)使用PSP(即任務棧);

當帶操作系統從APP區跳轉到BOOT區的時候需要將SP設置為MSP,否則在BOOT區中使用中斷將會引發硬件錯誤!

如果在APP中打開了看門狗那么當跳轉到BOOT中時也需要定時喂狗,否則會觸發看門狗超時復位!

 

------------------------------------------------------------------文章2------------------------------------------------------------------

Question:
最近在搞STM32 的IAP。發現一個很奇怪的問題。
程序A里面,跳轉到程序B執行。
A存放在0x08000000,B存放在0x0800e000.
起初,B使用的內存大概6K,其中堆棧使用了4K。此時如果從程序A跳到程序B,B出現死機。但是如果用仿真器直接運行B是可以運行的。
實在不知道什么問題,后來B的堆棧改小,設為1K,這是就正常了。能從程序A跳轉到程序B,並且B也能正常運行。
請問這是什么原因?程序B的運行為什么后它的內存大小的影響呢?
片子是STM32F103R8T6.
高手解答!! 謝謝了。
----------------------------------------------------------------------------------
Answer:
感覺是你在跳轉到B的時候沒有把程序B的主堆棧進行初始化,這樣程序B在運行的時候還在使用程序A的堆棧指針,很可能會與程序B的全局變量區混到一起了,執行情況就沒法預知了,會有某些奇怪現象發生。
----------------------------------------------------------------------------------
A程序用了ucos2,而且不是在中斷里跳轉到B,那應該是在某個任務里跳轉的吧。ucos2的官方移植版本,任務里使用的堆棧指針是PSP,如果你的A 程序是在使用PSP的任務里跳轉到B程序的,那么函數void JumpBootloaderProgram(void)中的__set_MSP(*(volatile unsigned int*) ApplicationAddress)函數並沒有使跳轉到B后的堆棧指針初始化為主堆棧指針,即跳轉到B后還是使用的程序A的PSP,問題可能會出在這 里。
----------------------------------------------------------------------------------
還得再啰嗦幾句,樓主所說的“把PSP和MSP都重新設置”指的是在函數JumpBootloaderProgram中又加入了一句 __set_PSP(*(volatile unsigned int*) ApplicationAddress)嗎?如果是這樣,貌似跳轉到B之后還有隱患,因為由A跳到B后,主程序用的是PSP,而中斷服務程序仍要使用 MSP,因為CM3的中斷服務是“處理模式”,只能使用MSP。如果在跳轉到B之前把MSP和PSP設為同樣值的話,那么B程序的中斷服務程序在使用堆棧 的同時,很可能也改寫了主程序的堆棧中的內容。所以我覺得最好在由A跳轉到B之前,在調用__set_MSP(*(volatile unsigned int*) ApplicationAddress)之前,把當前使用的堆棧指針由PSP改回MSP,然后再設置MSP,再跳轉,這樣比較好一些,跳轉到B之后,無論 主程序還是中斷服務程序都只使用MSP,也就不會沖突了。
----------------------------------------------------------------------------------
恩。多謝高手指點。呵呵。
在這里虛心接受建議。
我現在這樣改,應該就不會有問題了吧?
    JumpAddress = *(volatile unsigned int*) (ApplicationAddress + 4);
    Jump_To_Application = (pFunction) JumpAddress;
    __set_PSP(*(volatile unsigned int*) ApplicationAddress);
    __set_CONTROL(0);
    __set_MSP(*(volatile unsigned int*) ApplicationAddress);
    Jump_To_Application();

文章轉載自:http://www.360doc.com/content/12/0530/22/532901_214850938.shtml

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM