cortex_m_log/printer/
itm.rs

1//! Itm module
2
3use cortex_m::interrupt::Mutex;
4
5use crate::destination;
6use crate::modes::InterruptModer;
7
8use core::marker::PhantomData;
9use core::fmt::{self, Write};
10
11/// ITM backed printer
12pub struct Itm<M: InterruptModer> {
13    inner: destination::Itm,
14    _mod: PhantomData<M>
15}
16
17impl<M: InterruptModer> Itm<M> {
18    ///Constructs new instance
19    pub fn new(itm: destination::Itm) -> Self {
20        Self { inner: itm, _mod: PhantomData }
21    }
22}
23
24impl<Mode: InterruptModer> super::Printer for Itm<Mode> {
25    type W = destination::Itm;
26    type M = Mode;
27
28    #[inline]
29    fn destination(&mut self) -> &mut Self::W {
30        &mut self.inner
31    }
32}
33
34/// ITM backed printer with `Sync`
35pub struct ItmSync<M: InterruptModer> {
36    inner: destination::Itm,
37    lock: Mutex<()>,
38    _mod: PhantomData<M>,
39}
40
41impl<M: InterruptModer> ItmSync<M> {
42    ///Constructs new instance
43    pub fn new(itm: destination::Itm) -> Self {
44        Self { inner: itm, lock: Mutex::new(()), _mod: PhantomData }
45    }
46}
47
48impl<Mode: InterruptModer> super::Printer for ItmSync<Mode> {
49    type W = destination::Itm;
50    type M = Mode;
51
52    #[inline]
53    fn destination(&mut self) -> &mut Self::W {
54        &mut self.inner
55    }
56
57    #[inline]
58    ///Prints formatted output to destination
59    fn print(&mut self, args: fmt::Arguments) {
60        cortex_m::interrupt::free(|cs| {
61            let _lock = self.lock.borrow(cs);
62            let _ = self.inner.write_fmt(args);
63        });
64    }
65
66    #[inline]
67    ///Prints formatted output to destination with newline
68    fn println(&mut self, args: fmt::Arguments) {
69        cortex_m::interrupt::free(|cs| {
70            let _lock = self.lock.borrow(cs);
71            let _ = self.inner.write_fmt(args);
72            let _ = self.inner.write_str("\n");
73        });
74    }
75}
76
77unsafe impl<Mode: InterruptModer> Sync for ItmSync<Mode> {}
78
79/// ITM backed printer with the assumption of `Sync`
80/// This does *not* actually `Sync`'ronize access to the ITM
81/// For proper `Sync`, use `ItmSync`.
82pub struct ItmAssumeSync {
83    inner: destination::Itm,
84}
85
86impl ItmAssumeSync {
87    ///Constructs new instance.
88    ///
89    ///This is unsafe, because type is assumed to be `Sync` while it is not.
90    pub unsafe fn new(itm: destination::Itm) -> Self {
91        Self { inner: itm }
92    }
93}
94
95impl super::Printer for ItmAssumeSync {
96    type W = destination::Itm;
97    type M = crate::modes::InterruptOk;
98
99    #[inline]
100    fn destination(&mut self) -> &mut Self::W {
101        &mut self.inner
102    }
103
104    #[inline]
105    ///Prints formatted output to destination
106    fn print(&mut self, args: fmt::Arguments) {
107        let _ = self.inner.write_fmt(args);
108    }
109
110    #[inline]
111    ///Prints formatted output to destination with newline
112    fn println(&mut self, args: fmt::Arguments) {
113        let _ = self.inner.write_fmt(args);
114        let _ = self.inner.write_str("\n");
115    }
116}
117
118unsafe impl Sync for ItmAssumeSync {}
119
120/// Alias for Interrupt free Printer
121pub type InterruptFree = Itm<crate::modes::InterruptFree>;
122/// Alias for Printer without control over interrupts
123pub type InterruptOk = Itm<crate::modes::InterruptOk>;
124/// Alias for Synced Itm.
125pub type InterruptSync = ItmSync<crate::modes::InterruptFree>;