0
votes

I currently try to upgrade my firmware by using Dfuse from ST. In application mode USB HS in VCP mode allow a communication between computer and µC and I use this communication and a non initialized variable for reset device and configure DFU interface with the followed code.

  */void MX_USB_DEVICE_Init(void)
{
    if (DFU_OR_CDC==1)
    {

  /* Otherwise enters DFU mode to allow user programing his application */
  /* Init Device Library */
  USBD_Init(&USBD_Device, &DFU_Desc, 0);
  /* Add Supported Class */
    USBD_RegisterClass(&USBD_Device, USBD_DFU_CLASS);
  /* Add DFU Media interface */
    USBD_DFU_RegisterMedia(&USBD_Device, &USBD_DFU_Flash_fops);
  /* Start Device Process */
    USBD_Start(&USBD_Device);
    /* Set led1 for indicate that device that device works as CDC/VCP interface */
    SetLed(LED2);
    ResetLed(LED1);
        while(1)
        {
        }
    }
    /* If CDC is selected configure and start USB CDC interface*/
    else if (DFU_OR_CDC==2)
    {
              /* Init Device Library */
    USBD_Init(&hUSBDDevice, &VCP_Desc, 0);
    /* Add Supported Class */
    USBD_RegisterClass(&hUSBDDevice, USBD_CDC_CLASS);
    /* Add CDC Interface Class */
    USBD_CDC_RegisterInterface(&hUSBDDevice, &USBD_CDC_fops);
    /* Start Device Process */
    USBD_Start(&hUSBDDevice);

        /* Set led2 for indicate that device that device works as DFU interface */
        SetLed(LED1);
        ResetLed(LED2);
        Readframe();
    }
    /*Auto select of CDC usb interface for the next plug, Reset after use of DFU mode*/
DFU_OR_CDC=2;
}

When I use only DFU by set manually the variable DFU_OR_CDC to DFU that's works fine, but if I use VCP and then DFU by using my command I have de HardFault which occur on DFU_DeInit (from example from ST), especially in free() function.

/**
  * @brief  USBD_DFU_Init
  *         De-Initialize the DFU layer
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  USBD_DFU_DeInit (USBD_HandleTypeDef *pdev, 
                                 uint8_t cfgidx)
{
  USBD_DFU_HandleTypeDef   *hdfu;
  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;

  hdfu->wblock_num = 0;
  hdfu->wlength = 0;

  hdfu->dev_state = DFU_STATE_IDLE;
  hdfu->dev_status[0] = DFU_ERROR_NONE;
  hdfu->dev_status[4] = DFU_STATE_IDLE;

  /* DeInit  physical Interface components */
  if(pdev->pClassData != NULL)
  {
    /* De-Initialize Hardware layer */
    ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit(); 
    USBD_free(pdev->pClassData);
    pdev->pClassData = NULL;
  } 

  return USBD_OK;
}

The debugger indicate a UNDEFINSTR (Keil V5)with an address of 0x080089A8 for free function. UNDEFINSTR indicate that I try to branch to an address where no code is located, but I unable to understand why.

Any Help will be kind.

2

2 Answers

1
votes

Its a known bug in ST's library. Several of its versions mixes dynamic and static memory management.

Look closely to USBD_malloc / USBD_free. Most likely, USBD_malloc simply return pointer to global variable, and USBD_free calls standart memory manager:

/* Memory management macros */  
#define USBD_malloc               (uint32_t *)USBD_static_malloc
#define USBD_free                 USBD_static_free

void *USBD_static_malloc(uint32_t size)
{
  static uint8_t mem[sizeof(USBD_CDC_HandleTypeDef)];
  return mem;
}
void USBD_static_free(void *p)
{
  free(p);
}

To fix this, just remove call of free().

0
votes

For resolve this I have used the method explained by FLIP in the following post.

StackOverFlow Jump to bootloader

I program my µC in two steps :

-DFU firmware. Programming start: beginning of Flash memory address, End : position on application firmware in flash memory.This firmware read a GPIO pin and according to this one will jump on my application or start DFU mode.

-Application firmware. Programming start: beginning of Flash memory address, End : position on application firmware in flash memory. Then I reconfigure HAL library,clocks and vector table offset then I enter in my infinity loop where my application run.