STM32F446 DFU: грубая ошибка с функцией free()
В настоящее время я пытаюсь обновить прошивку с помощью Dfuse от ST. В прикладном режиме USB HS в режиме VCP обеспечивает связь между компьютером и микроконтроллером, и я использую эту связь и неинициализированную переменную для устройства сброса и конфигурирую интерфейс DFU с помощью следующего кода.
*/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, это работает нормально, но если я использую VCP, а затем 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 (Keil V5) с адресом 0x080089A8 для свободной функции. UNDEFINSTR указывают, что я пытаюсь перейти на адрес, где нет кода, но я не могу понять, почему.
Любая Помощь будет доброй.
2 ответа
Это известная ошибка в библиотеке 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()
,
Для решения этой проблемы я использовал метод, описанный FLIP в следующем посте.
StackOverFlow Перейти к загрузчику
Я программирую свой µC в два этапа:
-прошивка ДФУ. Начало программирования: начало адреса флеш-памяти, Конец: позиция прошивки приложения во флеш-памяти. Эта прошивка считывает вывод GPIO и в соответствии с этим запустится в моем приложении или запустит режим DFU.
-Приложение прошивки. Начало программирования: начало адреса флеш-памяти, конец: позиция прошивки приложения во флеш-памяти. Затем я перенастраиваю библиотеку HAL, часы и смещение векторной таблицы, затем вхожу в бесконечный цикл, где запускается мое приложение.