2015-08-25 2 views
0

J'essaie actuellement de mettre à jour mon firmware en utilisant Dfuse de ST. En mode application, USB HS en mode VCP permet une communication entre l'ordinateur et μC et j'utilise cette communication et une variable non initialisée pour réinitialiser le périphérique et configurer l'interface DFU avec le code suivi.STM32F446 DFU: Erreur matérielle avec la fonction 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; 
} 

Quand je n'utilise que DFU par définir manuellement la variable DFU_OR_CDC à DFU qui est fonctionne très bien, mais si je l'utilise VCP puis DFU en utilisant ma commande J'ai de HardFault qui se produisent sur DFU_DeInit (de l'exemple de ST) , en particulier dans la fonction 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; 
} 

Le débogueur indique un UNDEFINSTR (Keil V5) avec une adresse de 0x080089A8 pour la fonction libre. UNDEFINSTR indique que j'essaye de m'attacher à une adresse où aucun code n'est localisé, mais je n'arrive pas à comprendre pourquoi.

Toute aide sera aimable.

Répondre

1

C'est un bug connu dans la bibliothèque de ST. Plusieurs de ses versions mélangent la gestion dynamique et statique de la mémoire. Observer de près USBD_malloc/USBD_free. Très probablement, USBD_malloc revenir simplement pointeur vers la variable globale et USBD_free appels standart gestionnaire de mémoire:

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

Pour résoudre ce problème, il suffit de retirer l'appel de free().

+0

Merci Alexey, je garde dans mon esprit ce qui est intéressant en cas d'utilisation dans une autre bibliothèque du projet ST, mais pour celui-ci j'ai trouvé une autre solution en utilisant un saut comme expliqué dans ma réponse. – Seb

0

Pour résoudre cela, j'ai utilisé la méthode expliquée par FLIP dans le post suivant.

StackOverFlow Jump to bootloader

programmer mon uC en deux étapes:

- DFU firmware. Début de la programmation: début de l'adresse mémoire Flash, Fin: position sur le firmware de l'application dans la mémoire flash. Ce firmware lit une broche GPIO et selon celle-ci va sauter sur mon application ou démarrer le mode DFU.

- Micrologiciel d'application. Début de la programmation: début de l'adresse mémoire Flash, Fin: position sur le firmware de l'application dans la mémoire flash. Ensuite, je reconfigure la bibliothèque HAL, les horloges et le décalage de la table vectorielle, puis j'entre dans ma boucle infini où mon application s'exécute.