娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年07月10日(星期四)

2018年07月10日 | STM32F030 IAP升級研究

發布者:自在自由 來源: eefocus關鍵字:STM32F030  IAP升級 手機看文章 掃描二維碼
隨時隨地手機看文章

     在使用SMT32F103的時候,發現STM32是可以通過串口實現在線升級的(當然也可以通過文件的形式升級,原理都是一樣的),正好在使用STM32F030,所以就想能不能在STM32F030上做一個在線升級的功能,通過一天的搗騰,還是搞出來了。后面想想了,還是把整個過程寫成文檔的形式分享出來。因為網上的資料都是零散的。

     主要的參考資料:

          《AN4657-STM32Cube_IAP_using_UART》

          《STM32串口IAP實驗(戰艦STM32開發板實驗)http://www.openedv.com/thread-11494-1-1.html》

           《STM32串口IAP實驗(戰艦STM32開發板實驗)http://www.openedv.com/thread-11494-1-1.html》

           《MDK STM32啟動文件的詳細分析(_main,map詳細分析)http://www.openedv.com/thread-20164-1-1.html》

           《stm32 IAP + APP ==雙劍合一(HEX) https://wenku.baidu.com/view/cc93905d79563c1ec5da717a.html》     

           《keil .sct分散加載文件及其應用 http://blog.csdn.net/temp741852963/article/details/51668884》

     平臺:STM32F030F4 Flash 16K, RAM 4K

     功能:IAP程序和APP可以通過按鍵實現相互跳轉的功能。

          

    1.  IAP升級流程:

     

    2. APP回到IAP的流程:

         

     為了區分當前程序是IAP還是APP,我用了一個LED燈來指示,在IAP程序下,LED燈300ms閃爍一次,在APP狀態下LED燈1s閃爍一次。

    

     stm32f0系列MCU中斷矢量表的定位跟STM32其它系列相比有點差異,即M0系列沒有像其它M3/M4/M0+系列所具備的中斷矢量表重定位寄存器,其中斷矢量表不能借助矢量重定位寄存器簡單修改實現。所以Stm32f0 IAP的過程會跟其它系列的STM32芯片的IAP動作有所不同。但是stm32有兩種啟動方式,一種是從flash啟動,默認地址為0x0800000,一種是從RAM啟動,默認地址為0x20000000,所以可以讓IAP從Flash啟動,而APP從RAM啟動,通過接口SYSCFG_MemoryRemapConfig配置。由于我們是把APP代碼直接拷貝到0x0800000+offset的地址上去的,其中斷向量表在Flash里面,所以在APP啟動的時候,需要把中斷向量表拷貝到RAM的起始地址中去。

     

     

     3. IAP源碼和工程配置

     主函數如下:

          int main(void)

{

#ifdef FLASH_UPDATE_FLAG

    //讀取是否升級成功的標志

    JTHAL_STMFLASH_Read(APP_UPDATE_FLAG_ADDR, &s_u16AppIsUpdateFlag, 1);

    if (s_u16AppIsUpdateFlag != 1)   //沒有升級成功,進入等待升級的狀態

    {

        s_u16AppIsUpdateFlag = 0;

        iLedInit();

        iKeyInit();

    }

    else   //升級成功,直接跳轉到app處執行

    {

        iJumpToAppStartFun(APP_START_ADDR);

    }

#else

    SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_Flash); //設置成flash啟動

    iLedInit();

    iKeyInit();

#endif

    while (1)

    {

        // 通過按鍵去更新APP

        if (s_u8KeyPress == 1)

        {

            s_u8KeyPress = 0;

            //開始更新APP

            memcpy(s_au8AppStartAddr, s_u8UartBuff+4, 4);

            //防止大小端問題

//        s_u32Val = 0;

//        s_u32Val |= (s_u8UartBuff[7] << 24);

//        s_u32Val |= (s_u8UartBuff[6] << 16);

//        s_u32Val |= (s_u8UartBuff[5] << 8);

//        s_u32Val |= (s_u8UartBuff[4] << 0);

            s_u32Val = *((uint32 *)(s_au8AppStartAddr));

            if((s_u32Val & 0xFF000000) == 0x08000000) // APP 數據有效性判斷

            {

                while (wLen != sizeof(s_u8UartBuff))

                {

                    if (sizeof(s_u8UartBuff) - wLen >= 1024)

                        wTmp = 1024;

                    else

                        wTmp = sizeof(s_u8UartBuff) - wLen;

                    JTHAL_STMFLASH_Write(APP_START_ADDR+wLen, (uint16 *)(s_u8UartBuff+wLen), (wTmp+1)/2);//更新FLASH代碼

                    wLen += wTmp;

                }

#ifdef FLASH_UPDATE_FLAG

                s_u16AppIsUpdateFlag = 1;

                JTHAL_STMFLASH_Write(APP_UPDATE_FLAG_ADDR, &s_u16AppIsUpdateFlag, 1);

                NVIC_SystemReset();

#else   

                goto JUMP_TO_APP;

#endif

            }

        }

        // LED 快速閃爍

        iLedON();

        iDelayMs(500);

        iLedOff();

        iDelayMs(500);

    }

JUMP_TO_APP:

    EXTI_DeInit();  //關閉外部中斷

    SYSCFG_DeInit();

    RCC_DeInit();

    iJumpToAppStartFun(APP_START_ADDR);

}

#define APP_START_ADDR     0x08002800      //第一個應用程序起始地址(存放在FLASH)

typedef  void (*APP_START_F)(void);              //定義一個函數類型的參數.

static APP_START_F s_pfnAppStart = NULL;

//跳轉到應用程序段

//appxaddr:用戶代碼起始地址.

static void iJumpToAppStartFun(uint32 appxaddr)

{

    s_u32Val = *((vu32*)appxaddr);

    if((s_u32Val & 0x2FFE0000) == 0x20000000)  //檢查棧頂地址是否合法.

    {

        s_pfnAppStart =(APP_START_F)*(uint32*)(appxaddr+4);       //用戶代碼區第二個字為程序開始地址(復位地址)

        __set_MSP(*(__IO uint32_t*) appxaddr); //初始化APP堆棧指針(用戶代碼區的第一個字用于存放棧頂地址)

        s_pfnAppStart();                                 //跳轉到APP.

    }

}

     注意:

          1. 如果是通過非重啟的方式跳轉到APP,跳轉之前一定要清除中斷,RCC相關配置,因為跳轉,相當于調用函數,配置的寄存器值不會改變,開啟的中斷也不會自動關閉,如果APP中沒有編寫相同的中斷函數,觸發中斷的時候就掛掉了。

          2.如果是通過非重啟的方式回到IAP,那么在執行IAP之前,需要設置為Flash啟動模式。

     IAP工程配置:

          

     我這里分配的是10K的flash空間給IAP,這里最好是配置一下。

     

     4.APP源碼和工程配置

 int main(void)

{

    iRemapIrqVector(); //拷貝中斷向量到RAM,并設置為RAM啟動模式

    iKeyInit();

    iLedInit();

    while (1)

    {

        if (s_u8KeyPress == 1)

        {

            s_u8KeyPress = 0;

#ifdef FLASH_UPDATE_FLAG

            //如果通過這種方式,在IAP里面不需要去設置啟動模式

            s_u16AppIsUpdateFlag = 0;

            JTHAL_STMFLASH_Write(APP_UPDATE_FLAG_ADDR, &s_u16AppIsUpdateFlag, 1);

            NVIC_SystemReset();

#else

            // 如果通過這種方式去跳轉到IAP,在IAP里面一定要設置啟動模式為flash模式

            //否則會出現死機的情況

            EXTI_DeInit();  //關閉外部中斷

            SYSCFG_DeInit();

            RCC_DeInit();

            iJumpToAppStartFun(APP_START_ADDR);

#endif

        }

        // LED慢閃爍

        iLedOn();

        iDelayMs(10000);

        iLedOff();

        iDelayMs(10000);

    }

}

#if   (defined ( __CC_ARM ))

__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));

#elif (defined (__ICCARM__))

#pragma location = 0x20000000

__no_init __IO uint32_t VectorTable[48];

#elif defined   (  __GNUC__  )

__IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));

#elif defined ( __TASKING__ )

__IO uint32_t VectorTable[48] __at(0x20000000);

#endif

// 重映射中斷向量

static void iRemapIrqVector(void)

{

    // 中斷向量重映射

    unsigned char i = 0;

    for(i = 0; i < 48; i++)

    {

        VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2)); //中斷向量是一個指針,每個占4個字節

    }

    /* Enable the SYSCFG peripheral clock*/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //這個一定要有

    /* Remap SRAM at 0x00000000 */

    SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM); //設置為RAM啟動模式

}

工程配置:



需要勾上Use Memory Layout from Target Dialog選項,否則會出現..\OBJ\STM32F030.axf: Error: L6985E: Unable to automatically place AT section main.o(.ARM.__AT_0x20000000) with required base address 0x20000000. Please manually place in the scatter file using the --no_autoat option.

的問題。 

     

     如果完全按照網上的資料,把APP代碼通過串口全部接收到本地(RAM),然后校驗,然后寫入到flash,這樣是行不通的,RAM太小了。所以我就把APP bin文件的內容全部拷貝到一個const數組中,然后通過按鍵寫入到Flash升級。然后通過按鍵從IAP->APP->IAP切換。至于怎么用4K的RAM去升級大于4K的程序APP,我提供一個思路。

     把APP.bin分成若干個包,每個包包含包編號,包大小,包檢驗,bin文件總大小。stm32f0收到升級命令后,開始通過包編號順序去請求包,校驗成功后,寫入到對應的flash區域,然后請求下一包,直到完成。

參考代碼下載地址: 點擊打開鏈接 (http://download.csdn.net/detail/losthome/9820748)


關鍵字:STM32F030  IAP升級 引用地址:STM32F030 IAP升級研究

上一篇:stm32 總中斷的打開與關閉
下一篇:STM32之bootloader

推薦閱讀

本文APP基于RTX-RTOS開發,由于該系統的特殊性,需對中斷進行開啟處理1、bootloader進入app前關閉中斷__set_PRIMASK(1);2、在app中需要開啟,但是開啟的時間需要在RTOS創建之前,因為RTX運行基于systick運行,所以在boot中關閉中斷后直接進入APP,沒有開啟中斷的Systick產生中斷直接hardfault。由于RTX內部封裝,無法找到在RTX初始化之前開啟中斷,可以選...
通過融合人工智能和頂尖的3D打印技術,大眾有望顛覆汽車組件的制造方式。目前正在測試的新技術不僅能夠有效減少汽車重量,而且在為未來車型設計特殊零件提供了極大的靈活性。隸屬于大眾集團,最近更名為加州創新和工程中心(IECC)近日用電氣現代化重新詮釋了1962年款Microbus。 此外在本次展示中,大眾Type 20概念車吸引了眾多媒體的眼球。它的核心元素...
據《科創板日報》消息,鴻蒙(HarmonyOS)2.0將于9月11日舉行的華為開發者大會上發布。據報道,鴻蒙2.0系統將在2019年1.0版本僅搭載智慧屏的基礎上,打通包括智能手機、PC、手表或手環和車機,當然仍包括智慧屏在內的眾多終端產品。據介紹,這是華為面向全場景智慧化IoT生態的未來操作系統,對標谷歌正在研發的多設備終端操作系統Fuchsia。據報道,華為將...

史海拾趣

小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 合川市| 新丰县| 莱芜市| 安溪县| 大荔县| 宜春市| 博罗县| 乌审旗| 竹山县| 弥勒县| 迁西县| 宁海县| 延川县| 吴堡县| 莫力| 雷波县| 琼中| 齐齐哈尔市| 家居| 页游| 岱山县| 武宁县| 开平市| 朝阳县| 临朐县| 灌南县| 中江县| 垫江县| 宁国市| 惠安县| 板桥市| 延川县| 婺源县| 三明市| 榆林市| 阿巴嘎旗| 苏州市| 襄垣县| 裕民县| 东莞市| 舞阳县|