2015-08-25 9 views
0

В настоящее время я пытаюсь обновить свою прошивку, используя Dfuse от ST. В режиме приложения USB HS в режиме VCP позволяет осуществлять связь между компьютером и μC, и я использую эту связь и не инициализированную переменную для устройства сброса и настраиваю интерфейс DFU с последующим кодом.STM32F446 DFU: Жесткая ошибка с функцией free()

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

Когда я использую только DFU, установить вручную переменной DFU_OR_CDC в DFU, который прекрасно работает, но если я использую ПДС, а затем DFU с помощью моей команды у меня есть де HardFault, которые происходят на DFU_DeInit (из примера с ST) , особенно в функции free().

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

отладчик указывает на UNDEFINSTR (Кейль V5) с адресом 0x080089A8 для свободной функции. UNDEFINSTR указывает, что я пытаюсь перейти на адрес, где нет кода, но я не могу понять, почему.

Любая помощь будет доброй.

ответ

1

Его известная ошибка в библиотеке ST. Некоторые из его версий сочетают динамическое и статическое управление памятью.

Посмотрите внимательно на USBD_malloc/USBD_free. Скорее всего, USBD_malloc просто возвращает указатель на глобальную переменную, и USBD_free вызовы стандартному менеджеру памяти:

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

Чтобы исправить это, просто удалите вызов free().

+0

Спасибо, Алексей, я считаю, что это интересно в случае использования в другой библиотеке ST проекта, но для этого я нашел другое решение, используя прыжок, как объяснялось в моем ответе. – Seb

0

Для этого я использовал метод, описанный FLIP, в следующем сообщении.

StackOverFlow Jump to bootloader

Я программирую мой мкКл в два этапа:

- DFU прошивки. Начало программирования: начало адреса флэш-памяти, Окончание: положение встроенного программного обеспечения приложения во флэш-памяти. Эта прошивка считывает вывод GPIO, и в соответствии с этим он сканирует мое приложение или запускает режим DFU.

- Application firmware. Начало программирования: начало адреса флэш-памяти, Окончание: положение прошивки приложения во флэш-памяти. Затем я переконфигурирую библиотеку HAL, часы и смещение векторной таблицы, затем я вхожу в мой цикл бесконечности, где выполняется мое приложение.