stm32f103 DFU升级程序

本文介绍了如何通过STM32CubeMX创建工程并配置USBDFU功能,包括内存初始化、擦除操作注意事项,以及在STM32CubeProgrammer中使用USB进行程序升级的方法。
摘要由CSDN通过智能技术生成

通过引导程序跳转到系统bootloader中,通过USB下载程序。
一、新建工程
用STM32CubeMX生成工程,基本设置都一样,主要是需要对USB进行设定。
在这里插入图片描述
该处Parameter Settings部分保持默认即可。
在这里插入图片描述
修改参数配置
在这里插入图片描述
USBD_DFU_XFER_SIZE(每次传输的最大字节数)
USBD_DFU_APP_DEFAULT_ADD (Base Address 0x)(升级
程序的起始地址):该值需要大于引导程序的大小,且是0x200的倍数。
程序所占flash的大小,可以去.map文件中查看

在这里插入图片描述

二、修改程序
修改usbd_dfu_if.c文件

/**
  * @brief  Memory initialization routine.
  * @retval USBD_OK if operation is successful, MAL_FAIL else.
  */
uint16_t MEM_If_Init_FS(void)
{
  /* USER CODE BEGIN 0 */
	HAL_FLASH_Unlock();
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
  return (USBD_OK);
  /* USER CODE END 0 */
}
/**
  * @brief  De-Initializes Memory
  * @retval USBD_OK if operation is successful, MAL_FAIL else
  */
uint16_t MEM_If_DeInit_FS(void)
{
  /* USER CODE BEGIN 1 */
	HAL_FLASH_Lock();
  return (USBD_OK);
  /* USER CODE END 1 */
}

关于flash的擦除,这里很重要,由于使用的是VG芯片,它的内部分为了两个BANK,进行擦除的时候要分别擦除,尝试过直接从0x08100000擦到起始地址,但是只能擦除一个BANK。

/**
  * @brief  Erase sector.
  * @param  Add: Address of sector to be erased.
  * @retval 0 if operation is successful, MAL_FAIL else.
  */
uint16_t MEM_If_Erase_FS(uint32_t Add)
{
  /* USER CODE BEGIN 2 */
    uint32_t NbOFPages=0; 
    uint32_t PageError;
	  HAL_StatusTypeDef status;
    FLASH_EraseInitTypeDef pEraseInit;

    /* Unlock the Flash to enable the flash control register access *************/
    MEM_If_Init_FS();

    /* Get the sector where start the user flash area */
    NbOFPages = (USBD_DFU_BANK1_END_ADD - USBD_DFU_APP_DEFAULT_ADD)/FLASH_PAGE_SIZE;

    pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
    pEraseInit.PageAddress = USBD_DFU_APP_DEFAULT_ADD;
    pEraseInit.NbPages = NbOFPages;
	
		status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);
    if (status != HAL_OK)
    {
        /* Error occurred while page erase */
        return USBD_FAIL;
    }
		
	//VG芯片的flash分为两个BANK,擦除时要分别进行擦除,否则BANK2会擦除失败,下载程序时会出现下载到BANK2时就报错的问题
    NbOFPages = (USBD_DFU_BANK2_END_ADD - USBD_DFU_BANK1_END_ADD)/FLASH_PAGE_SIZE;

    pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
    pEraseInit.PageAddress = USBD_DFU_BANK1_END_ADD;
    pEraseInit.NbPages = NbOFPages;
	
		status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);
    if (status != HAL_OK)
    {
        /* Error occurred while page erase */
        return USBD_FAIL;
    }		
		
		
  return (USBD_OK);
  /* USER CODE END 2 */
}
/**
  * @brief  Memory write routine.
  * @param  src: Pointer to the source buffer. Address to be written to.
  * @param  dest: Pointer to the destination buffer.
  * @param  Len: Number of data to be written (in bytes).
  * @retval USBD_OK if operation is successful, MAL_FAIL else.
  */
uint16_t MEM_If_Write_FS(uint8_t *src, uint8_t *dest, uint32_t Len)
{
  /* USER CODE BEGIN 3 */
	  uint32_t i = 0;
 
    for(i = 0; i < Len; i += 4)
    {
        /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
        * be done by byte */
        if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)(dest + i), *(uint32_t *)(src + i)) == HAL_OK)
        {
            /* Check the written value */
            if(*(uint32_t *)(src + i) != *(uint32_t *)(dest + i))
            {
                /* Flash content doesn't match SRAM content */
                return 2;
            }
        }
        else
        {
            /* Error occurred while writing data in Flash memory */
            return 1;
        }
    }
  return (USBD_OK);
  /* USER CODE END 3 */
}
/**
  * @brief  Memory read routine.
  * @param  src: Pointer to the source buffer. Address to be written to.
  * @param  dest: Pointer to the destination buffer.
  * @param  Len: Number of data to be read (in bytes).
  * @retval Pointer to the physical address where data should be read.
  */
uint8_t *MEM_If_Read_FS(uint8_t *src, uint8_t *dest, uint32_t Len)
{
  /* Return a valid address to avoid HardFault */
  /* USER CODE BEGIN 4 */
     uint32_t i = 0;
    uint8_t *psrc = src;
 
    for(i = 0; i < Len; i++)
    {
        dest[i] = *psrc++;
    }
    /* Return a valid address to avoid HardFault */
    return (uint8_t *)(dest);
  /* USER CODE END 4 */
}
/**
  * @brief  Get status routine
  * @param  Add: Address to be read from
  * @param  Cmd: Number of data to be read (in bytes)
  * @param  buffer: used for returning the time necessary for a program or an erase operation
  * @retval USBD_OK if operation is successful
  */
uint16_t MEM_If_GetStatus_FS(uint32_t Add, uint8_t Cmd, uint8_t *buffer)
{
  /* USER CODE BEGIN 5 */
  uint16_t FLASH_PROGRAM_TIME = 50;
  uint16_t FLASH_ERASE_TIME = 50;
  switch (Cmd)
  {
    case DFU_MEDIA_PROGRAM:
     buffer[1] = (uint8_t)FLASH_PROGRAM_TIME;
     buffer[2] = (uint8_t)(FLASH_PROGRAM_TIME << 8);
     buffer[3] = 0;
    break;

    case DFU_MEDIA_ERASE:
    default:
     buffer[1] = (uint8_t)FLASH_ERASE_TIME;
     buffer[2] = (uint8_t)(FLASH_ERASE_TIME << 8);
     buffer[3] = 0;
    break;
  }
  return (USBD_OK);
  /* USER CODE END 5 */
}

三、main函数

	if(HAL_GPIO_ReadPin( GPIOC , GPIO_PIN_3 ) == GPIO_PIN_RESET)//如果有键按下,那么跳转进行程序升级
	{
    MX_USB_DEVICE_Init();
	}
	else
	{
       /* Test if user code is programmed starting from USBD_DFU_APP_DEFAULT_ADD address */			
        if(((*(__IO uint32_t*)USBD_DFU_APP_DEFAULT_ADD) & 0x2FFE0000 ) == 0x20000000)
        {
            /* Jump to user application */
            JumpAddress = *(__IO uint32_t*) (USBD_DFU_APP_DEFAULT_ADD + 4);
            JumpToApplication = (pFunction) JumpAddress;

            /* Initialize user application's Stack Pointer */
            __set_MSP(*(__IO uint32_t*) USBD_DFU_APP_DEFAULT_ADD);
            JumpToApplication();
        }
				
		 //MX_USB_DEVICE_Init();	
	}

四、使用STM32CubeProgrammer升级程序。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值