InfiniTime.git

commit b8c51abe691a2d0f6770f4bfef3574541f49d744

Author: Felipe Martínez <felipe@pipe01.net>

Use all free RAM for FreeRTOS heap

* Use all free RAM for FreeRTOS heap
* Wrap newlib malloc and related functions
* Implement calloc

 src/CMakeLists.txt | 4 ++
 src/FreeRTOS/heap_4_infinitime.c | 28 +++++++++-------
 src/FreeRTOS/portmacro_cmsis.h | 1 
 src/FreeRTOSConfig.h | 1 
 src/displayapp/screens/SystemInfo.cpp | 3 +
 src/libs/lfs_config.h | 49 +++++++++++++++++++++++++++++
 src/stdlib.c | 36 +++++++++++++++++---


diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0a97a0158b2f9af46d4ef4a073906e25ea5481e8..e2b69b8b027b11952f8396817ba606c825f39882 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -788,6 +788,10 @@ add_definitions(-DFREERTOS)
 add_definitions(-D__STACK_SIZE=1024)
 add_definitions(-D__HEAP_SIZE=0)
 add_definitions(-DMYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME=1500)
+add_definitions(-DLFS_CONFIG=libs/lfs_config.h)
+
+# _sbrk is purposefully not implemented so that builds fail when it is used
+add_link_options(-Wl,-wrap=malloc -Wl,-wrap=free -Wl,-wrap=calloc -Wl,-wrap=realloc -Wl,-wrap=_malloc_r -Wl,-wrap=_sbrk)
 
 # Note: Only use this for debugging
 # Derive the low frequency clock from the main clock (SYNT)




diff --git a/src/FreeRTOS/heap_4_infinitime.c b/src/FreeRTOS/heap_4_infinitime.c
index 1470847114fc75f08ab0f00d3dd480cd7290a0cd..bf6492545ad410050624bd0b14e8719e1bcfa1f8 100644
--- a/src/FreeRTOS/heap_4_infinitime.c
+++ b/src/FreeRTOS/heap_4_infinitime.c
@@ -60,15 +60,6 @@
 /* Assumes 8bit bytes! */
 #define heapBITS_PER_BYTE		( ( size_t ) 8 )
 
-/* Allocate the memory for the heap. */
-#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
-/* The application writer has already defined the array used for the RTOS
-heap - probably so it can be placed in a special segment or address. */
-extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
-#else
-static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
-#endif /* configAPPLICATION_ALLOCATED_HEAP */
-
 /* Define the linked list structure.  This is used to link free blocks in order
 of their memory address. */
 typedef struct A_BLOCK_LINK
@@ -112,6 +103,8 @@ member of an BlockLink_t structure is set then the block belongs to the
 application.  When the bit is free the block is still part of the free heap
 space. */
 static size_t xBlockAllocatedBit = 0;
+
+static size_t xHeapSize = 0;
 
 /*-----------------------------------------------------------*/
 
@@ -332,27 +325,38 @@  return xMinimumEverFreeBytesRemaining;
 }
 /*-----------------------------------------------------------*/
 
+size_t xPortGetHeapSize( void )
+{
+ return xHeapSize;
+}
+/*-----------------------------------------------------------*/
+
 void vPortInitialiseBlocks( void )
 {
  /* This just exists to keep the linker quiet. */
 }
 /*-----------------------------------------------------------*/
 
+extern uint8_t *__HeapLimit; // Defined by nrf_common.ld
+
 static void prvHeapInit( void )
 {
  BlockLink_t *pxFirstFreeBlock;
  uint8_t *pucAlignedHeap;
  size_t uxAddress;
- size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
+ size_t xTotalHeapSize = ( size_t ) &__StackLimit - ( size_t ) &__HeapLimit;
+ uint8_t *pucHeap = ( uint8_t * ) &__HeapLimit;
+
+ xHeapSize = xTotalHeapSize;
 
  /* Ensure the heap starts on a correctly aligned boundary. */
- uxAddress = ( size_t ) ucHeap;
+ uxAddress = ( size_t ) pucHeap;
 
  if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
  {
    uxAddress += ( portBYTE_ALIGNMENT - 1 );
    uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
-   xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
+   xTotalHeapSize -= uxAddress - ( size_t ) pucHeap;
  }
 
  pucAlignedHeap = ( uint8_t * ) uxAddress;




diff --git a/src/FreeRTOS/portmacro_cmsis.h b/src/FreeRTOS/portmacro_cmsis.h
index e6e09158a7bd7bc3deeeb4a24ed9e71df0971c53..d165d171357a2f07ce0fd5e02d8471038eb552b3 100644
--- a/src/FreeRTOS/portmacro_cmsis.h
+++ b/src/FreeRTOS/portmacro_cmsis.h
@@ -180,6 +180,7 @@ }
 
 /*-----------------------------------------------------------*/
 
+size_t xPortGetHeapSize(void);
 
 #ifdef __cplusplus
 }




diff --git a/src/FreeRTOSConfig.h b/src/FreeRTOSConfig.h
index 67c33a34cc9124c7ab0bef81e905daf82d82cfb9..d877705a704fc416b3a0df35a17d4627646808f1 100644
--- a/src/FreeRTOSConfig.h
+++ b/src/FreeRTOSConfig.h
@@ -62,7 +62,6 @@ #define configCPU_CLOCK_HZ                      (SystemCoreClock)
 #define configTICK_RATE_HZ                      1024
 #define configMAX_PRIORITIES                    (3)
 #define configMINIMAL_STACK_SIZE                (120)
-#define configTOTAL_HEAP_SIZE                   (1024 * 40)
 #define configMAX_TASK_NAME_LEN                 (4)
 #define configUSE_16_BIT_TICKS                  0
 #define configIDLE_SHOULD_YIELD                 1




diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp
index d265fddd5bb20f64a9c2cc71f65e308ff132a0b4..886dacb6c6f5056aa3e93b0cb60a2a7772fe1548 100644
--- a/src/displayapp/screens/SystemInfo.cpp
+++ b/src/displayapp/screens/SystemInfo.cpp
@@ -195,7 +195,7 @@                         "\n"
                         "#808080 SPI Flash# %02x-%02x-%02x\n"
                         "\n"
                         "#808080 Memory heap#\n"
-                        " #808080 Free# %d\n"
+                        " #808080 Free# %d/%d\n"
                         " #808080 Min free# %d\n"
                         " #808080 Alloc err# %d\n"
                         " #808080 Ovrfl err# %d\n",
@@ -209,6 +209,7 @@                         spiFlashId.manufacturer,
                         spiFlashId.type,
                         spiFlashId.density,
                         xPortGetFreeHeapSize(),
+                        xPortGetHeapSize(),
                         xPortGetMinimumEverFreeHeapSize(),
                         mallocFailedCount,
                         stackOverflowCount);




diff --git a/src/libs/lfs_config.h b/src/libs/lfs_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..eaeede0e6350c0f5e5c5eccf6e7c257d09ec5b8c
--- /dev/null
+++ b/src/libs/lfs_config.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <libraries/log/nrf_log.h>
+
+#ifndef LFS_TRACE
+#ifdef LFS_YES_TRACE
+#define LFS_TRACE_(fmt, ...) \
+    NRF_LOG_DEBUG("[LFS] %s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
+#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
+#else
+#define LFS_TRACE(...)
+#endif
+#endif
+
+#ifndef LFS_DEBUG
+#ifndef LFS_NO_DEBUG
+#define LFS_DEBUG_(fmt, ...) \
+    NRF_LOG_DEBUG("[LFS] %s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
+#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "")
+#else
+#define LFS_DEBUG(...)
+#endif
+#endif
+
+#ifndef LFS_WARN
+#ifndef LFS_NO_WARN
+#define LFS_WARN_(fmt, ...) \
+    NRF_LOG_WARNING("[LFS] %s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
+#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "")
+#else
+#define LFS_WARN(...)
+#endif
+#endif
+
+#ifndef LFS_ERROR
+#ifndef LFS_NO_ERROR
+#define LFS_ERROR_(fmt, ...) \
+    NRF_LOG_ERROR("[LFS] %s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
+#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "")
+#else
+#define LFS_ERROR(...)
+#endif
+#endif
+
+// This is required in order for the CRC implementation in littlefs/lfs_util.c to be compiled
+#undef LFS_CONFIG
+
+#undef LFS_UTIL_H
+#include <littlefs/lfs_util.h>




diff --git a/src/stdlib.c b/src/stdlib.c
index 3ad66b378116ef2150a419140d192c10dcd0f9bc..21b506a8432e438a84a099c8265826cb5c166db8 100644
--- a/src/stdlib.c
+++ b/src/stdlib.c
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <string.h>
 #include <FreeRTOS.h>
 
 // Override malloc() and free() to use the memory manager from FreeRTOS.
@@ -10,18 +11,41 @@ void* malloc(size_t size) {
   return pvPortMalloc(size);
 }
 
+void* __wrap_malloc(size_t size) {
+  return malloc(size);
+}
+
+void* __wrap__malloc_r(struct _reent* reent, size_t size) {
+  (void) reent;
+  return malloc(size);
+}
+
 void free(void* ptr) {
   vPortFree(ptr);
+}
+
+void __wrap_free(void* ptr) {
+  free(ptr);
 }
 
 void* calloc(size_t num, size_t size) {
-  (void)(num);
-  (void)(size);
-  // Not supported
-  return NULL;
+  void *ptr = malloc(num * size);
+  if (ptr) {
+    memset(ptr, 0, num * size);
+  }
+  return ptr;
 }
 
-void *pvPortRealloc(void *ptr, size_t xWantedSize);
-void* realloc( void *ptr, size_t newSize) {
+void* __wrap_calloc(size_t num, size_t size) {
+  return calloc(num, size);
+}
+
+void* pvPortRealloc(void* ptr, size_t xWantedSize);
+
+void* realloc(void* ptr, size_t newSize) {
   return pvPortRealloc(ptr, newSize);
 }
+
+void* __wrap_realloc(void* ptr, size_t newSize) {
+  return realloc(ptr, newSize);
+}