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.