Heap Tracing
Drone OS provides tools to fine-tune the built-in allocator for purposes of a particular application.
A newly generated Drone project has the following heap!
macro in src/lib.rs
:
#![allow(unused)] fn main() { heap! { // Heap configuration key in `Drone.toml`. config => main; /// The main heap allocator generated from the `Drone.toml`. metadata => pub Heap; // Use this heap as the global allocator. global => true; // Uncomment the following line to enable heap tracing feature: // trace_port => 31; } }
Note that trace_port
option is commented out - by default the firmware
compiles without the heap tracing runtime. When the option is uncommented, the
heap allocator will log its operations to the log port #31. In order to capture
these logs, first uncomment the trace_port
option:
#![allow(unused)] fn main() { heap! { // ... The header is skipped ... // Uncomment the following line to enable heap tracing feature: trace_port => 31; } }
Then flash the new version of the application firmware to the target device:
$ just flash
Then you run a special recipe to capture the data:
$ just heaptrace
This recipe is similar to just log
, with an exception that it will
additionally capture port #31 output and write it to a file named
heaptrace
. When you think it is enough data collected, just stop it with
Ctrl-C.
When there is a non-empty heaptrace
file with the collected data in the
project root, you may use the following command to analyze your heap usage:
$ drone heap
It will print statistics of all your allocations during just heaptrace
:
Block Size | Max Load | Total Allocations
------------+----------+-------------------
1 | 1 | 1
12 | 3 | 7
28 | 1 | 2
32 | 1 | 1
128 | 1 | 2
Maximum memory usage: 225 / 2.20%
The data in the heaptrace
file can also be used to generate an optimized
memory pools layout:
$ drone heap generate --pools 5
Here 5
is the maximum number of pools. Less pools lead to more fragmentation,
but faster allocations. You should get something like this:
=============================== SUGGESTED LAYOUT ===============================
[heap]
size = "10K"
pools = [
{ block = "4", capacity = 201 },
{ block = "12", capacity = 222 },
{ block = "28", capacity = 115 },
{ block = "32", capacity = 83 },
{ block = "128", capacity = 7 },
]
# Fragmentation: 0 / 0.00%
It generated a [heap]
section suitable to put into the Drone.toml
.