μP7 (micro P7) is lightweight C library for sending trace/logs & telemetry data from your Micro-controller’s firmware to host/HW FIFO/cycle buffer/network/etc. for further analysis. It is designed to be integrated on almost every microcontroller, even with very limited resources.

The library is oriented on firmware developers (Bare-metal or RTOS) & real-time task. contains exhaustive documentation inside package.

  • extremely low memory usage, (900 lines of code, no dynamic memory allocation, all traces/logs format strings are removed from compilation & binaries)
    • μP7 instance – 408 bytes of heap + 264 bytes in .BSS
    • 40 bytes of heap per trace/telemetry item (allocated at initialization)
  • Speed is priority, library is designed to minimize time per trace/telemetry call, for example average performance for Intel i7-870 is:
    • 15 million traces per second
    • 23 million telemetry samples per second
  • Unicode support (UTF-8, UTF-16, UTF-32)
  • No external dependencies
  • Different host's sinks (transport & storages) are supported:
    • Network (Baical server)
    • Binary File
    • Text File (Linux: UTF-8, Windows: UTF-16)
    • Console
    • Syslog (RFC 5424)
    • Auto (Baical server if reachable, else - binary file)
    • Null
  • Files rotation setting (by size or time)
  • Files max count setting (deleting old files automatically)
  • Remote management from Baical server (set verbosity per module, enable/disable telemetry counters)
  • Trace & telemetry files have compact binary format (due to speed requirements - binary files much more compact than raw text), export to text is available
  • Command line interface for configuration may be used in addition to application parameters
  • Big/Little endian support
  • Soft Microprocessors (MicroBlaze, Risc-V, NIOS), ARM, etc.
  • GCC, Clang


μP7 consist of next components/tools:

  • μP7 library (will be part of user firmware)
  • μP7 proxy library (will communicate with firmware from host and convert μP7 protocol to P7)
  • μP7 pre-processor (will be used to pre-process firmware source code before compilation)


From software engineer’s point of view trace is a source code line (function with variable arguments list):

uP7DBG(0, hModule, "Iteration %I64d", llIter); 

And at another side it looks like that:

It is very similar to logging, but unlike logging - trace gives your much better performance in term of CPU cycles and transmission data bandwidth. To reach best performance next optimizations are used:

  • Do not format trace string on CPU side, variable arguments formatting is a heavy operation and it will be done on server side by request
  • Do not transmit duplicated/redundant information, for example string "Iteration %I64d" won't be sent to host, it will be even stripped out from the firmware
  • Deliver only changes for every subsequent trace call [variable arguments, sequence number, time with 100ns granularity, current thread, processor core number]
  • Use binary protocol instead of sending text
  • Use of pre-processor to collect all possible information in advance (file names, function names, code lines, etc.)


From software engineer’s point of view telemetry is a few source code lines:

huP7TelId  hCounter = uP7_TELEMETRY_INVALID_ID;
uP7TelCreateCounter("CPU/Cycle", 0, 0, 1, 1, true, &hCounter);

while (bProcessing)
    uP7TelSentSample(hCounter, 1);
    //some user code ...
    uP7TelSentSample(hCounter, 0);

And at another side it may looks like that (thread cyclograms, buffers sizes, delays, handles count, etc.):

Telemetry is a simple and fast way to record any dynamically changed values for further or real time analysis on Baical server side. You may use it for a lot of things: system statistics (cpu, memory, hdd, etc.), buffers filling, threads cyclograms or synchronization, mutexes, networks delays, packets sizes, etc. There are plenty of possible usage cases.