From a83f067af9af82f034596f6f6154f4dccf598ace Mon Sep 17 00:00:00 2001 From: JF Date: Thu, 2 Jul 2020 21:38:52 +0200 Subject: [PATCH] Reduce RAM memory usage by tuning the stack of the stasks and the heap allocated for FreeRTOS. Add Monitor to log the stack usage of each task. --- src/CMakeLists.txt | 1 + src/FreeRTOSConfig.h | 6 +-- src/Logging/NrfLogger.cpp | 2 +- src/SystemTask/SystemMonitor.h | 46 +++++++++++++++++++ src/SystemTask/SystemTask.cpp | 2 + src/SystemTask/SystemTask.h | 7 +++ .../npl/freertos/src/nimble_port_freertos.c | 4 +- 7 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 src/SystemTask/SystemMonitor.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a30fb568..8b39d2b5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -442,6 +442,7 @@ set(INCLUDE_FILES libs/date/includes/date/tz_private.h DisplayApp/LittleVgl.h SystemTask/SystemTask.h + SystemTask/SystemMonitor.h ) include_directories( diff --git a/src/FreeRTOSConfig.h b/src/FreeRTOSConfig.h index 93289e1a..a18a2927 100644 --- a/src/FreeRTOSConfig.h +++ b/src/FreeRTOSConfig.h @@ -63,7 +63,7 @@ #define configTICK_RATE_HZ 1024 #define configMAX_PRIORITIES ( 3 ) #define configMINIMAL_STACK_SIZE ( 120 ) -#define configTOTAL_HEAP_SIZE ( 1024*20 ) +#define configTOTAL_HEAP_SIZE ( 1024*11 ) #define configMAX_TASK_NAME_LEN ( 4 ) #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 @@ -85,7 +85,7 @@ /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 -#define configUSE_TRACE_FACILITY 0 +#define configUSE_TRACE_FACILITY 1 #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /* Co-routine definitions. */ @@ -96,7 +96,7 @@ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( 0 ) #define configTIMER_QUEUE_LENGTH 32 -#define configTIMER_TASK_STACK_DEPTH ( 240 ) +#define configTIMER_TASK_STACK_DEPTH ( 200 ) /* Tickless Idle configuration. */ #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 diff --git a/src/Logging/NrfLogger.cpp b/src/Logging/NrfLogger.cpp index 1c47a108..7ccacc82 100644 --- a/src/Logging/NrfLogger.cpp +++ b/src/Logging/NrfLogger.cpp @@ -13,7 +13,7 @@ void NrfLogger::Init() { NRF_LOG_DEFAULT_BACKENDS_INIT(); - if (pdPASS != xTaskCreate(NrfLogger::Process, "LOGGER", 512, nullptr, 0, &m_logger_thread)) + if (pdPASS != xTaskCreate(NrfLogger::Process, "LOGGER", 200, this, 0, &m_logger_thread)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } diff --git a/src/SystemTask/SystemMonitor.h b/src/SystemTask/SystemMonitor.h new file mode 100644 index 00000000..50dd295a --- /dev/null +++ b/src/SystemTask/SystemMonitor.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include +#include + + +namespace Pinetime { + namespace System { + struct DummyMonitor {}; + struct FreeRtosMonitor {}; + + template + class SystemMonitor { + public: + SystemMonitor() = delete; + }; + + template<> + class SystemMonitor { + public: + void Process() const {} + }; + + template<> + class SystemMonitor { + public: + void Process() const { + if(xTaskGetTickCount() - lastTick > 10000) { + NRF_LOG_INFO("---------------------------------------\nFee heap : %d", xPortGetFreeHeapSize()); + auto nb = uxTaskGetSystemState(tasksStatus, 10, NULL); + for (int i = 0; i < nb; i++) { + NRF_LOG_INFO("Task [%s] - %d", tasksStatus[i].pcTaskName, tasksStatus[i].usStackHighWaterMark); + if (tasksStatus[i].usStackHighWaterMark < 20) + NRF_LOG_INFO("WARNING!!! Task %s task is nearly full, only %dB available", tasksStatus[i].pcTaskName, + tasksStatus[i].usStackHighWaterMark * 4); + } + lastTick = xTaskGetTickCount(); + } + } + + private: + mutable TickType_t lastTick = 0; + mutable TaskStatus_t tasksStatus[10]; + }; + } +} \ No newline at end of file diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp index 61b3c638..1f01b1b5 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/SystemTask/SystemTask.cpp @@ -169,6 +169,8 @@ void SystemTask::Work() { dateTimeController.UpdateTime(systick_counter); batteryController.Update(); + monitor.Process(); + if(!nrf_gpio_pin_read(pinButton)) watchdog.Kick(); } diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h index ab5f7010..e006058f 100644 --- a/src/SystemTask/SystemTask.h +++ b/src/SystemTask/SystemTask.h @@ -10,6 +10,7 @@ #include #include #include +#include "SystemMonitor.h" namespace Pinetime { namespace System { @@ -72,6 +73,12 @@ namespace Pinetime { bool doNotGoToSleep = false; void GoToRunning(); + +#if configUSE_TRACE_FACILITY == 1 + SystemMonitor monitor; +#else + SystemMonitor monitor; +#endif }; } } \ No newline at end of file diff --git a/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c b/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c index 8ee3475a..64196b36 100644 --- a/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c +++ b/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c @@ -37,7 +37,7 @@ nimble_port_freertos_init(TaskFunction_t host_task_fn) * provided by NimBLE and in case of FreeRTOS it does not need to be wrapped * since it has compatible prototype. */ - xTaskCreate(nimble_port_ll_task_func, "ll", configMINIMAL_STACK_SIZE + 400, + xTaskCreate(nimble_port_ll_task_func, "ll", configMINIMAL_STACK_SIZE + 100, NULL, configMAX_PRIORITIES - 1, &ll_task_h); #endif @@ -46,6 +46,6 @@ nimble_port_freertos_init(TaskFunction_t host_task_fn) * have separate task for NimBLE host, but since something needs to handle * default queue it is just easier to make separate task which does this. */ - xTaskCreate(host_task_fn, "ble", configMINIMAL_STACK_SIZE + 400, + xTaskCreate(host_task_fn, "ble", configMINIMAL_STACK_SIZE + 200, NULL, tskIDLE_PRIORITY + 1, &host_task_h); }