1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
//! Debug logging facade. //! //! This module implements standard output/error interface, which mimics Rust's //! standard library. This is a facade module. Concrete output implementation //! should be provided by downstream crates. //! //! Reserved ports: //! //! * `0` - standard output //! * `1` - standard error //! * `31` - heap trace #![cfg_attr(feature = "std", allow(unreachable_code, unused_variables))] mod macros; mod port; /// Returns log output baud rate defined in `Drone.toml`. /// /// # Examples /// /// ``` /// # #![feature(proc_macro_hygiene)] /// # drone_core::config_override! { " /// # [memory] /// # flash = { size = \"128K\", origin = 0x08000000 } /// # ram = { size = \"20K\", origin = 0x20000000 } /// # [heap.main] /// # size = \"0\" /// # pools = [] /// # [linker] /// # platform = \"arm\" /// # [probe] /// # gdb-client-command = \"gdb-multiarch\" /// # [log.dso] /// # baud-rate = 115200 /// # serial-endpoint = \"/dev/ttyACM0\" /// # " } /// use drone_core::log; /// /// assert_eq!(log::baud_rate!(), 115_200); /// ``` #[doc(inline)] pub use drone_core_macros::log_baud_rate as baud_rate; pub use self::port::Port; use core::{fmt, fmt::Write}; extern "C" { pub(crate) fn drone_log_is_enabled(port: u8) -> bool; pub(crate) fn drone_log_write_bytes(port: u8, buffer: *const u8, count: usize); pub(crate) fn drone_log_write_u8(port: u8, value: u8); pub(crate) fn drone_log_write_u16(port: u8, value: u16); pub(crate) fn drone_log_write_u32(port: u8, value: u32); pub(crate) fn drone_log_flush(); } /// Number of ports. pub const PORTS_COUNT: u8 = 32; /// Port number of the standard output stream. pub const STDOUT_PORT: u8 = 0; /// Port number of the standard error stream. pub const STDERR_PORT: u8 = 1; /// Returns port for standard output. #[inline] pub fn stdout() -> Port { Port::new(STDOUT_PORT) } /// Returns port for standard error. #[inline] pub fn stderr() -> Port { Port::new(STDERR_PORT) } /// Writes `string` to the log port number `port`. /// /// The presence of the debug probe is not checked, so it is recommended to use /// this function together with [`Port::is_enabled`]. /// /// # Examples /// /// ``` /// use drone_core::{log, log::Port}; /// /// if Port::new(11).is_enabled() { /// log::write_str(11, "hello there!\n"); /// } /// ``` #[inline(never)] pub fn write_str(port: u8, string: &str) { let _ = Port::new(port).write_str(string); } /// Writes `args` to the log port number `port`. /// /// The presence of the debug probe is not checked, so it is recommended to use /// this function together with [`Port::is_enabled`]. /// /// # Examples /// /// ``` /// use drone_core::{log, log::Port}; /// /// let a = 0; /// /// if Port::new(11).is_enabled() { /// log::write_fmt(11, format_args!("a = {}\n", a)); /// } /// ``` #[inline(never)] pub fn write_fmt(port: u8, args: fmt::Arguments<'_>) { let _ = Port::new(port).write_fmt(args); } /// Blocks until all pending packets are transmitted. /// /// This function is a no-op if no debug probe is connected and listening. #[inline] pub fn flush() { #[cfg(feature = "std")] return; unsafe { drone_log_flush() }; }