背景:在cortex_M3使用freeRTOS开启启用运行时间统计功能时。
在编译阶段编译报错:
/data/user_home//build_tools/gcc-arm-none-eabi-/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
Makefile:155: recipe for target 'all' failed
make: *** [all] Error 1
原因:ARM gcc默认是使用startfiles,导致调用底层未实现的某些函数(malloc、 free、 sprintf…)时,编译链接失败。
推广:如果编译报undefined reference to `_sbrk' `_read' `_write' `_lseek' `_isatty' `_fstat' 也是相同原因。
解决方案:
方案一:如果项目不需要这些函数,找到直接屏蔽函数即可。
方案二:一劳永逸。链接失败是因为未实现这些,所以可以自己重写这些底层函数或者添加有这些函数的库文件,比如libnosys.a。 添加编译参数 --specs=nosys.specs 即可使用。
添加后如果编译报以下错误:
/data/user_home/ /build_tools/gcc-arm-none-eabi-/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libnosys.a(sbrk.o): In function `_sbrk':
sbrk.c:(.text._sbrk+0x18): undefined reference to `end'
collect2: error: ld returned 1 exit status
Makefile:155: recipe for target 'all' failed
make: *** [all] Error 1
这是由于’end’ symbol在.lds链接器脚本中未定义,所以找到项目的xx.lds文件设置该脚本用于堆位置,例如:
.heap :
{
. = ALIGN(4);
__HEAP_START = .;
. += 0x2000; __HEAP_MAX = .;
end = __HEAP_MAX;
PROVIDE(end = .);
} > ram