用STM32cubeMX做USB DFU Bootloader, 在更新时卡在94%不动

2019-12-12 18:14发布

本帖最后由 SkyGz 于 2019-3-27 20:59 编辑

芯片是 STM32F072C8T6


已解决, 确认是 NbOfPages 的问题,  网上的代码 果然不靠谱
成功实现将 F072的JLINK OB,  弄成 可通过DFU更新固件了...现已升到JLINK_V644C里的..

============================================================================
更新APP用户程序时, 卡在Download Phase 94%处不动了...请问是什么原因, 刚做好时, 第一次能下载成功.....之后再下载就卡着失败了

usbd_dfu_if.c 里的代码, 贴出几处关键部份...............  

大伙看看这是否有错误,  是否NbOfPages值错误了  
NbOfPages = (USBD_DFU_APP_END_ADD - USBD_DFU_APP_DEFAULT_ADD) / FLASH_PAGE_SIZE;
(F800-4800) / 800 =  0x16 也是22个页,   是否应该23页呢?

#define USBD_DFU_APP_END_ADD      0x0800F800        //ADDR_FLASH_PAGE_31, APP 最后一个扇区的首地址
//#define USBD_DFU_APP_DEFAULT_ADD  0x08004800   //APP 程序起始地址 usbd_conf.h
//#define FLASH_PAGE_SIZE           0x800U    //2K 大小/页 stm32f0xx_hal_flash_ex.h
#define FLASH_ERASE_TIME    (uint16_t)50
#define FLASH_PROGRAM_TIME  (uint16_t)50


#define FLASH_DESC_STR      "@Internal Flash   /0x08000000/09*002Ka,23*002Kg"

uint16_t MEM_If_Erase_FS(uint32_t Add)
{
  /* USER CODE BEGIN 2 */
        uint32_t NbOfPages = 0;
        uint32_t PageError = 0;
        /* Variable contains Flash operation status */
        HAL_StatusTypeDef status;
        FLASH_EraseInitTypeDef eraseinitstruct;

        /* Get the number of sector to erase from 1st sector*/
        NbOfPages = (USBD_DFU_APP_END_ADD - USBD_DFU_APP_DEFAULT_ADD) / FLASH_PAGE_SIZE;
        eraseinitstruct.TypeErase = FLASH_TYPEERASE_PAGES;
        eraseinitstruct.PageAddress = USBD_DFU_APP_DEFAULT_ADD;
        eraseinitstruct.NbPages = NbOfPages;
        status = HAL_FLASHEx_Erase(&eraseinitstruct, &PageError);

        if (status != HAL_OK)
        {
                return USBD_FAIL;
        }
        return (USBD_OK);
  /* USER CODE END 2 */
}


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 */
}

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 = *psrc++;
        }
        return (uint8_t *)(dest);
  /* USER CODE END 4 */
}


uint16_t MEM_If_GetStatus_FS(uint32_t Add, uint8_t Cmd, uint8_t *buffer)
{
  /* USER CODE BEGIN 5 */
        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 */
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。