1.IAP部分
添加fat32文件(修改Flash擦除代码,F401ccu6按扇区删除,F103按页删除)
static bool _fat32_write_firmware(const uint8_t *b, uint32_t addr)
{
bool return_status = true;
HAL_StatusTypeDef status;
HAL_FLASH_Unlock();
uint32_t offset = addr - fw_addr_range.begin;
uint32_t phy_addr = APP_ADDR + offset;
uint32_t prog_size = MIN(FAT32_SECTOR_SIZE, fw_addr_range.end - fw_addr_range.begin);
if(prog_size & 0x03)
{
prog_size += 4;
}
if(addr == fw_addr_range.begin)
{
// Erase the APPCODE area
//stm32f401ccu6 256k Flash ,0~5个扇区 0,1,2,3:16K 4:64K 5:128K
//前面32K预留为BootLoader 删除后两个扇区64K+128K备用烧录程序
uint32_t PageError = 0;
FLASH_EraseInitTypeDef eraseinitstruct;
eraseinitstruct.TypeErase = FLASH_TYPEERASE_SECTORS;
eraseinitstruct.Sector = FLASH_SECTOR_2;
eraseinitstruct.NbSectors = 4;
status = HAL_FLASHEx_Erase(&eraseinitstruct, &PageError);
if(status != HAL_OK)
{
return_status = false;
goto EXIT;
}
}
if((phy_addr >= APP_ADDR) && (phy_addr < (APP_ADDR + APP_SIZE)) )
{
uint32_t i = 0;
for(i=0; i<prog_size; i+=4)
{
const uint8_t *wbuf = b + i;
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, phy_addr + i, *((uint32_t*)wbuf));
if(status != HAL_OK)
{
return_status = false;
goto EXIT;
}
}
}
if(addr == (fw_addr_range.end - FAT32_SECTOR_SIZE))
{
// HAL_FLASH_Lock();
DownloadComplete();
return_status = true;
}
EXIT:
HAL_FLASH_Lock();
return return_status;
}
IAP跳转函数
#include "stdio.h"
#include <stdint.h>
#include <stdbool.h>
#include "btldr_config.h"
int fputc(int ch, FILE* FILE)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
return ch;
}
bool is_appcode_exist()
{
uint32_t *mem = (uint32_t*)APP_ADDR;
if ((mem[0] == 0x00000000 || mem[0] == 0xFFFFFFFF) && \
(mem[1] == 0x00000000 || mem[1] == 0xFFFFFFFF) && \
(mem[2] == 0x00000000 || mem[2] == 0xFFFFFFFF) && \
(mem[3] == 0x00000000 || mem[3] == 0xFFFFFFFF))
{
return false;
}
else
{
return true;
}
}
static void JumpToApp(void)
{
typedef void (*pFunction)(void);
static pFunction JumpToApplication;
static uint32_t JumpAddress;
/* Test if user code is programmed starting from USBD_DFU_APP_DEFAULT_ADD * address */
if (((*(__IO uint32_t *) APP_ADDR) & 0x2FFE0000) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t *) (APP_ADDR + 4u);
//HAL_DeInit();
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP((*(__IO uint32_t *) APP_ADDR));
JumpToApplication();
}
}
bool is_button_down()
{
return (HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET);
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
// MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
printf("STM32F4 USB-IAP TEST !!!\r\n");
if(!is_appcode_exist() || is_button_down())
{
MX_USB_DEVICE_Init();
printf("Jump failed, USB firmware upgrade mode!!!\r\n");
while(1)
{
}
}
else
{
printf("Jump succeed!!!\r\n");
JumpToApp();
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
跳转位置以生成的bin大小为准
因为F401以扇区擦除,说英语0x5000修改为0x8000,前面2个扇区作为BootLoader
2.APP篇
int fputc(int ch, FILE* FILE)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
return ch;
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
SCB->VTOR = FLASH_BASE | 0x8000;
__ASM("CPSIE I");//
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
printf("STM32F4 USB-IAP-APP TEST !!!\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
printf("Succeed!!!\r\n");
HAL_Delay(500);
}
/* USER CODE END 3 */
}
设置生成bin文件(fromelf –bin -o “$L@L.bin” “#L”)
设置跳转
版权声明:本文为weixin_44096390原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。