看了很多,自己總結一部分。
其實這個功能可以這麼理解,好比是一臺電腦進行分區,我們現在要分成C:和D:。C盤就好比是Bootloader,主要存放系統引導文件,D盤就是我們放文件的地方,好比是APP。這樣來進行快速理解吧。
所以項目要建立兩部分:Bootloader和APP。
一、首先建立Bootloader項目
利用STM32FCubeMX 來建立,詳細步驟不寫了,需要用到一個GPIO口(LED指示)和USART3,主要用於查看程序運行狀態。
在“usart.c”中鍵入如下代碼:實現printf打印輸出
#include "stdio.h"
/**
* 函數功能: 重定向c庫函數printf到定義的串口
* 輸入參數: 無
* 返 回 值: 無
* 說 明:無
*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
在“main.c”中鍵入如下代碼:
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define APP_ADDR 0x08002000 //應用程序首地址定義
typedef void (*APP_FUNC)(); //函數指針類型定義
APP_FUNC jump2app;
/* USER CODE END PD */
/* USER CODE BEGIN PFP */
void run_app(uint32_t app_addr);
/* USER CODE END PFP */
/* USER CODE BEGIN 2 */
__disable_irq();
run_app(0x08002000);
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
/**
* @brief
* @param
* @retval
*/
void run_app(uint32_t app_addr)
{
uint32_t reset_addr = 0;
APP_FUNC jump2app;
printf("執行程序跳轉程序段\r\n");
/* 跳轉之前關閉相應的中斷 */
__disable_irq();
/* 棧頂地址是否合法 */
if(((*(uint32_t *)app_addr)&0x2FFFE000) == 0x20000000)
{
/* 獲取復位地址 */
reset_addr = *(uint32_t *)(app_addr+4);
jump2app = ( APP_FUNC )reset_addr;
__set_MSP((*(__IO uint32_t *) app_addr));
jump2app();
}
else
{
printf("APP 未找到!\r\n");
}
}
/* USER CODE END 4 */
在下面箭頭處將0X10000改成0X2000
好了,執行編譯和燒錄,將程序代碼燒錄進單片機。Bootloader部分就算完工了。
二、建立APP項目
也是用CubeMX建立,需要增加GPIO和USART3。
首先USART3 一樣插入如上代碼,實現pritnf打印輸出,不重複寫了。
插入如下代碼
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define APP_ADDR 0x08002000 //應用程序首地址定義
/* USER CODE END PD */
/* USER CODE BEGIN 2 */
__enable_irq();
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
printf("成功\r\n");
HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
HAL_Delay(500);
/* USER CODE BEGIN 3 */
}
點擊魔術棒,修改箭頭這裏。
打開"system_stm32f1xx.c"修改如下箭頭所指處。
編譯燒錄APP程序。我用的是ST-LINK V2 燒的,這裏注意,選擇擦除選中區
效果:
串口輸出兩段程序中的printf字符串。同時LED在閃爍,我就不放照片了。