|
47 | 47 | /// function. Refer to crate example usage.
|
48 | 48 | pub use rtic_trace_macros::trace;
|
49 | 49 |
|
50 |
| -// TODO is there an even better way to store this? |
51 |
| -static mut WATCH_VARIABLE: u32 = 0; |
| 50 | +struct WatchVars { |
| 51 | + /// Watch variable to which the just entered software task ID is written to. |
| 52 | + enter: u32, |
| 53 | + |
| 54 | + /// Watch variable to which the just exited software task ID is written to. |
| 55 | + exit: u32, |
| 56 | +} |
| 57 | +static mut WATCH_VARIABLES: WatchVars = WatchVars { enter: 0, exit: 0 }; |
52 | 58 |
|
53 | 59 | /// Auxilliary functions for peripheral configuration. Should be called
|
54 | 60 | /// in the init-function, and preferably in order of (1)
|
@@ -109,29 +115,41 @@ pub mod setup {
|
109 | 115 | /// tracing. The unit is indirectly utilized by [super::trace]. Any
|
110 | 116 | /// changes to the unit after this function yields undefined
|
111 | 117 | /// behavior, in regards to RTIC task tracing.
|
112 |
| - pub fn assign_dwt_unit(dwt: &Core::dwt::Comparator) { |
113 |
| - let watch_address: u32 = unsafe { &super::WATCH_VARIABLE as *const _ } as u32; |
114 |
| - // TODO do we need to clear the MATCHED, bit[24] after every match? |
115 |
| - dwt.configure(ComparatorFunction::Address(ComparatorAddressSettings { |
116 |
| - address: watch_address, |
117 |
| - mask: 0, |
118 |
| - emit: EmitOption::Data, |
119 |
| - access_type: AccessType::WriteOnly, |
120 |
| - })) |
121 |
| - .unwrap(); // NOTE safe: valid (emit, access_type) used |
| 118 | + pub fn assign_dwt_units(enter_dwt: &Core::dwt::Comparator, exit_dwt: &Core::dwt::Comparator) { |
| 119 | + let enter_addr: u32 = unsafe { &super::WATCH_VARIABLES.enter as *const _ } as u32; |
| 120 | + let exit_addr: u32 = unsafe { &super::WATCH_VARIABLES.exit as *const _ } as u32; |
| 121 | + |
| 122 | + for (dwt, addr) in [(enter_dwt, enter_addr), (exit_dwt, exit_addr)] { |
| 123 | + // TODO do we need to clear the MATCHED, bit[24] after every match? |
| 124 | + dwt.configure(ComparatorFunction::Address(ComparatorAddressSettings { |
| 125 | + address: addr, |
| 126 | + mask: 0, |
| 127 | + emit: EmitOption::Data, |
| 128 | + access_type: AccessType::WriteOnly, |
| 129 | + })) |
| 130 | + .unwrap(); // NOTE safe: valid (emit, access_type) used |
| 131 | + } |
122 | 132 | }
|
123 | 133 | }
|
124 | 134 |
|
| 135 | +// TODO only write as much as needed. e.g. for id < 256, only 8 bits |
| 136 | +// must be written. |
| 137 | + |
125 | 138 | /// The function utilized by [trace] to write the unique software task
|
126 | 139 | /// ID to the watch address. You are discouraged to use this function
|
127 | 140 | /// directly; [trace] uses a sequence of task IDs compatible with the
|
128 | 141 | /// `parsing` module. If used directly, task IDs must also be properly
|
129 | 142 | /// configured for the host application.
|
130 | 143 | #[inline]
|
131 |
| -pub fn __write_trace_payload(id: u32) { |
132 |
| - // TODO only write as much as needed. e.g. for id < 256, only 8 bits |
133 |
| - // must be written. |
| 144 | +pub fn __write_enter_id(id: u32) { |
| 145 | + unsafe { |
| 146 | + WATCH_VARIABLES.enter = id; |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +#[inline] |
| 151 | +pub fn __write_exit_id(id: u32) { |
134 | 152 | unsafe {
|
135 |
| - WATCH_VARIABLE = id; |
| 153 | + WATCH_VARIABLES.exit = id; |
136 | 154 | }
|
137 | 155 | }
|
0 commit comments