Format_args_nl macro seems to produce different results

Question: the format_args_nl macro seems to be giving me different results when formatting unicode,

output when printing in a std env

❯ cargo run --example fit ..\boards\bootloaders\rpi4\apertis\signed-rpi4-apertis.itb
   Compiling rustBoot v0.1.0 (C:\Users\Nil\devspace\rust\projects\rustBoot\rustBoot)
    Finished dev [unoptimized + debuginfo] target(s) in 0.81s
     Running `C:\Users\Nil\devspace\rust\projects\rustBoot\target\debug\examples\fit.exe ..\boards\bootloaders\rpi4\apertis\signed-rpi4-apertis.itb`
[INFO]  computing "kernel" hash: 97dcbff24ad0a60514e31a7a6b34a765681fea81f8dd11e4644f3ec81e1044fb
         ⌙ rustBoot::dt::fit @ line:289
[INFO]  kernel integrity consistent with supplied itb...
         ⌙ rustBoot::dt::fit @ line:298
[INFO]  computing "fdt" hash: 3572783be74511b710ed7fca9b3131e97fd8073c620a94269a4e4ce79d331540
         ⌙ rustBoot::dt::fit @ line:289
[INFO]  fdt integrity consistent with supplied itb...
         ⌙ rustBoot::dt::fit @ line:298
[INFO]  computing "ramdisk" hash: f1290587e2155e3a5c2c870fa1d6e3e2252fb0dddf74992113d2ed86bc67f37c
         ⌙ rustBoot::dt::fit @ line:289
[INFO]  ramdisk integrity consistent with supplied itb...
         ⌙ rustBoot::dt::fit @ line:298
[INFO]  computing "rbconfig" hash: 29f24b5b6a31dfaae8817bc40e6611fbb04ab4300b338d25436bdd56ec309586
         ⌙ rustBoot::dt::fit @ line:289
[INFO]  rbconfig integrity consistent with supplied itb...
         ⌙ rustBoot::dt::fit @ line:298

*********** ecdsa signature checks out, image is authentic ***********

output when printing in a no_std env (i.e. bare-metal on a rpi4):

[   48.077793] loaded fit: 62202019 bytes, starting at addr: 0xa0080
[   48.080927] authenticating fit-image...
[   82.624287] [INFO]  computing "kernel" hash: 97dcbff24ad0a60514e31a7a6b34a765681fea81f8dd11e4644f3ec81e1044fb
[   82.632022]              ↓ rustBoot::dt::fit @ line:289
[   82.637334] [INFO]  kernel integrity consistent with supplied itb...
[   82.644966]              ↓ rustBoot::dt::fit @ line:298
[   82.681473] [INFO]  computing "fdt" hash: 3572783be74511b710ed7fca9b3131e97fd8073c620a94269a4e4ce79d331540
[   82.688948]              ↓ rustBoot::dt::fit @ line:289
[   82.694245] [INFO]  fdt integrity consistent with supplied itb...
[   82.701632]              ↓ rustBoot::dt::fit @ line:298
[  121.519796] [INFO]  computing "ramdisk" hash: f1290587e2155e3a5c2c870fa1d6e3e2252fb0dddf74992113d2ed86bc67f37c
[  121.527617]              ↓ rustBoot::dt::fit @ line:289
[  121.532894] [INFO]  ramdisk integrity consistent with supplied itb...
[  121.540649]              ↓ rustBoot::dt::fit @ line:298
[  121.547074] [INFO]  computing "rbconfig" hash: 29f24b5b6a31dfaae8817bc40e6611fbb04ab4300b338d25436bdd56ec309586
[  121.556547]              ↓ rustBoot::dt::fit @ line:289
[  121.561821] [INFO]  rbconfig integrity consistent with supplied itb...
[  121.569665]              ↓ rustBoot::dt::fit @ line:298

*********** ecdsa signature checks out, image is authentic ***********

The result produced in the std env is the expected output. \u{2319} is an angled bracket but instead I get a down arrow (which is \u19). I'm not sure what's happening but it seems to skip the first 2 unicode characters altogether. The no_std logging implementation is pretty much identical to the regular println.

In the std case, println is from std library and simply does this

fn log(&self, record: &Record) {
        if self.enabled(record.metadata()) {
            println!("\x1b[93m[{}]\x1b[0m  {}", record.level(), record.args());
            match (record.module_path(), record.line()) {
                (Some(file), Some(line)) => {
                    println!("\t \u{2319} {} @ line:{}", file, line);
                }
                (_, None) => {
                    println!("... ")
                }
                (_, Some(line)) => println!("\t  \u{2a3d} {} @ line:{}", record.target(), line),
                (Some(file), None) => println!("\t  \u{2a3d} @ {}", file),
            }
        }
    }

macro_rules! println {
    () => {
        $crate::print!("\n")
    };
    ($($arg:tt)*) => {
        $crate::io::_print($crate::format_args_nl!($($arg)*))
    };
}

In the no_std impl, info is a custom macro that pretty much tries to mimic println.

fn log(&self, record: &Record) {
        if self.enabled(record.metadata()) {
            info!("\x1b[93m[{}]\x1b[0m  {}", record.level(), record.args());
            match (record.module_path(), record.line()) {
                (Some(file), Some(line)) => {
                    info!("          \u{2319} {} @ line:{}", file, line);
                }
                (None, None) => {info!("... ")}
                (None, Some(line)) => info!("\t  \u{2a3d} {} @ line:{}", record.target(), line),
                (Some(file), None) => info!("\t  \u{2a3d} @ {}", file),
            }
            
        }
    }

macro_rules! info {
    ($format_string:expr, $($arg:tt)*) => ({
        #[allow(unused_imports)]
        use $crate::rpi::rpi4::arch::time::*;

        let timestamp = time_manager().uptime();
        let timestamp_subsec_us = timestamp.subsec_micros();

        $crate::rpi::rpi4::log::print::_print(format_args_nl!(
            concat!("[  {:>3}.{:03}{:03}] ", $format_string),
            timestamp.as_secs(),
            timestamp_subsec_us / 1_000,
            timestamp_subsec_us % 1_000,
            $($arg)*
        ));
    })
}

Checking again - I cant seem to figure this one. But I'm pretty sure I'm missing something

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.