问题原因 出现该问题的主要原因在于 USB 库中使用了 malloc() 和 free() 函数。在“usbd_conf.h”文件中有类似如下内容: /* Memory management macros */ #define USBD_malloc malloc#define USBD_free free这两个函数需要使用“target specific functions” ,另外,如 printf()、scanf() 等函数都要用到“target specific functions”。 问题解决当遇到类似问题,你可以: - Provide real implementations for the functions. See the syscalls.c files.
- Use a different library.
如果使用了实时操作系统,那么还可以将malloc和free等替换成实时系统提供的函数(等同于“Use a different library”)。 我使用了FreeRTOS,该 RTOS 提供了 pvPortMalloc() 和 vPortFree() 用于替代 malloc() 和 free() 。但是,在 USB 驱动程序中无法直接使用这两个内存管理函数,因为它们内部调用了 vTaskSuspendAll() 和 xTaskResumeAll() 来挂起和恢复任务,而任务挂起和恢复函数在中断中是无法使用的。USB 驱动程序恰恰是在中断中调用的 USBD_malloc() 和 USBD_free()。因此,需要使用中断服务版本的内存管理程序或者使用内存池才真正可行。中断服务版本的内存分配/释放算法需要被 portDISABLE_INTERRUPTS()/portENABLE_INTERRUPTS() 对包围起来。具体可以参考http://www.freertos.org/FreeRTOS ... _ISR_ffdab88aj.html中的讨论。 注:非常建议使用实时系统提供的内存管理函数,因为使用标准的 malloc() 与 free() 库函数,必须承担以下若干问题:
- 这两个函数在小型嵌入式系统中可能不可用。
- 这两个函数的具体实现可能会相对较大,会占用较多宝贵的代码空间。
- 这两个函数通常不具备线程安全特性。
- 这两个函数具有不确定性。每次调用时的时间开销都可能不同。
- 这两个函数会产生内存碎片。
- 这两个函数会使得链接器配置得复杂。 |