Skip to content

Commit 9e6d168

Browse files
committed
gcc: Provide _sbrk implementation compatible with RTX
I verified that the hang issue I was seeing when building and running the mbed official networking tests with GCC_ARM was related to this issue reported on the mbed forums: http://mbed.org/forum/mbed/topic/3803/?page=1#comment-18934 If you are using the 4.7 2013q1 update of GCC_ARM or newer then it will have a _sbrk() implementation which checks the new top of heap pointer against the current thread SP, stack pointer. See this GCC_ARM related thread for more information: https://answers.launchpad.net/gcc-arm-embedded/+question/218972 When using RTX RTOS threads, the thread's stack pointer can easily point to an address which is below the current top of heap so this check will incorrectly fail the allocation. I have added a _sbrk() implementation to the mbed SDK which checks the heap pointer against the MSP instead of the current thread SP. I have only enabled this for TOOLCHAIN_GCC_ARM as this is the only GCC based toolchain that I am sure requires this.
1 parent e23be8a commit 9e6d168

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

libraries/mbed/common/retarget.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,30 @@ extern "C" void __iar_argc_argv() {
425425
mbed_main();
426426
}
427427
#endif
428+
429+
// Provide implementation of _sbrk (low-level dynamic memory allocation
430+
// routine) for GCC_ARM which compares new heap pointer with MSP instead of
431+
// SP. This make it compatible with RTX RTOS thread stacks.
432+
#if defined(TOOLCHAIN_GCC_ARM)
433+
// Linker defined symbol used by _sbrk to indicate where heap should start.
434+
extern "C" int __end__;
435+
436+
// Turn off the errno macro and use actual global variable instead.
437+
#undef errno
438+
extern "C" int errno;
439+
440+
// Dynamic memory allocation related syscall.
441+
extern "C" caddr_t _sbrk(int incr) {
442+
static unsigned char* heap = (unsigned char*)&__end__;
443+
unsigned char* prev_heap = heap;
444+
unsigned char* new_heap = heap + incr;
445+
446+
if (new_heap >= (unsigned char*)__get_MSP()) {
447+
errno = ENOMEM;
448+
return (caddr_t)-1;
449+
}
450+
451+
heap = new_heap;
452+
return (caddr_t) prev_heap;
453+
}
454+
#endif

0 commit comments

Comments
 (0)