Module cortex_m_log::log

source ·
Expand description

Integration with log

As embedded development implies #[no_std] we cannot box our logger so instead simplest approach would be to declare our logger static

use log::info;
use cortex_m_log::log::{Logger, init};
use cortex_m_log::printer::Dummy;

static LOGGER: Logger<Dummy> = Logger {
    inner: Dummy::new(),
    level: log::LevelFilter::Off
};

fn main() {
    init(&LOGGER).expect("To set logger");

    info!("Starting my cute program");
}

Of course since there is no const-fn and some printers require Initialization function we need some better way.

One way to do it would be to trick compiler by changing lifetime of stack allocated logger to static, obviously unsafe.

use core::mem;

use cortex_m_log::log::{Logger, trick_init};
use cortex_m_log::printer::semihosting;
use cortex_m_log::modes::InterruptOk;

let logger = Logger {
    //Uses semihosting as destination with no interrupt control.
    inner: semihosting::InterruptOk::<_>::stdout().expect("Get Semihosting stdout"),
    level: log::LevelFilter::Info
};
//Haha trust me, it is safe ;)
//As long as logger is not dropped....
unsafe {
    let _ = trick_init(&logger);
}

Obviously it is UB to drop logger after that and use any of log’s macros

Structs

  • Simple Logger implementation

Functions

  • Initialize logging facilities.
  • Performs init by tricking compiler into beliving that &Logger is static.