4 years, 1 month ago.

How to disable RTX in mBed OS 5?

Hi,

I just moved to mBed OS 5, to stay up to date. My app is actually single threaded though, and the RTOS stuff - especially RTX (whatever that is) - take up a lot of RAM. I'm using an nRF51 so I only have something like 22 kB (some is used by the softdevice), and RTX uses 4 kB:

+----------------------+--------+-------+-------+
| Module               |  .text | .data |  .bss |
+----------------------+--------+-------+-------+
| Fill                 |    230 |     4 |    47 |
| Misc                 |  72909 |  2531 |  2977 |
| features/FEATURE_BLE |  15748 |     5 |   540 |
| features/mbedtls     |  16193 |     4 |     0 |
| features/net         |     78 |     0 |     0 |
| hal/common           |   5358 |     4 |   345 |
| hal/targets          |  23979 |   136 |  2240 |
| rtos/rtos            |    165 |     4 |     4 |
| rtos/rtx             |   6117 |    20 |  4279 |
| Subtotals            | 140777 |  2708 | 10432 |
+----------------------+--------+-------+-------+

As a result I'm running out of heap at runtime, when the gatt server is allocated. Is there any way to disable RTX? Or make it use less memory?

Edit:

I've had a look at what is using so much memory, and it seems like the RTOS allocates a thread-local stack called `thread_stack_main` for the main thread in addition to the actual main stack (which is used by the OS I guess?). Unless I'm totally misreading things. Here are the largest .bss symbols:

.bss 10432

  2292  DeviceBle::get()::that
  2048  thread_stack_main
  800   os_thread_def_stack_osTimerThread
  640   buffer_memory.7664
  528   mp_stk
  460   mp_tcb
  312   m_im
  312   getDeviceInstance()::deviceInstance
  256   filehandles
  208   m_pdb
  200   pc
  132   os_fifo

The first one I expect (it is basically all of my code). I don't expect thread_stack_main though. Here is where it is defined:

#if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) || defined (TARGET_STM32F334R8) ||\
    defined(TARGET_STM32F070RB) || defined(TARGET_STM32F072RB) || \
    defined(TARGET_STM32F302R8) || defined(TARGET_STM32F303K8) || defined (TARGET_STM32F334C8) ||\
    defined(TARGET_STM32F103RB)
static uint32_t thread_stack_main[DEFAULT_STACK_SIZE / sizeof(uint32_t)];
#elif defined(TARGET_XDOT_L151CC)
static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 6 / sizeof(uint32_t)];
#else
static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 2 / sizeof(uint32_t)];
#endif
osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, sizeof(thread_stack_main), thread_stack_main};

There is some code that suggests DEFAULT_STACK_SIZE should be 768 on nRF51, but for whatever reason it comes out as 2048.

I did stumble across a #define called MBED_RTOS_SINGLE_THREAD which saved a bit of memory!

+----------------------+--------+-------+------+
| Module               |  .text | .data | .bss |
+----------------------+--------+-------+------+
| Fill                 |    224 |     4 |   43 |
| Misc                 |  72909 |  2531 | 2977 |
| features/FEATURE_BLE |  15748 |     5 |  540 |
| features/mbedtls     |  16193 |     4 |    0 |
| features/net         |     78 |     0 |    0 |
| hal/common           |   5358 |     4 |  345 |
| hal/targets          |  23979 |   136 | 2240 |
| rtos/rtos            |    165 |     4 |    4 |
| rtos/rtx             |   5547 |    20 | 3075 |
| Subtotals            | 140201 |  2708 | 9224 |
+----------------------+--------+-------+------+

But it actually gets rid of os_thread_def_stack_osTimerThread! thread_stack_main is still 2 kB! What is going on...

Edit 2:

Well I followed all the macros and found this bit of code, to which I added the Nordic target:

#if defined(TARGET_XDOT_L151CC)
#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE/2)
#elif defined(TARGET_MCU_NRF51822)
#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE*2)
#else
#define DEFAULT_STACK_SIZE         (WORDS_STACK_SIZE*4)
#endif

(By default WORDS_STACK_SIZE is 512.) This gets me to here, which should be ok:

+----------------------+--------+-------+------+
| Module               |  .text | .data | .bss |
+----------------------+--------+-------+------+
| Fill                 |    224 |     4 |   43 |
| Misc                 |  72909 |  2531 | 2977 |
| features/FEATURE_BLE |  15748 |     5 |  540 |
| features/mbedtls     |  16193 |     4 |    0 |
| features/net         |     78 |     0 |    0 |
| hal/common           |   5358 |     4 |  345 |
| hal/targets          |  23979 |   136 | 2240 |
| rtos/rtos            |    165 |     4 |    4 |
| rtos/rtx             |   5547 |    20 | 2051 |
| Subtotals            | 140201 |  2708 | 8200 |
+----------------------+--------+-------+------+

2 Answers

3 years, 9 months ago.

as i found in the header file

RTX_Conf_CA.c

#if defined(MBED_RTOS_SINGLE_THREAD)
#define OS_TASKCNT  1
#define OS_TIMERS   0
#endif

3 years, 9 months ago.

MBED OS is a realtime, multithreaded OS which uses Keil RTX kernel. If you do not want to use RTOS because of the memory overhead, just a plain old super loop, do not import mbed os lib or any of the os features like mbed events. Use mbed lib instead and problem solved. You did not show us your code. Somewhere you included something OS specific.