Crate stlog [] [src]

Lightweight logging framework for resource constrained devices

stlog running on a Cortex-M microcontroller

Features

  • O(1) runtime. Logging strings of arbitrary size takes a constant number of instructions.

  • O(0) memory usage. The logged strings are NOT stored in the device memory.

  • Supports different logging levels: trace, debug, info, warn and error. Each level can be individually disabled at compile time.

  • Provides a "global" logging mode

Non-features

  • printf style or any other kind of formatting

Limitations

  • The current implementation only supports 256 different log strings. This restriction will be lifted in the future.

Requirements

The application must be linked using the stlog.x linker script provided by this crate. The easiest way to do this is to use the -C link-arg rustc flag:

$ cat .cargo/config
[target.thumbv7m-none-eabi]
rustflags = [
    "-C", "link-arg=-Tstlog.x",
    # ..
]

Example

Minimal

  • Device side
#[macro_use]
extern crate stlog;

struct Logger { .. }

impl stlog::Logger for Logger { .. }

fn main() {
    let logger = Logger { .. };

    info!(logger, "Hello, world!");
    warn!(logger, "The quick brown fox jumps over the lazy dog.");
}
  • Host side
$ # flash and execute the device program
$ arm-none-eabi-gdb /path/to/device/binary &

$ # stcat is required to decode strings logged via `stlog`
$ cargo install stcat --vers 0.1.0

$ cat /dev/ttyUSB0 | stcat -e /path/to/device/binary
INFO Hello, world!
WARN The quick brown fox jumps over the lazy dog.

Assuming that the device is logging the strings through the /dev/ttyUSB0 interface. The device binary must not be stripped.

Global logging

If the first argument is omitted from the logging macros logging will be performed using the global logger. The global logger must be selected using the set_global_logger! macro.

// Global logger
struct Logger;

impl stlog::Logger for Logger {
    // required: the error type must be `!`
    type Error = !;

    fn log(&self, addr: u8) -> Result<(), !> {
        interrupt::free(|cs| {
            // ..
        });
    }
}

set_global_logger!(Logger);

fn main() {
    info!("Hello");
}

fn isr() {
    info!("World");
}

Disabling certain log levels

The Logger trait includes methods to disable certain log levels. By default all the log levels are enabled.

// Global logger
struct Logger;

impl stlog::Logger for Logger {
    type Error = !;

    fn log(&self, addr: u8) -> Result<(), !> { .. }

    // disable `trace!` and `debug!`
    fn trace_enabled(&self) -> bool { false }
    fn debug_enabled(&self) -> bool { false }
}

Troubleshooting

Didn't pass -Tstlog.x to the linker

Symptom

$ cat /dev/ttyUSB0 | stcat -e /path/to/device/binary
Error: _sstlog_trace symbol not found

Solution

Pass -Tstlog.x to the linker using the method shown in the requirements section.

Macros

debug

Logs $string at the DEBUG log level

error

Logs $string at the ERROR log level

info

Logs $string at the INFO log level

set_global_logger

Sets the global logger

trace

Logs $string at the TRACE log level

warn

Logs $string at the WARN log level

Traits

Logger

A logger compatible with the stlog logging framework