arduino燒錄bootloader,STM32的Bootloader實現

 2023-12-06 阅读 26 评论 0

摘要:目錄0. 概述1. keil設置2. IAP跳轉函數3. APP重定向中斷向量表3.1 標準庫3.2 HAL庫4. 一些小問題 0. 概述 實際中通常會用到升級功能。本文主要是記錄下基本設置。 1. keil設置 設置flash起始地址和大小。IAP從起始地址運行,分配空間為8K,換算成16進制為0x2000

目錄

  • 0. 概述
  • 1. keil設置
  • 2. IAP跳轉函數
  • 3. APP重定向中斷向量表
    • 3.1 標準庫
    • 3.2 HAL庫
  • 4. 一些小問題

0. 概述

實際中通常會用到升級功能。本文主要是記錄下基本設置。

1. keil設置

  1. 設置flash起始地址和大小。IAP從起始地址運行,分配空間為8K,換算成16進制為0x2000,如下圖:
    在這里插入圖片描述
    APP在IAP后,即從0x8002000開始。使用的STM32L051C8Tx flash空間為64K,去除IAP部分還剩56K,APP分配空間為52K,換算成16進制為0xD000,如下圖:
    在這里插入圖片描述
  2. 設置為扇區擦除。IAP和APP程序設置相同,如下圖:
    在這里插入圖片描述

2. IAP跳轉函數

跳轉函數如下:

#define APPLICATION_ADDRESS 	(uint32_t)0x08002000typedef void (*pfun) (void);
pfun Jump_To_Application;
uint32_t JumpAddress;void go_to_app(void)
{if (((*(volatile uint32_t*)APPLICATION_ADDRESS) & 0x2FFFE000 ) == 0x20000000){JumpAddress =  *(volatile uint32_t*)(APPLICATION_ADDRESS + 4);Jump_To_Application = (pfun)JumpAddress;__set_MSP(*(volatile uint32_t*)APPLICATION_ADDRESS);Jump_To_Application();}
}

函數解釋如下:

  1. if (((*(volatile uint32_t*)ApplicationAddress) & 0x2FFFE000 ) == 0x20000000)
    ApplicationAddress存放的是用戶程序Flash的首地址,((volatile uint32_t)ApplicationAddress)的意思是取用戶程序首地址里面的數據,這個數據就是用戶代碼的堆棧地址,堆棧地址指向RAM,而RAM的起始地址是0x20000000,因此上面的判斷語句執行:判斷用戶代碼的堆棧地址是否落在:0x20000000~0x20001FFF區間中,這個區間的大小為8K。
  2. test = (*(volatile u32*)ApplicationAddress),test保存的就是堆棧地址(并且是應用程序堆棧的棧頂地址)。查看STM32的向量表,可以知道:棧頂地址 + 4 存放的是復位地址,因此JumpAddress存放的是復位地址。
  3. 調用__set_MSP函數后,將把用戶代碼的棧頂地址設為棧頂指針。
  4. Jump_To_Application();的意思就是設置PC指針為復位地址。

CORTEX-M3上電后后檢測BOOT引腳的電平來決定PC的位置。例:BOOT設置為FLASH啟動,啟動后CPU會先取兩個地址:一個是棧頂地址,另一個是復位地址。因此才有了第3、第4點的寫法。

摘自一篇非常詳細的文章,可惜找不到鏈接了。 

3. APP重定向中斷向量表

3.1 標準庫

STM32標準庫可通過下面函數實現重定向:

NVIC_SetVectorTable(0x08000000,0x2000);

3.2 HAL庫

HAL庫不再支持該函數,通過下面函數完成重定向:

void SystemInit (void)
{......SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table ......
}

我們修改VECT_TAB_OFFSET宏定義的值即可:

/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x2000U /*!< Vector Table base offset field.This value must be a multiple of 0x100. */

當需要調整IAP空間時,這里很容易漏掉。經常使用如下定義:

extern int Image$$ER_IROM1$$Base;
#define VECT_TAB_OFFSET  ((uint32_t)&Image$$ER_IROM1$$Base)

然后KEIL添加設置:
在這里插入圖片描述
這樣調整空間的同時,也調整了中斷向量表:
在這里插入圖片描述
源代碼鏈接:STM32L051_Bootloader。

4. 一些小問題

這一小節記錄下boot遇到的問題,逐漸補充,不針對上一節貼的代碼。

  1. 從IAP跳轉到APP后運行異常。
    單獨運行IAP和APP都正常,但是跳轉后APP不發正常運行。仿真發現APP的HAL_Delay異常,沒有進入systick中斷。
    發現IAP中進行了關中斷操作:
    在這里插入圖片描述
    這是一個通用boot程序,以前的APP程序基于RTOS實現,現在APP采用裸機,所以需要手動開中斷:
    在這里插入圖片描述

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/190225.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息