【STM32H7教程】第68章 STM32H7的系統bootloader之USB DFU方式固件升級


完整教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

第68章       STM32H7的系統bootloader之USB DFU方式固件升級

本章節為大家講解使用系統bootloader做程序升級的方法,即使不依賴外部boot引腳也可以方便升級。

DFU的全稱是Device Firmware Upgrade,即設備固件升級

68.1 初學者重要提示

68.2 跳轉到系統bootloader的程序設計

68.3 STM32CubeProg的安裝說明

68.3 STM32CubeProg的程序下載說明

68.4 USB DFU方式系統bootloader驅動移植和使用

68.6 實驗例程設計框架

68.7 實驗例程說明(MDK)

68.8 實驗例程說明(IAR)

68.9 總結

 

 

68.1 初學者重要提示

  1.   學習本章節前,務必優先學習第67章。
  2.   特別注意STM32H7的系統bootLoader地址並不是0x1FFF 0000。
  3.   本章用到的相關軟件和文檔下載:http://www.armbbs.cn/forum.php?mod=viewthread&tid=96573
  4.   軟件STM32CubeProg和DfuSe都支持USB DFU,但是兩個軟件不能都安裝使用,因為這兩個軟件的USB驅動不同,導致工作在系統bootloader模式的板子通過USB線接到電腦端時,只有一個軟件的驅動被識別。
  5.   DfuSe是老版的USB DFU軟件,不推薦大家使用了。建議使用STM32CubeProg,此軟件實現了之前的DfuSe,STLINK小軟件和Flashloader三合一,並且支持外部EEPROM,NOR Flash,SPI Flash,NAND Flash等燒寫,也支持OTA編程。
  6.   本章節的USB DFU的下載軟件采用STM32CubeProg,如果想使用DfuSe的話,此貼有詳細說明:http://www.armbbs.cn/forum.php?mod=viewthread&tid=11185
  7.   當芯片工作在系統bootLoader的USB DFU模式,更新完畢程序后,不會自動退出USB DFU,需要重新復位芯片后才會退出。由於DFU模式會用到USB線,插拔USB線是難以避免的,所以是否支持自動退出,並不影響。

68.2 跳轉到系統bootLoader的程序設計

程序設計如下,基本是按照第67章3.2小節的方法進行設計

1.    /*
2.    ******************************************************************************************************
3.    *    函 數 名: JumpToBootloader
4.    *    功能說明: 跳轉到系統BootLoader
5.    *    形    參: 無
6.    *    返 回 值: 無
7.    ******************************************************************************************************
8.    */
9.    static void JumpToBootloader(void)
10.    {
11.        uint32_t i=0;
12.        void (*SysMemBootJump)(void);        /* 聲明一個函數指針 */
13.        __IO uint32_t BootAddr = 0x1FF09800; /* STM32H7的系統BootLoader地址 */
14.    
15.        /* 關閉全局中斷 */
16.        DISABLE_INT(); 
17.    
18.        /* 關閉滴答定時器,復位到默認值 */
19.        SysTick->CTRL = 0;
20.        SysTick->LOAD = 0;
21.        SysTick->VAL = 0;
22.    
23.        /* 設置所有時鍾到默認狀態,使用HSI時鍾 */
24.        HAL_RCC_DeInit();
25.    
26.        /* 關閉所有中斷,清除所有中斷掛起標志 */
27.        for (i = 0; i < 8; i++)
28.        {
29.            NVIC->ICER[i]=0xFFFFFFFF;
30.            NVIC->ICPR[i]=0xFFFFFFFF;
31.        }    
32.    
33.        /* 使能全局中斷 */
34.        ENABLE_INT();
35.    
36.        /* 跳轉到系統BootLoader,首地址是MSP,地址+4是復位中斷服務程序地址 */
37.        SysMemBootJump = (void (*)(void)) (*((uint32_t *) (BootAddr + 4)));
38.    
39.        /* 設置主堆棧指針 */
40.        __set_MSP(*(uint32_t *)BootAddr);
41.        
42.        /* 在RTOS工程,這條語句很重要,設置為特權級模式,使用MSP指針 */
43.        __set_CONTROL(0);
44.    
45.        /* 跳轉到系統BootLoader */
46.        SysMemBootJump(); 
47.    
48.        /* 跳轉成功的話,不會執行到這里,用戶可以在這里添加代碼 */
49.        while (1)
50.        {
51.    
52.        }
53.    }

 

這里把程序設計中的幾個關鍵地方做個說明:

  •   第12行,聲明一個函數指針。
  •   第13行,這個要特別注意,H7的系統Bootloader地址在0x1FF09800。
  •   第19到21行,設置滴答定時器到復位值。
  •   第24行,此函數比較省事,可以方便的設置H7所有時鍾到復位值,內部時鍾使用HSI。
  •   第27到31行,清除所有中斷掛起標志並關閉中斷,這里是直接通過一個for循環設置了NVIC所有配置位,共8組。

 

  •   第37行,將系統bootLoader的中斷復位服務程序的入口地址賦給第12行聲明的函數,用戶執行這個函數時,就會直接跳轉過去。
  •   第40行,設置主堆棧指針位置,即系統bootloader的首地址存儲的就是棧地址。
  •   第43行,這個設置在RTOS應用程序中比較重要,因為基於Cortex-M內核的RTOS任務堆棧基本都是使用線程堆棧指針PSP。但系統bootLoader使用的是主堆棧指針MSP,所以務必要設置下,同時讓M內核工作於特權級。此寄存器的作用如下:

 

  •   第46行,跳轉到系統bootLoader。

68.3 STM32CubeProg的安裝說明

STM32CubeProg的安裝比較簡單,如果大家的電腦中缺少JAVA環境,會提示安裝,按照提示操作即可。

這里特別注意USB DFU驅動的安裝,如果大家的電腦上安裝了DfuSe軟件,那邊板子工作在系統bootLoader模式時,電腦端的設備管理器識別出來的標識是這樣的:

 

如果用STM32CubeProg的話,務必要將此驅動刪掉,鼠標右擊此標識,選擇卸載,彈出如下對話框:

 

卸載完畢后,重啟電腦,然后運行STM32CubeProg安裝目錄里面的STM32Bootloader.bat即可,最后插上設備就可以正常識別了。識別后的標識:

 

68.4 STM32CubeProg的程序下載說明

這里把兩種下載方式都做個說明,一種是設置外部boot引腳進行下載,另一種是設置程序跳轉到系統bootloader進行下載。

68.4.1 設置boot引腳跳轉到系統bootLoader

  •   第1步:此接口插上USB線:

 

  •   第2步:板子上電前按住右下角的BOOT引腳。

 

  •   第3步:板子上電3秒左右,松手。

在電腦端設備管理器就可以看到已經識別出來:

 

68.4.2 應用程序跳轉到系統bootloader

應用程序跳轉到系統bootLoader比較方便,無需用戶操作外置的boot引腳了,只需調用本章第2小節的程序就可以跳轉。本章配套的例子是用戶按下按鍵K1后執行跳轉程序,大家可以根據需要實現各種觸發跳轉的方式。跳轉成功后,在電腦端設備管理器里面也會看到bootloader標識:

 

68.4.3 STM32CubeProg下載程序設置

識別成功后就可以下載程序了。

  第1步,選擇USB方式,點擊Connect按鈕。

 

識別成功后的效果如下:

 

這里要特別注意一點,如果用戶沒有關閉這個軟件,多次插拔USB線時,記得點擊這里的刷新按鈕,因為有時候這個軟件不會自動顯示出來,點擊刷新按鈕才行。

 

  第2步,添加要下載的hex文件,勾選需要設置的選項,點擊啟動編程。

 

  •   Start address選項不填的話,默認會下載到內部Flash的首地址,保險起見,大家也可以填上首地址0x0800 0000,或者其它要下載的地址。
  •   Run after programming選項勾選或者不勾選均可,因為測試發現STM32CubeProg不支持USB DFU編程后運行。這樣特別說一點,如果勾上此選項后,下載完畢程序后,會自動斷開連接,並彈出一些列窗口,最終彈出下面這個窗口:

 

彈出這個窗口並不是表示下載失敗了,而是下載完成后退出了系統bootloader。

  第3步,完成下載后的效果如下:

 

下載完成后板子重新上電就可以看到程序已經成功下載了。

68.5 USB DFU方式系統Bootloader驅動移植和使用

系統bootloader的移植比較簡單,僅需添加本章第2小節的程序到自己工程里面即可。里面有個開關中斷API,是在bsp.h文件里面定義的:

/* 開關全局中斷的宏 */
#define ENABLE_INT()    __set_PRIMASK(0)    /* 使能全局中斷 */
#define DISABLE_INT()    __set_PRIMASK(1)    /* 禁止全局中斷 */

 

68.6 實驗例程設計框架

通過程序設計框架,讓大家先對配套例程有一個全面的認識,然后再理解細節,本次實驗例程的設計框架如下:

 

  第1階段,上電啟動階段:

  • 這部分在第14章進行了詳細說明。

  第2階段,進入main函數:

  •   第1部分,硬件初始化,主要是MPU,Cache,HAL庫,系統時鍾,滴答定時器和LED。
  •   第2部分,應用程序設計部分,K1按鍵按下后跳轉到系統bootloader。。

68.7 實驗例程說明(MDK)

配套例子:

V7-047_基於系統bootloader的USB接口方式IAP升級(USB DFU)

實驗目的:

  1. 學習基於系統bootloader的USB接口方式IAP升級。

實驗內容:

  1. STM32的系統存儲區自帶bootLoader,可以方便的實現串口,I2C,CAN,SPI,USB等接口方式的程序升級。
  2. 如果使用系統bootLoader支持的接口升級方式,基本就不需要用戶自己做bootLoader了。
  3. 除了通過boot引腳控制啟動地址,也可以直接從應用程序里面跳轉到系統存儲區。

實驗操作:

  1. K1鍵按下,跳轉到系統bootLoader。

上電后串口打印的信息:

波特率 115200,數據位 8,奇偶校驗位無,停止位 1。

 

程序設計:

  系統棧大小分配:

 

  RAM空間用的DTCM:

 

  硬件外設初始化

硬件外設的初始化是在 bsp.c 文件實現:

/*
*********************************************************************************************************
*    函 數 名: bsp_Init
*    功能說明: 初始化所有的硬件設備。該函數配置CPU寄存器和外設的寄存器並初始化一些全局變量。只需要調用一次
*    形    參:無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* 配置MPU */
    MPU_Config();
    
    /* 使能L1 Cache */
    CPU_CACHE_Enable();

    /* 
       STM32H7xx HAL 庫初始化,此時系統用的還是H7自帶的64MHz,HSI時鍾:
       - 調用函數HAL_InitTick,初始化滴答時鍾中斷1ms。
       - 設置NVIV優先級分組為4。
     */
    HAL_Init();

    /* 
       配置系統時鍾到400MHz
       - 切換使用HSE。
       - 此函數會更新全局變量SystemCoreClock,並重新配置HAL_InitTick。
    */
    SystemClock_Config();

    /* 
       Event Recorder:
       - 可用於代碼執行時間測量,MDK5.25及其以上版本才支持,IAR不支持。
       - 默認不開啟,如果要使能此選項,務必看V7開發板用戶手冊第xx章
    */    
#if Enable_EventRecorder == 1  
    /* 初始化EventRecorder並開啟 */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
bsp_InitDWT();      /* 初始化DWT時鍾周期計數器 */       
    bsp_InitKey();        /* 按鍵初始化,要放在滴答定時器之前,因為按鈕檢測是通過滴答定時器掃描 */
    bsp_InitTimer();      /* 初始化滴答定時器 */
    bsp_InitUart();    /* 初始化串口 */
    bsp_InitExtIO();    /* 初始化FMC總線74HC574擴展IO. 必須在 bsp_InitLed()前執行 */    
    bsp_InitLed();        /* 初始化LED */    
    bsp_InitExtSDRAM(); /* 初始化SDRAM */
}

 

  MPU配置和Cache配置:

數據Cache和指令Cache都開啟。配置了AXI SRAM區(本例子未用到AXI SRAM)和FMC的擴展IO區。

/*
*********************************************************************************************************
*    函 數 名: MPU_Config
*    功能說明: 配置MPU
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void MPU_Config( void )
{
    MPU_Region_InitTypeDef MPU_InitStruct;

    /* 禁止 MPU */
    HAL_MPU_Disable();

    /* 配置AXI SRAM的MPU屬性為Write back, Read allocate,Write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x24000000;
    MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置FMC擴展IO的MPU屬性為Device或者Strongly Ordered */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x60000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;    
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /*使能 MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/*
*********************************************************************************************************
*    函 數 名: CPU_CACHE_Enable
*    功能說明: 使能L1 Cache
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
    /* 使能 I-Cache */
    SCB_EnableICache();

    /* 使能 D-Cache */
    SCB_EnableDCache();
}

 

  每10ms調用一次蜂鳴器處理:

蜂鳴器處理是在滴答定時器中斷里面實現,每10ms執行一次檢測。

/*
*********************************************************************************************************
*    函 數 名: bsp_RunPer10ms
*    功能說明: 該函數每隔10ms被Systick中斷調用1次。詳見 bsp_timer.c的定時中斷服務程序。一些處理時間要求
*              不嚴格的任務可以放在此函數。比如:按鍵掃描、蜂鳴器鳴叫控制等。
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_RunPer10ms(void)
{
    bsp_KeyScan10ms();
}

 

  主功能:

主程序實現如下操作:

  •   啟動一個自動重裝軟件定時器,每100ms翻轉一次LED2。
  •   K1鍵按下,跳轉到系統BootLoader。
/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程序入口
*    形    參: 無
*    返 回 值: 錯誤代碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint8_t ucKeyCode;    /* 按鍵代碼 */

    
    bsp_Init();        /* 硬件初始化 */
    PrintfLogo();    /* 打印例程名稱和版本等信息 */
    PrintfHelp();    /* 打印操作提示 */
    
    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重裝的定時器 */
    
    while (1)
    {
        bsp_Idle();        /* 這個函數在bsp.c文件。用戶可以修改這個函數實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        /* 按鍵濾波和檢測由后台systick中斷服務程序實現,我們只需要調用bsp_GetKey讀取鍵值即可。 */
        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K1:            /* K1鍵按下,K1鍵按下,跳轉到系統BootLoader */
                    JumpToBootloader();
                    break;
                    
                default:
                    /* 其它的鍵值不處理 */
                    break;
            }
        }
    }
}

 

68.8 實驗例程說明(IAR)

配套例子:

V7-047_基於系統bootloader的USB接口方式IAP升級(USB DFU)

實驗目的:

  1. 學習基於系統bootloader的USB接口方式IAP升級。

實驗內容:

  1. STM32的系統存儲區自帶bootLoader,可以方便的實現串口,I2C,CAN,SPI,USB等接口方式的程序升級。
  2. 如果使用系統bootLoader支持的接口升級方式,基本就不需要用戶自己做bootLoader了。
  3. 除了通過boot引腳控制啟動地址,也可以直接從應用程序里面跳轉到系統存儲區。

實驗操作:

  1. K1鍵按下,跳轉到系統bootLoader。

上電后串口打印的信息:

波特率 115200,數據位 8,奇偶校驗位無,停止位 1。

 

程序設計:

  系統棧大小分配:

 

  RAM空間用的DTCM:

 

  硬件外設初始化

硬件外設的初始化是在 bsp.c 文件實現:

/*
*********************************************************************************************************
*    函 數 名: bsp_Init
*    功能說明: 初始化所有的硬件設備。該函數配置CPU寄存器和外設的寄存器並初始化一些全局變量。只需要調用一次
*    形    參:無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* 配置MPU */
    MPU_Config();
    
    /* 使能L1 Cache */
    CPU_CACHE_Enable();

    /* 
       STM32H7xx HAL 庫初始化,此時系統用的還是H7自帶的64MHz,HSI時鍾:
       - 調用函數HAL_InitTick,初始化滴答時鍾中斷1ms。
       - 設置NVIV優先級分組為4。
     */
    HAL_Init();

    /* 
       配置系統時鍾到400MHz
       - 切換使用HSE。
       - 此函數會更新全局變量SystemCoreClock,並重新配置HAL_InitTick。
    */
    SystemClock_Config();

    /* 
       Event Recorder:
       - 可用於代碼執行時間測量,MDK5.25及其以上版本才支持,IAR不支持。
       - 默認不開啟,如果要使能此選項,務必看V7開發板用戶手冊第xx章
    */    
#if Enable_EventRecorder == 1  
    /* 初始化EventRecorder並開啟 */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
bsp_InitDWT();      /* 初始化DWT時鍾周期計數器 */       
    bsp_InitKey();        /* 按鍵初始化,要放在滴答定時器之前,因為按鈕檢測是通過滴答定時器掃描 */
    bsp_InitTimer();      /* 初始化滴答定時器 */
    bsp_InitUart();    /* 初始化串口 */
    bsp_InitExtIO();    /* 初始化FMC總線74HC574擴展IO. 必須在 bsp_InitLed()前執行 */    
    bsp_InitLed();        /* 初始化LED */    
    bsp_InitExtSDRAM(); /* 初始化SDRAM */
}

 

  MPU配置和Cache配置:

數據Cache和指令Cache都開啟。配置了AXI SRAM區(本例子未用到AXI SRAM)和FMC的擴展IO區。

/*
*********************************************************************************************************
*    函 數 名: MPU_Config
*    功能說明: 配置MPU
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void MPU_Config( void )
{
    MPU_Region_InitTypeDef MPU_InitStruct;

    /* 禁止 MPU */
    HAL_MPU_Disable();

    /* 配置AXI SRAM的MPU屬性為Write back, Read allocate,Write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x24000000;
    MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置FMC擴展IO的MPU屬性為Device或者Strongly Ordered */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x60000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;    
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /*使能 MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/*
*********************************************************************************************************
*    函 數 名: CPU_CACHE_Enable
*    功能說明: 使能L1 Cache
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
    /* 使能 I-Cache */
    SCB_EnableICache();

    /* 使能 D-Cache */
    SCB_EnableDCache();
}

 

  每10ms調用一次蜂鳴器處理:

蜂鳴器處理是在滴答定時器中斷里面實現,每10ms執行一次檢測。

/*
*********************************************************************************************************
*    函 數 名: bsp_RunPer10ms
*    功能說明: 該函數每隔10ms被Systick中斷調用1次。詳見 bsp_timer.c的定時中斷服務程序。一些處理時間要求
*              不嚴格的任務可以放在此函數。比如:按鍵掃描、蜂鳴器鳴叫控制等。
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_RunPer10ms(void)
{
    bsp_KeyScan10ms();
}

 

  主功能:

主程序實現如下操作:

  •   啟動一個自動重裝軟件定時器,每100ms翻轉一次LED2。
  •   K1鍵按下,跳轉到系統BootLoader。
/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程序入口
*    形    參: 無
*    返 回 值: 錯誤代碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint8_t ucKeyCode;    /* 按鍵代碼 */

    
    bsp_Init();        /* 硬件初始化 */
    PrintfLogo();    /* 打印例程名稱和版本等信息 */
    PrintfHelp();    /* 打印操作提示 */
    
    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重裝的定時器 */
    
    while (1)
    {
        bsp_Idle();        /* 這個函數在bsp.c文件。用戶可以修改這個函數實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        /* 按鍵濾波和檢測由后台systick中斷服務程序實現,我們只需要調用bsp_GetKey讀取鍵值即可。 */
        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K1:            /* K1鍵按下,K1鍵按下,跳轉到系統BootLoader */
                    JumpToBootloader();
                    break;
                    
                default:
                    /* 其它的鍵值不處理 */
                    break;
            }
        }
    }
}

 

68.9 總結

本章節為大家介紹的USB DFU方式還是非常實用的,特別是產品硬件不帶boot引腳時。

 


免責聲明!

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



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