mirror of https://github.com/ARMmbed/mbed-os.git
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.
pull/48/head
parent
e23be8a1b3
commit
9e6d1683b8
|
|
@ -425,3 +425,30 @@ extern "C" void __iar_argc_argv() {
|
|||
mbed_main();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Provide implementation of _sbrk (low-level dynamic memory allocation
|
||||
// routine) for GCC_ARM which compares new heap pointer with MSP instead of
|
||||
// SP. This make it compatible with RTX RTOS thread stacks.
|
||||
#if defined(TOOLCHAIN_GCC_ARM)
|
||||
// Linker defined symbol used by _sbrk to indicate where heap should start.
|
||||
extern "C" int __end__;
|
||||
|
||||
// Turn off the errno macro and use actual global variable instead.
|
||||
#undef errno
|
||||
extern "C" int errno;
|
||||
|
||||
// Dynamic memory allocation related syscall.
|
||||
extern "C" caddr_t _sbrk(int incr) {
|
||||
static unsigned char* heap = (unsigned char*)&__end__;
|
||||
unsigned char* prev_heap = heap;
|
||||
unsigned char* new_heap = heap + incr;
|
||||
|
||||
if (new_heap >= (unsigned char*)__get_MSP()) {
|
||||
errno = ENOMEM;
|
||||
return (caddr_t)-1;
|
||||
}
|
||||
|
||||
heap = new_heap;
|
||||
return (caddr_t) prev_heap;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue