diff options
| author | Bjorn <[email protected]> | 2024-10-31 22:51:03 -0700 |
|---|---|---|
| committer | Bjorn <[email protected]> | 2024-10-31 22:51:03 -0700 |
| commit | 333d8584812c0ea3e1f9262922befbd3fe709775 (patch) | |
| tree | 4b9079f70f4283185ac7a7b94247ee7752e42967 /embassy-usb-logger/src | |
| parent | f319f1bc1b36cd6c7860391e49083ee64c079547 (diff) | |
Added ReceiverHandler to logger
Diffstat (limited to 'embassy-usb-logger/src')
| -rw-r--r-- | embassy-usb-logger/src/lib.rs | 92 |
1 files changed, 79 insertions, 13 deletions
diff --git a/embassy-usb-logger/src/lib.rs b/embassy-usb-logger/src/lib.rs index 11188b4ef..29c102f10 100644 --- a/embassy-usb-logger/src/lib.rs +++ b/embassy-usb-logger/src/lib.rs | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #![warn(missing_docs)] | 3 | #![warn(missing_docs)] |
| 4 | 4 | ||
| 5 | use core::fmt::Write as _; | 5 | use core::fmt::Write as _; |
| 6 | use core::future::Future; | ||
| 6 | 7 | ||
| 7 | use embassy_futures::join::join; | 8 | use embassy_futures::join::join; |
| 8 | use embassy_sync::pipe::Pipe; | 9 | use embassy_sync::pipe::Pipe; |
| @@ -13,6 +14,25 @@ use log::{Metadata, Record}; | |||
| 13 | 14 | ||
| 14 | type CS = embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 15 | type CS = embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 15 | 16 | ||
| 17 | /// A trait that can be implemented and then passed to the | ||
| 18 | pub trait ReceiverHandler { | ||
| 19 | /// Data comes in from the serial port with each command and runs this function | ||
| 20 | fn handle_data(&self, data: &[u8]) -> impl Future<Output = ()> + Send; | ||
| 21 | |||
| 22 | /// Create a new instance of the Handler | ||
| 23 | fn new() -> Self; | ||
| 24 | } | ||
| 25 | |||
| 26 | /// Use this Handler if you don't wish to use any handler | ||
| 27 | pub struct DummyHandler; | ||
| 28 | |||
| 29 | impl ReceiverHandler for DummyHandler { | ||
| 30 | async fn handle_data(&self, _data: &[u8]) {} | ||
| 31 | fn new() -> Self { | ||
| 32 | Self {} | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 16 | /// The logger state containing buffers that must live as long as the USB peripheral. | 36 | /// The logger state containing buffers that must live as long as the USB peripheral. |
| 17 | pub struct LoggerState<'d> { | 37 | pub struct LoggerState<'d> { |
| 18 | state: State<'d>, | 38 | state: State<'d>, |
| @@ -39,17 +59,19 @@ impl<'d> LoggerState<'d> { | |||
| 39 | pub const MAX_PACKET_SIZE: u8 = 64; | 59 | pub const MAX_PACKET_SIZE: u8 = 64; |
| 40 | 60 | ||
| 41 | /// The logger handle, which contains a pipe with configurable size for buffering log messages. | 61 | /// The logger handle, which contains a pipe with configurable size for buffering log messages. |
| 42 | pub struct UsbLogger<const N: usize> { | 62 | pub struct UsbLogger<const N: usize, T: ReceiverHandler + Send + Sync> { |
| 43 | buffer: Pipe<CS, N>, | 63 | buffer: Pipe<CS, N>, |
| 44 | custom_style: Option<fn(&Record, &mut Writer<'_, N>) -> ()>, | 64 | custom_style: Option<fn(&Record, &mut Writer<'_, N>) -> ()>, |
| 65 | recieve_handler: Option<T>, | ||
| 45 | } | 66 | } |
| 46 | 67 | ||
| 47 | impl<const N: usize> UsbLogger<N> { | 68 | impl<const N: usize, T: ReceiverHandler + Send + Sync> UsbLogger<N, T> { |
| 48 | /// Create a new logger instance. | 69 | /// Create a new logger instance. |
| 49 | pub const fn new() -> Self { | 70 | pub const fn new() -> Self { |
| 50 | Self { | 71 | Self { |
| 51 | buffer: Pipe::new(), | 72 | buffer: Pipe::new(), |
| 52 | custom_style: None, | 73 | custom_style: None, |
| 74 | recieve_handler: None, | ||
| 53 | } | 75 | } |
| 54 | } | 76 | } |
| 55 | 77 | ||
| @@ -58,9 +80,15 @@ impl<const N: usize> UsbLogger<N> { | |||
| 58 | Self { | 80 | Self { |
| 59 | buffer: Pipe::new(), | 81 | buffer: Pipe::new(), |
| 60 | custom_style: Some(custom_style), | 82 | custom_style: Some(custom_style), |
| 83 | recieve_handler: None, | ||
| 61 | } | 84 | } |
| 62 | } | 85 | } |
| 63 | 86 | ||
| 87 | /// Add a command handler to the logger | ||
| 88 | pub fn with_handler(&mut self, handler: T) { | ||
| 89 | self.recieve_handler = Some(handler); | ||
| 90 | } | ||
| 91 | |||
| 64 | /// Run the USB logger using the state and USB driver. Never returns. | 92 | /// Run the USB logger using the state and USB driver. Never returns. |
| 65 | pub async fn run<'d, D>(&'d self, state: &'d mut LoggerState<'d>, driver: D) -> ! | 93 | pub async fn run<'d, D>(&'d self, state: &'d mut LoggerState<'d>, driver: D) -> ! |
| 66 | where | 94 | where |
| @@ -118,15 +146,22 @@ impl<const N: usize> UsbLogger<N> { | |||
| 118 | } | 146 | } |
| 119 | } | 147 | } |
| 120 | }; | 148 | }; |
| 121 | let discard_fut = async { | 149 | let reciever_fut = async { |
| 122 | let mut discard_buf: [u8; MAX_PACKET_SIZE as usize] = [0; MAX_PACKET_SIZE as usize]; | 150 | let mut reciever_buf: [u8; MAX_PACKET_SIZE as usize] = [0; MAX_PACKET_SIZE as usize]; |
| 123 | receiver.wait_connection().await; | 151 | receiver.wait_connection().await; |
| 124 | loop { | 152 | loop { |
| 125 | let _ = receiver.read_packet(&mut discard_buf).await; | 153 | let n = receiver.read_packet(&mut reciever_buf).await.unwrap(); |
| 154 | match &self.recieve_handler { | ||
| 155 | Some(handler) => { | ||
| 156 | let data = &reciever_buf[..n]; | ||
| 157 | handler.handle_data(data).await; | ||
| 158 | } | ||
| 159 | None => (), | ||
| 160 | } | ||
| 126 | } | 161 | } |
| 127 | }; | 162 | }; |
| 128 | 163 | ||
| 129 | join(log_fut, discard_fut).await; | 164 | join(log_fut, reciever_fut).await; |
| 130 | } | 165 | } |
| 131 | 166 | ||
| 132 | /// Creates the futures needed for the logger from a given class | 167 | /// Creates the futures needed for the logger from a given class |
| @@ -142,7 +177,7 @@ impl<const N: usize> UsbLogger<N> { | |||
| 142 | } | 177 | } |
| 143 | } | 178 | } |
| 144 | 179 | ||
| 145 | impl<const N: usize> log::Log for UsbLogger<N> { | 180 | impl<const N: usize, T: ReceiverHandler + Send + Sync> log::Log for UsbLogger<N, T> { |
| 146 | fn enabled(&self, _metadata: &Metadata) -> bool { | 181 | fn enabled(&self, _metadata: &Metadata) -> bool { |
| 147 | true | 182 | true |
| 148 | } | 183 | } |
| @@ -182,7 +217,7 @@ impl<'d, const N: usize> core::fmt::Write for Writer<'d, N> { | |||
| 182 | 217 | ||
| 183 | /// Initialize and run the USB serial logger, never returns. | 218 | /// Initialize and run the USB serial logger, never returns. |
| 184 | /// | 219 | /// |
| 185 | /// Arguments specify the buffer size, log level and the USB driver, respectively. | 220 | /// Arguments specify the buffer size, log level and the USB driver, respectively. You can optionally add a RecieverHandler. |
| 186 | /// | 221 | /// |
| 187 | /// # Usage | 222 | /// # Usage |
| 188 | /// | 223 | /// |
| @@ -196,17 +231,27 @@ impl<'d, const N: usize> core::fmt::Write for Writer<'d, N> { | |||
| 196 | #[macro_export] | 231 | #[macro_export] |
| 197 | macro_rules! run { | 232 | macro_rules! run { |
| 198 | ( $x:expr, $l:expr, $p:ident ) => { | 233 | ( $x:expr, $l:expr, $p:ident ) => { |
| 199 | static LOGGER: ::embassy_usb_logger::UsbLogger<$x> = ::embassy_usb_logger::UsbLogger::new(); | 234 | static LOGGER: ::embassy_usb_logger::UsbLogger<$x, ::embassy_usb_logger::DummyHandler> = |
| 235 | ::embassy_usb_logger::UsbLogger::new(); | ||
| 200 | unsafe { | 236 | unsafe { |
| 201 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); | 237 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); |
| 202 | } | 238 | } |
| 203 | let _ = LOGGER.run(&mut ::embassy_usb_logger::LoggerState::new(), $p).await; | 239 | let _ = LOGGER.run(&mut ::embassy_usb_logger::LoggerState::new(), $p).await; |
| 204 | }; | 240 | }; |
| 241 | |||
| 242 | ( $x:expr, $l:expr, $p:ident, $h:ty ) => { | ||
| 243 | unsafe { | ||
| 244 | static mut LOGGER: ::embassy_usb_logger::UsbLogger<$x, $h> = ::embassy_usb_logger::UsbLogger::new(); | ||
| 245 | LOGGER.with_handler(<$h>::new()); | ||
| 246 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); | ||
| 247 | let _ = LOGGER.run(&mut ::embassy_usb_logger::LoggerState::new(), $p).await; | ||
| 248 | } | ||
| 249 | }; | ||
| 205 | } | 250 | } |
| 206 | 251 | ||
| 207 | /// Initialize the USB serial logger from a serial class and return the future to run it. | 252 | /// Initialize the USB serial logger from a serial class and return the future to run it. |
| 208 | /// | 253 | /// |
| 209 | /// Arguments specify the buffer size, log level and the serial class, respectively. | 254 | /// Arguments specify the buffer size, log level and the serial class, respectively. You can optionally add a RecieverHandler. |
| 210 | /// | 255 | /// |
| 211 | /// # Usage | 256 | /// # Usage |
| 212 | /// | 257 | /// |
| @@ -220,19 +265,29 @@ macro_rules! run { | |||
| 220 | #[macro_export] | 265 | #[macro_export] |
| 221 | macro_rules! with_class { | 266 | macro_rules! with_class { |
| 222 | ( $x:expr, $l:expr, $p:ident ) => {{ | 267 | ( $x:expr, $l:expr, $p:ident ) => {{ |
| 223 | static LOGGER: ::embassy_usb_logger::UsbLogger<$x> = ::embassy_usb_logger::UsbLogger::new(); | 268 | static LOGGER: ::embassy_usb_logger::UsbLogger<$x, ::embassy_usb_logger::DummyHandler> = |
| 269 | ::embassy_usb_logger::UsbLogger::new(); | ||
| 224 | unsafe { | 270 | unsafe { |
| 225 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); | 271 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); |
| 226 | } | 272 | } |
| 227 | LOGGER.create_future_from_class($p) | 273 | LOGGER.create_future_from_class($p) |
| 228 | }}; | 274 | }}; |
| 275 | |||
| 276 | ( $x:expr, $l:expr, $p:ident, $h:ty ) => {{ | ||
| 277 | unsafe { | ||
| 278 | static mut LOGGER: ::embassy_usb_logger::UsbLogger<$x, $h> = ::embassy_usb_logger::UsbLogger::new(); | ||
| 279 | LOGGER.with_handler(<$h>::new()); | ||
| 280 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); | ||
| 281 | LOGGER.create_future_from_class($p) | ||
| 282 | } | ||
| 283 | }}; | ||
| 229 | } | 284 | } |
| 230 | 285 | ||
| 231 | /// Initialize the USB serial logger from a serial class and return the future to run it. | 286 | /// Initialize the USB serial logger from a serial class and return the future to run it. |
| 232 | /// This version of the macro allows for a custom style function to be passed in. | 287 | /// This version of the macro allows for a custom style function to be passed in. |
| 233 | /// The custom style function will be called for each log record and is responsible for writing the log message to the buffer. | 288 | /// The custom style function will be called for each log record and is responsible for writing the log message to the buffer. |
| 234 | /// | 289 | /// |
| 235 | /// Arguments specify the buffer size, log level, the serial class and the custom style function, respectively. | 290 | /// Arguments specify the buffer size, log level, the serial class and the custom style function, respectively. You can optionally add a RecieverHandler. |
| 236 | /// | 291 | /// |
| 237 | /// # Usage | 292 | /// # Usage |
| 238 | /// | 293 | /// |
| @@ -250,10 +305,21 @@ macro_rules! with_class { | |||
| 250 | #[macro_export] | 305 | #[macro_export] |
| 251 | macro_rules! with_custom_style { | 306 | macro_rules! with_custom_style { |
| 252 | ( $x:expr, $l:expr, $p:ident, $s:expr ) => {{ | 307 | ( $x:expr, $l:expr, $p:ident, $s:expr ) => {{ |
| 253 | static LOGGER: ::embassy_usb_logger::UsbLogger<$x> = ::embassy_usb_logger::UsbLogger::with_custom_style($s); | 308 | static LOGGER: ::embassy_usb_logger::UsbLogger<$x, ::embassy_usb_logger::DummyHandler> = |
| 309 | ::embassy_usb_logger::UsbLogger::with_custom_style($s); | ||
| 254 | unsafe { | 310 | unsafe { |
| 255 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); | 311 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); |
| 256 | } | 312 | } |
| 257 | LOGGER.create_future_from_class($p) | 313 | LOGGER.create_future_from_class($p) |
| 258 | }}; | 314 | }}; |
| 315 | |||
| 316 | ( $x:expr, $l:expr, $p:ident, $s:expr, $h:ty ) => {{ | ||
| 317 | unsafe { | ||
| 318 | static mut LOGGER: ::embassy_usb_logger::UsbLogger<$x, $h> = | ||
| 319 | ::embassy_usb_logger::UsbLogger::with_custom_style($s); | ||
| 320 | LOGGER.with_handler(<$h>::new()); | ||
| 321 | let _ = ::log::set_logger_racy(&LOGGER).map(|()| log::set_max_level_racy($l)); | ||
| 322 | LOGGER.create_future_from_class($p) | ||
| 323 | } | ||
| 324 | }}; | ||
| 259 | } | 325 | } |
