我有以下

问题描述 投票:0回答:0

以及以下宏:

macro_rules! log {
    ($verbosity: expr, $s: expr $(, $args: expr)*) => {
        if $crate::logger::LOGGER.get_verbosity(module_path!()) <= $verbosity {
                println_serial!("[{}] {}:{} {}", $verbosity, file!(), line!(), $s);
                println_serial!($s $(, $args)*);

                let log = $crate::logger::Log {
                    file: file!(),
                    line: line!(),
                    verbosity: $verbosity,
                    message: alloc::format!($s $(, $args)*)
                };
                $crate::logger::LOGGER.push_log(log); // this triggers a println_serial! call 
            }
        }
}
我在一个工作的宏观上进行了调试!当我运行宏观如下时:

println_serial!
我得到以下输出:

log!(logger::Verbosity::Info, "Simple static string test");
Full脚本

[INFO] src/main.rs:83 Simple static string test
Simple static string test

logger.rs

use alloc::string::String; use hashbrown::HashMap; use crate::{ interrupts::guard::InterruptLock, util::circular_buffer::CircularBuffer, }; macro_rules! log { ($verbosity: expr, $s: expr $(, $args: expr)*) => { if $crate::logger::LOGGER.get_verbosity(module_path!()) <= $verbosity { let log = $crate::logger::Log { file: file!(), line: line!(), verbosity: $verbosity, message: alloc::format!($s $(, $args)*) }; $crate::logger::LOGGER.push_log(log); } } } pub static LOGGER: Logger = Logger::new(); pub struct Log { pub file: &'static str, pub line: u32, pub verbosity: Verbosity, pub message: String, } impl core::fmt::Display for Log { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_fmt(format_args!( "[{}] {}:{} {}", self.verbosity, self.file, self.line, self.message ))?; Ok(()) } } #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq)] pub enum Verbosity { Debug, Info, Warning, Error, } impl core::fmt::Display for Verbosity { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::Debug => f.write_str("DEBUG"), Self::Info => f.write_str("INFO"), Self::Warning => f.write_str("WARNING"), Self::Error => f.write_str("ERROR"), }?; Ok(()) } } pub struct Logger { verbose: InterruptLock<Option<HashMap<String, Verbosity>>>, logs: InterruptLock<CircularBuffer<Log, 1024>>, } impl Logger { const fn new() -> Self { Logger { verbose: InterruptLock::new(None), logs: InterruptLock::new(CircularBuffer::new()), } } pub fn get_verbosity(&self, module: &str) -> Verbosity { *self .verbose .lock() .as_ref() .expect("Logger not initialized") .get(module) .unwrap_or(&Verbosity::Info) } pub fn push_log(&self, log: Log) { if self.logs.lock().push_back(log).is_err() { panic!("Dropped log"); } } pub fn trigger(&self) { while let Some(log) = self.logs.lock().pop_front() { println_serial!("{}", log); } } } pub fn init(verbose: HashMap<String, Verbosity>) { *LOGGER.verbose.lock() = Some(verbose); } pub fn trigger() { LOGGER.trigger() }

circular_buffer.rs

use core::mem::MaybeUninit;

use thiserror_no_std::Error;

#[derive(Error, Debug)]
#[error("Failed to push item into buffer")]
pub struct PushError;

pub struct CircularBuffer<T, const N: usize> {
    array: [MaybeUninit<T>; N],
    head: usize,
    tail: usize,
}

impl<T, const N: usize> CircularBuffer<T, N> {
    pub const fn new() -> Self {
        Self {
            array: MaybeUninit::uninit_array(),
            head: 0,
            tail: 0,
        }
    }

    pub fn push_back(&mut self, item: T) -> Result<(), PushError> {
        let insertion_index = self.tail;

        match self.increment_tail() {
            Some(tail) => self.tail = tail,
            None => return Err(PushError),
        }

        self.array[insertion_index] = MaybeUninit::new(item);
        Ok(())
    }

    pub fn pop_front(&mut self) -> Option<T> {
        let index = self.head;

        if self.head == self.tail {
            return None;
        }

        wrapping_increment(&mut self.head, N);

        if self.tail == N + 1 {
            self.tail = index;
        }

        let mut ret = MaybeUninit::uninit();
        core::mem::swap(&mut ret, &mut self.array[index]);
        unsafe { Some(ret.assume_init()) }
    }

    fn increment_tail(&mut self) -> Option<usize> {
        if self.tail == N + 1 {
            return None;
        }

        wrapping_increment(&mut self.tail, N);

        if self.tail == self.head {
            self.tail = N + 1;
        }

        Some(self.tail)
    }
}

fn wrapping_increment(i: &mut usize, container_size: usize) {
    *i = (*i + 1) % container_size
}

guard.rs

notice不存在
use core::{
    arch::asm,
    cell::UnsafeCell,
    ops::{Deref, DerefMut},
    sync::atomic::{AtomicUsize, Ordering},
};

static NUM_GUARDS: AtomicUsize = AtomicUsize::new(0);

pub struct InterruptGuard<'a, T> {
    data: &'a mut T,
}

impl<'a, T> Drop for InterruptGuard<'a, T> {
    fn drop(&mut self) {
        if NUM_GUARDS.fetch_sub(1, Ordering::SeqCst) == 1 {
            unsafe {
                asm!("sti");
            }
        }
    }
}

impl<'a, T> Deref for InterruptGuard<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        self.data
    }
}

impl<'a, T> DerefMut for InterruptGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        self.data
    }
}

pub struct InterruptLock<T> {
    data: UnsafeCell<T>,
}

impl<T> InterruptLock<T> {
    pub const fn new(data: T) -> InterruptLock<T> {
        InterruptLock {
            data: UnsafeCell::new(data),
        }
    }

    pub fn lock(&self) -> InterruptGuard<'_, T> {
        NUM_GUARDS.fetch_add(1, Ordering::SeqCst);

        unsafe {
            asm!("cli");
        }

        unsafe {
            InterruptGuard {
                data: &mut *self.data.get(),
            }
        }
    }
}

// NOTE: Sync implementation assumes single threaded os
unsafe impl<T> Sync for InterruptLock<T> {}
的输出。我希望宏仅通过使用其他宏来使用

LOGGER
调用来工作。删除后,未能获得输出。

alloc::format!()

函数本质上使用
println_serial!
宏!
  • 我在一个领域工作

    使用在主函数中调用的
    push_log
    函数调用所有记录。 
    println_serial!
    函数从缓冲区弹出日志,并将其传递到
    no_std

  • 奇特的宏也可以与其他表达式一起工作(ex:
    trigger

    PS:这是自定义内核项目的一部分,因此有很多代码。也很高兴也分享,我只是想我会分享核心位。
  • 在大量挖掘后,问题与实现记录器的方式无关。该错误实际上是我的自定义内存分配器的实现方式,这就是为什么失败的原因。 在评论中为每个人的所有人致意,他们帮助我进一步完善了这个问题。

    	

rust rust-macros rust-no-std
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.