From 81dea364a5b372ad1625181eff710c095420735c Mon Sep 17 00:00:00 2001
From: Ian Martin <ian@locicontrols.com>
Date: Mon, 27 Oct 2014 20:00:52 -0400
Subject: [PATCH] cpu/cc2538: sbrk() checks if the requested memory is really
 available.

---
 cpu/cc2538/Makefile.include |  4 ++++
 cpu/cc2538/syscalls.c       | 31 +++++++++++++++++++++----------
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/cpu/cc2538/Makefile.include b/cpu/cc2538/Makefile.include
index e851b58687..c282717bd4 100644
--- a/cpu/cc2538/Makefile.include
+++ b/cpu/cc2538/Makefile.include
@@ -10,6 +10,10 @@ export CORTEX_COMMON = $(RIOTCPU)/cortex-m3_common/
 # Define the linker script to use for this CPU:
 export LINKERSCRIPT = $(RIOTCPU)/$(CPU)/$(CPU_MODEL)_linkerscript.ld
 
+# Export the CPU model:
+MODEL = $(shell echo $(CPU_MODEL) | tr 'a-z' 'A-Z')
+export CFLAGS += -DCPU_MODEL_$(MODEL)
+
 # Include CPU specific includes:
 export INCLUDES += -I$(RIOTCPU)/$(CPU)/include
 
diff --git a/cpu/cc2538/syscalls.c b/cpu/cc2538/syscalls.c
index d1bb148835..84721323a9 100644
--- a/cpu/cc2538/syscalls.c
+++ b/cpu/cc2538/syscalls.c
@@ -39,6 +39,13 @@
 #ifdef MODULE_UART0
 #include "board_uart0.h"
 #endif
+
+#ifdef CPU_MODEL_CC2538NF11
+#define SRAM_LENGTH (16 * 1024) /**< The CC2538NF11 has 16 Kb of RAM */
+#else
+#define SRAM_LENGTH (32 * 1024) /**< All other existing models of the CC2538 have 32 Kb of RAM */
+#endif
+
 /**
  * manage the heap
  */
@@ -113,21 +120,25 @@ void _exit(int n)
  * @brief Allocate memory from the heap.
  *
  * The current heap implementation is very rudimentary, it is only able to allocate
- * memory. But it does not
- * - check if the returned address is valid (no check if the memory very exists)
- * - have any means to free memory again
+ * memory. It does not have any means to free memory again.
  *
- * TODO: check if the requested memory is really available
- *
- * @return [description]
+ * @return      a pointer to the successfully allocated memory
+ * @return      -1 on error, and errno is set to ENOMEM
  */
 caddr_t _sbrk_r(struct _reent *r, size_t incr)
 {
     unsigned int state = disableIRQ();
-    caddr_t res = heap_top;
-    heap_top += incr;
-    restoreIRQ(state);
-    return res;
+    if ((uintptr_t)heap_top + incr > SRAM_BASE + SRAM_LENGTH) {
+        restoreIRQ(state);
+        r->_errno = ENOMEM;
+        return (caddr_t)-1;
+    }
+    else {
+        caddr_t res = heap_top;
+        heap_top += incr;
+        restoreIRQ(state);
+        return res;
+    }
 }
 
 /**
-- 
GitLab