国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

IAP與APP互相跳轉的實現

2019-11-09 17:52:58
字體:
來源:轉載
供稿:網友
 

IAP與APP互相跳轉的實現

2015-10-27 09:31 198人閱讀 評論(0) 收藏 舉報

首先,在您動手做這個實驗之前,先要弄清除咱倆的軟硬件有什么不同:

1. 我的CPU是STM32F103ZET6,里面有512K的Flash,您的CPU如果是其它類型,也不要緊,只是在程序里面,地址上限可能不一樣。但是,個人覺得,最好能用256K以下的FLASH。

2. 我的外部存儲介質是U盤,如果您的外部存儲介質是SD卡,那也應該一樣用,只是它們必須是FAT16,FAT32文件系統。如果您的板上沒有外部存儲介質,那也能做跳轉實驗,只是不能做加載APP實驗。

3. 我的仿真器是JLINK7,如果您的仿真器是其它的,估計也沒多大問題,只要您會用它就行了。什么?沒有仿真器,那還是別做這個實驗吧,出錯了沒法調試。

4. 我的開發環境是RVMDK 3。7,STM庫是V2。03。使用其它開發環境的話,您要是能找到MDK中的設置對應到您那里怎么設置,估計也沒問題。至于庫嘛,您現在是用哪個就哪個吧,全部包在您的工程里,沒問題的。

好了,開始啦。

先找個你以前調好的工程,當然,最好是非常可靠的,內容很精彩的,帶液晶顯示的,這樣比較容易知道你后面有沒有調好。這個工程還最好是在FLASH里面運行的,如果不是,要將它改回來。

至于什么開發文檔,太麻煩了,不用看。我之前看了STM的IAP應用筆記AN2557,就覺得一個字“亂”,特別是心里還沒譜的時候,更是越看越糊涂,這么大個工程,到最后對我有幫助的,就是一小段,就是如何擦除,如何編程那小段。當然,STM32的庫還是非常有用的,如果不用庫的話,學習、工作進度會慢很多。

說多啦,找好工程沒有?找好工程咱就開工了。將這個工程復制兩份,一份命名為IAP,一份命名為APP。

第一步:規劃好你兩個程序的存放位置。

IAP程序肯定是從0X08000000開始的,因為它是引導程序。將IAP程序放在0X08000000-0X0800FFFF的位置,給它64K空間,足夠了。

APP程序從0X08010000-0X0807FFFF,給它448K空間。

如果您的CPU不同,那APP程序的空間小一點,也沒問題。

第二步:制作你的APP程序。

1. 將程序定位在0X08010000開始的位置。

點魔術棒,打開目標選項設置。

選Target選項卡,IROM1改成從0X08010000開始,尺寸0X00070000;

Debug選項卡,Load application at Startup打上勾,Run to main()打上勾;

Utilitiles選項卡,點settings按紐,彈出Flash download卡,Erase sectors打上勾,點你的編程算法,將底下的的起始地址改成0X08010000,尺寸0X00070000。

2. 制作一個RunInFlashOffset.ini文件。文件內容為:

SP = _RDWord(0x08010000);           // Setup Stack Pointer

PC = _RDWORD(0x08010004);           // Setup PRogram Counter

目的是在用JLINK調試的時候,引導程序運行。

點魔術棒,打開目標選項設置。

選Debug選項卡,Initialization File:項,選擇上面的RunInFlashOffset.ini。 

3. 為了從IAP程序跳來運行APP的時候正常開始,初始化時要恢復RCC為復位狀態,恢復NVIC為復位狀態。

在你的RCC初始化部分,第一句加上:

RCC_DeInit();

在你的NVIC初始化部分,第一句加上:

NVIC_DeInit ();

4. 重定位中斷表到0X08010000位置。

在上面NVIC_DeInit ();后面加上:

NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x00010000);

如果原來有其它的定位語句,將它刪掉。

5. 編寫跳轉IAP函數:

/**************************************************************************************************

函數: 運行IAP程序.

輸入: 無

返回: 無.不再返回.

說明:   由于APP是在IAP的基礎上運行的,因此,IAP一定是有效的,這里不再作IAP有效性檢查.

**************************************************************************************************/

#define IAP_ADDR        0X08000000

void IapProgramRun(void)

{

    INT32U  IapSpInitVal;           //IAP程序的SP初值.

    INT32U  IapJumpAddr;            //IAP程序的跳轉地址.即,IAP程序的入口.

    void    (*pIapFun)(void);       //定義一個函數指針.用于指向APP程序入口.

    

    NVIC_DeInit ();                                 //恢復NVIC為復位狀態.使中斷不再發生.

    

    IapSpInitVal = *(INT32U *)IAP_ADDR;             //取APP的SP初值.

    IapJumpAddr = *(INT32U *)(IAP_ADDR + 4);        //取程序入口.

    

    __MSR_MSP (IapSpInitVal);                       //設置SP.

    pIapFun = (void (*)(void))IapJumpAddr;              //生成跳轉函數.

    (*pIapFun) ();                                  //跳轉.不再返回.

}

6. 編寫在一定條件下跳轉IAP的部分。比如按下某個鍵,就跳到IAP去。

完成上述幾步后,編譯調試,用JLINK調試,可以直接運行的,跟你原來的工程應該沒區別。有問題的話,將它解決。

第三步:制作您的IAP程序。

1. 將程序定位在0X08000000開始的位置。如果您的程序本來就是在這個位置的,不用改了。

點魔術棒,打開目標選項設置。

選Target選項卡,IROM1改成從0X08000000開始,尺寸0X00010000;

Debug選項卡,Load Application at Startup打上勾,Run to main()打上勾;

Utilitiles選項卡,點settings按紐,彈出Flash download卡,Erase sectors打上勾,點你的編程算法,將底下的的起始地址改成0X08000000,尺寸0X00010000。

2. 為了從APP程序跳回來運行IAP的時候正常開始,初始化時要恢復RCC為復位狀態,恢復NVIC為復位狀態。

在你的RCC初始化部分,第一句加上:

RCC_DeInit();

在你的NVIC初始化部分,第一句加上:

NVIC_DeInit ();

3. 重定位中斷表到0X08000000位置。

在上面NVIC_DeInit ();后面加上:

NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x0);

如果原來有其它的定位語句,將它刪掉。

4. 編寫在一定條件下跳轉APP的部分。比如按下某個鍵,就跳到APP去。

5. 編寫跳轉APP函數:

#define  APP_ADDR                0X08010000

OP_RESULT AppProgramRun(void)

{

    INT32U  AppSpInitVal;           //App程序的SP初值.

    INT32U  AppJumpAddr;            //APP程序的跳轉地址.即,APP程序的入口.

    void    (*pAppFun)(void);       //定義一個函數指針.用于指向APP程序入口.

    

    AppSpInitVal = *(INT32U *)APP_ADDR;             //取APP的SP初值.

    if (AppSpInitVal & 0XFFFF 0000 != 0X20 00 00 00)    //APP未寫入.不能跳.

    {

        FaceEnterDialog (&OpFailDialog);

        return OP_FAIL;

    }

    AppJumpAddr = *(INT32U *)(APP_ADDR + 4);        //取程序入口.

    if ((AppJumpAddr & 0X FF F8 00 00) != 0X 08 00 00 00)   //APP無效.不能跳.

    {

        FaceEnterDialog (&OpFailDialog);

        return OP_FAIL;

    }

    

    NVIC_DeInit ();                                 //恢復NVIC為復位狀態.使中斷不再發生.

    __MSR_MSP (AppSpInitVal);                       //設置SP.

    pAppFun = (void (*)(void))AppJumpAddr;          //生成跳轉函數.

    (*pAppFun) ();                                  //跳轉.不再返回.

    return OP_SUCCESS;

}

完成上述幾步后,編譯調試,OK。

第四步:雙程序調試:

1. 用仿真器運行IAP程序,然后按下按鍵,轉到APP去。如果你正常轉到APP,說明成功。不能的話,用仿真器跟一下,把問題解決。

2. 用仿真器運行APP程序,然后按下按鍵,轉到IAP去。如果你正常轉到IAP,說明成功。不能的話,用仿真器跟一下,把問題解決。

3. 用仿真器運行IAP程序,然后按下按鍵,轉到APP。

在APP中又按下按鍵,轉回IAP。如此反復。

可以在IAP第一句設個斷點,每次轉回來的時候,都應該會停在那里的。

注意:在跳到另一個程序中運行的時候,要停止不能直接點“停止調試按紐”,就是那個放大鏡一樣的按紐,否則MDK立馬出錯退出。要停止的話,要先打開反匯編觀察窗口,然后按下“停止”按紐,就是左上角紅圓圈里一把叉那個,

再按下“停止調試按紐”。

第五步:在IAP中加載APP。

如果你的板子上沒有USB,或都SD卡,這后面的就做不了了。

1. 改IAP程序,加上加載APP程序功能。就是按下某個鍵時,從U盤讀取APP程序,并把它寫到FLASH中。這個參考附件。

2. 在APP程序中,選擇輸出HEX文件。目前來說,HEX文件是比較方便處理的文件。

點魔術棒,打開目標選項設置。

選Output選項卡,Create HEX File打上勾。

編譯,生成HEX文件。

3. 把APP。HEX拷到U盤中,然后用IAP程序加載。

第六步:讓IAP區分是復位運行,還是從APP轉過來運行的。

打開你的啟動文件(我這里是stm32f10x_vector.s),看一下它里面棧空間是多大,堆空間是多大。在IAP程序主函數第一句設個斷點,記下此時的SP值,一般這個值比 棧+堆+全局變量還要大一些。在這個值+8之上的內部RAM空間,是程序用不上的。所以可以讓APP程序在RAM空間的頂端設置一個標志,然I后讓AP程序去根據這個標志來區別復位運行、從APP轉過來的運行。

區分IAP的運行方式有一個特殊的用途,那就是從APP程序中,跳轉IAP程序,來更新APP程序。這是真正的在線升級。

最后,我總結一下,要做IAP和APP間的互相跳轉,要注間以下幾點:

1. APP程序是放在FLASH的中間位置運行的,所以在編譯、下載、調試時,都要指定它的入口(本例是0X08010000)。具體實現就是在魔術棒中的設置。

2. 程序可以是從另外一個程序轉來的,而另外一個程序的RCC,NVIC設置不可知,所以必須在初始化時,恢復RCC,NVIC為復位狀態,并且設置正確的NVIC向量表。

3. 在要跳到別的程序之前,要恢復NVIC為復位狀態,防止在跳轉過程中出現中斷。

4. 如果IAP要判斷是復位開始運行的,還是從APP跳轉過來的,應該用程序啟動部分不會被改變的內存、外存存儲一個標志,用它來判定從哪跳來的。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳朔县| 民勤县| 长泰县| 阜平县| 乐东| 蓝山县| 贵定县| 孝感市| 瑞丽市| 天门市| 乐都县| 高阳县| 贡嘎县| 关岭| 普陀区| 汽车| 从江县| 东乡县| 阿拉善左旗| 都江堰市| 江油市| 绍兴县| 眉山市| 景宁| 同江市| 阿坝| 多伦县| 深圳市| 东丽区| 缙云县| 同江市| 法库县| 桦南县| 苏尼特左旗| 贡山| 宁陵县| 萨迦县| 宝丰县| 漳州市| 咸阳市| 临邑县|