Part VI: Memory Footprint
This chapter reports the kernel’s ROM and RAM footprint.
Note
Footprint figures measured with arm-none-eabi-gcc (Arm GNU Toolchain 15.3.Rel1 (Build arm-15.180)) 15.3.1 20260627 at -Os
How the figures are measured
QRT_ROM — kernel code and read-only data.
QRT_RAM — kernel statically-allocated data and BSS, excluding the configured kernel heap (
QRT_CFG_KERNEL_HEAP_SIZE) and the per-thread stack pool (QRT_CFG_STACK_POOL_SIZE). Those are integrator-sized working memory, not fixed kernel overhead; the total kernel RAM isQRT_RAMplus the heap and stack sizes you configure.
All builds use -Os with the MPU and FPU disabled.
Minimal configuration
The absolute floor: every optional feature compiled out (all
QRT_CFG_*_ENABLE options set to 0) — a single-threaded scheduler with
the System Timer and the system-call dispatch path only.
Target |
QRT_ROM |
QRT_RAM |
|---|---|---|
Cortex-M3 |
12.4 KiB (12,708 B) |
3.6 KiB (3,648 B) |
Per-feature ROM cost
Starting from that floor, the table below gives the ROM each
optional subsystem adds when enabled on its own. See
Part V: Kernel Configuration for the matching QRT_CFG_*_ENABLE options.
Feature |
ROM added |
|---|---|
Semaphores |
452 B |
Mutexes |
1,264 B |
Message queues |
1,364 B |
Software timers |
676 B |
Thread naming |
284 B |
Pthread keys |
284 B |
Deferred calls |
140 B |
Kernel object sizes
The RAM each kernel object instance occupies. Allocation differs by lifetime:
Synchronization / IPC objects / thread handles (
sem_t,pthread_mutex_t,mqd_t,pthread_t,timer_t…) are opaque handles; the figures below are the internal control blocks they refer to, allocated from the kernel heap on create.Attribute objects (
pthread_attr_t,pthread_mutexattr_t) are caller-owned: the caller declares them (typically on the stack) and the kernel initialises them in place, so they are transient and never touch the heap.
A message queue additionally allocates its name and its message buffer
(mq_attr.mq_maxmsg × mq_attr.mq_msgsize) alongside the control block. The TCB
entry is a range because it is configuration-dependent.
Object |
Size |
Notes |
|---|---|---|
Thread ( |
80-184 B |
Allocated by |
Thread attributes ( |
56 B |
Transient, on the creator’s stack |
Semaphore ( |
44 B |
Allocated by |
Mutex ( |
56 B |
Allocated by |
Mutex attributes ( |
20 B |
Transient, on the creator’s stack |
Message queue |
116 B |
Allocated by |
Message queue descriptor ( |
12 B |
Allocated by |
Software timer ( |
56 B |
Allocated by |
Thread Control Block
Each thread needs one Thread Control Block (TCB). Its size depends on which
optional features are enabled. The table gives the absolute TCB size for several
representative configurations. The MPU-enabled rows are shown for
QRT_CFG_MPU_ENTRIES of 8, 12 and 16, because the per-thread RAM grows
with the configured region count.
Configuration |
TCB size |
|---|---|
Minimal (all optional fields off) |
80 B |
Thread name |
88 B |
Mutexes |
88 B |
MPU (8 regions) |
112 B |
MPU (12 regions) |
144 B |
MPU (16 regions) |
176 B |
Thread naming + mutexes + MPU (8 regions) |
120 B |
Thread naming + mutexes + MPU (12 regions) |
152 B |
Thread naming + mutexes + MPU (16 regions) |
184 B |