HAL-STM32-USB内部Flash虚拟U盘更新程序

  • Post author:
  • Post category:其他


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 版权协议,转载请附上原文出处链接和本声明。