STM32 GCC 使用 USB 库出现”undefined reference to _sbrk”问题解决
来源:互联网 发布:excel中没有数据有效性 编辑:程序博客网 时间:2024/05/29 17:56
问题原因
出现该问题的主要原因在于 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_Support_Forum_Archive/April_2014/freertos_about_malloc_buffer_in_interrupt_ISR_ffdab88aj.html中的讨论。
注:非常建议使用实时系统提供的内存管理函数,因为使用标准的 malloc() 与 free() 库函数,必须承担以下若干问题:
- 这两个函数在小型嵌入式系统中可能不可用。
- 这两个函数的具体实现可能会相对较大,会占用较多宝贵的代码空间。
- 这两个函数通常不具备线程安全特性。
- 这两个函数具有不确定性。每次调用时的时间开销都可能不同。
- 这两个函数会产生内存碎片。
- 这两个函数会使得链接器配置得复杂。
SysCalls.cpp参考文件
Add this file to your project (e.g. syscalls.cpp) and paste the following code into it:
#include <stdio.h>#include <sys/stat.h>#include <stm32f10x_usart.h>extern "C" { int _fstat (int fd, struct stat *pStat) { pStat->st_mode = S_IFCHR; return 0; } int _close(int) { return -1; } int _write (int fd, char *pBuffer, int size) { for (int i = 0; i < size; i++) { while (!(USART1->SR & USART_SR_TXE)) { } USART_SendData(USART1, pBuffer[i]); } return size; } int _isatty (int fd) { return 1; } int _lseek(int, int, int) { return -1; } int _read (int fd, char *pBuffer, int size) { for (int i = 0; i < size; i++) { while ((USART1->SR & USART_SR_RXNE) == 0) { } pBuffer[i] = USART_ReceiveData(USART1); } return size; } caddr_t _sbrk(int increment) { extern char end asm("end"); register char *pStack asm("sp"); static char *s_pHeapEnd; if (!s_pHeapEnd) s_pHeapEnd = &end; if (s_pHeapEnd + increment > pStack) return (caddr_t)-1; char *pOldHeapEnd = s_pHeapEnd; s_pHeapEnd += increment; return (caddr_t)pOldHeapEnd; }}
- STM32 GCC 使用 USB 库出现”undefined reference to _sbrk”问题解决
- 用gcc-none-arm 编译出现undefined reference to `_sbrk'
- gcc "undefined reference to" 问题解决方法
- gcc编译出现”undefined reference to `pcap_parse’”
- gcc undefined reference to
- Ubuntu qt 使用opencv库出现undefined reference问题解决
- undefined reference to" 问题解决
- gcc编译cpp文件 出现undefined reference to `__gxx_personality_v0'
- 关于GCC模板出现"undefined reference to"的错误
- 关于GCC模板出现"undefined reference to"的错误
- gcc编译出现 undefined reference to 的问题
- gcc编译出现undefined reference to 'pthread_create'的解决方法
- gcc编译出现undefined reference to 的问题
- gcc 编译出现undefined reference to‘pthread_create’的错误
- "undefined reference to" 多种可能出现的问题解决方法
- gcc undefined reference to `pthread_create'
- undefined reference to 'pthread_create'问题解决
- undefined reference to 'pthread_create'问题解决
- mysql explain
- redhat 5.5nutch1.9和solr4.9集成
- cocos2dx win32工程如何自定义资源路径,即Resources的路径
- 如何指定进程运行的CPU
- 圖片輪播增加播放影音檔功能
- STM32 GCC 使用 USB 库出现”undefined reference to _sbrk”问题解决
- ora-02292,ora-02266主键约束问题
- 几大抽屉效果第三方总结
- C++--结构体和类
- leetcode-152 Maximum Product Subarray
- Gson解析json字符串,并封装成List<T>
- 扫雷游戏原理
- hive1.1安装
- java中的IO整理