#串口 #panic-handler #panic #panic-message #serial #arduino #uart

nightly no-std panic-serial

在串口打印panic信息

3个版本

0.1.2 2023年3月2日
0.1.1 2023年3月2日
0.1.0 2023年3月2日

716嵌入式开发

MIT 许可证

11KB
53

panic-serial

通过串口打印panic信息,然后进入无限循环。

状态:实验性;倾向于Arduino

此crate实现了一个panic处理器,它会在串口(或其他类型的输出 - 见下文)上打印panic信息。

为什么?

看到panic消息(或者至少它们的地址)是理解发生了什么错误的关键。

我不想没有它。

打印了什么?

根据您愿意在固件中浪费多少空间,panic可以在三个不同细节级别上打印,这取决于您选择的 功能标志

  • location:打印位置信息。例如
    Panic at src/main.rs:91:9
    
  • message:打印实际的完整panic消息。这使用了 core::fmt,因此预期固件大小会增加。例如
    attempt to subtract with overflow
    
  • full == location & message:结合位置和消息。例如
    Panic at src/main.rs:91:9: attempt to subtract with overflow
    
  • (没有功能):如果没有选择任何功能,则打印静态消息。例如
    PANIC !
    
    此选项对固件大小最为简单。

使用方法

可以在以下位置找到基于这些说明的Arduino Uno示例项目: https://github.com/nilclass/panic-serial-example

  1. 删除任何现有的panic处理器。例如,如果您目前正在使用 panic_halt,请删除该依赖项及其使用。
  2. panic-serial 依赖项添加到您的项目中
    # Check "What is printed" section above for features to choose
    cargo add panic-serial --features full
    
  3. 在您的 main.rs(或顶级其他地方)中调用 impl_panic_handler
    panic_serial::impl_panic_handler!(
      // This is the type of the UART port to use for printing the message:
      arduino_hal::usart::Usart<
        arduino_hal::pac::USART0,
        arduino_hal::port::Pin<arduino_hal::port::mode::Input, arduino_hal::hal::port::PD0>,
        arduino_hal::port::Pin<arduino_hal::port::mode::Output, arduino_hal::hal::port::PD1>
      >
    );
    

这将执行以下两项操作

  • 定义实际的panic处理器
  • 定义一个名为 share_serial_port_with_panic 的函数,我们将将其用于下一步
  1. main 中调用 share_serial_port_with_panic
    #[arduino_hal::entry]
    fn main() -> ! {
      // ...
      let serial = arduino_hal::default_serial!(dp, pins, 57600);
      // this gives ownership of the serial port to panic-serial. We receive a mutable reference to it though, so we can keep using it.
      let serial = share_serial_port_with_panic(serial);
      // continue using serial:
      ufmt::uwriteln!(serial, "Hello there!\r").unwrap();
    
      // ...
    }
    

它如何工作?

impl_panic_handler 定义了一个可变的静态变量 PANIC_PORT: Option<$your_type>。当你调用 share_serial_port_with_panic 时,这个选项被填充,并且你将得到 PANIC_PORT.as_mut().unwrap()

如果发生恐慌,恐慌处理程序要么无限循环(如果你从未调用过 share_serial_port_with_panic),要么将恐慌信息打印到指定的端口。它分两步完成

  1. 调用 port.flush()
  2. 使用 ufmt(或 core::fmt)来打印片段。

从技术上讲,这可以与实现 ufmt::uWrite 且具有 flush() 方法的任何东西一起工作。

这有多不安全?

当你发现时,请告诉我。

许可证:MIT

依赖项

~1.5MB
~37K SLoC