我现在尝试使用ST的Dfuse升级我的固件。在应用模式下,VCP模式下的USB HS允许计算机与µC之间的通信,我使用此通信和一个用于复位器件的未初始化变量,并使用以下代码配置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_OR_CDC设置为DFU只使用DFU时,这是很好的,但是如果我使用VCP,然后使用我的命令DFU,我有de HardFault,它发生在DFU_DeInit上(来自ST的例子),特别是在DFU_DeInit()函数中。
/**
* @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;
}调试器指示释放函数的地址为0x080089A8的UNDEFINSTR (Keil V5)。UNDEFINSTR表明我试图转移到一个没有代码的地址,但是我不能理解为什么。
任何帮助都是善意的。
发布于 2015-09-08 20:12:19
这是ST库中的一个已知bug。它的几个版本混合了动态和静态内存管理。
请仔细查看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()的调用。
发布于 2015-09-09 23:26:31
为了解决这个问题,我使用了FLIP在下面的帖子中解释的方法。
StackOverFlow Jump to bootloader
我将µC编程分为两步:
-DFU固件。编程开始:闪存地址的开始,结束:闪存固件上的应用程序固件读取memory.This引脚,并根据此引脚将跳转到我的应用程序或启动DFU模式。
-应用程序固件。编程开始:闪存地址的开始,结束:闪存中应用固件的位置。然后,我重新配置HAL库、时钟和向量表偏移量,然后进入应用程序运行的无限循环。
https://stackoverflow.com/questions/32207296
复制相似问题