diff options
Diffstat (limited to 'lib/chibios-contrib/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h')
-rw-r--r-- | lib/chibios-contrib/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/lib/chibios-contrib/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h b/lib/chibios-contrib/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h new file mode 100644 index 000000000..43fc8feb3 --- /dev/null +++ b/lib/chibios-contrib/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h | |||
@@ -0,0 +1,286 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. | ||
3 | Copyright (C) 2019 Diego Ismirlian, (dismirlian(at)google's mail) | ||
4 | |||
5 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | you may not use this file except in compliance with the License. | ||
7 | You may obtain a copy of the License at | ||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | Unless required by applicable law or agreed to in writing, software | ||
10 | distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | See the License for the specific language governing permissions and | ||
13 | limitations under the License. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * To use: | ||
18 | * | ||
19 | * 1) | ||
20 | * #include this file at the bottom of chconf.h. You may need to | ||
21 | * redefine some of the hooks in chconf.h, for example | ||
22 | * | ||
23 | * CH_CFG_THREAD_INIT_HOOK => _CH_CFG_THREAD_INIT_HOOK. | ||
24 | * | ||
25 | * If you don't use those hooks in your original code, you may just delete | ||
26 | * them from chconf.h | ||
27 | * | ||
28 | * | ||
29 | * 2) | ||
30 | * Copy the SEGGER_RTT_Conf.h and SEGGER_SYSVIEW_Conf.h files from the | ||
31 | * segger_bindings/example_configurations/ directory to the project's | ||
32 | * cfg directory. | ||
33 | * | ||
34 | * You can tune the config files to suit your needs; see the SEGGER RTT and | ||
35 | * SystemView documentation for details. | ||
36 | * | ||
37 | * | ||
38 | * 3) | ||
39 | * Add the following call to main(): | ||
40 | * SYSVIEW_ChibiOS_Start(STM32_SYSCLK, STM32_SYSCLK, "I#15=SysTick"); | ||
41 | * | ||
42 | * The first parameter, SysFreq, is the time base for all the timestamps. It | ||
43 | * must match SEGGER_SYSVIEW_GET_TIMESTAMP in SEGGER_SYSVIEW_Conf.h. By | ||
44 | * default, SEGGER_SYSVIEW_GET_TIMESTAMP is configured to use the DWT cycle | ||
45 | * counter, so this parameter should match the CPU frequency (eg. | ||
46 | * STM32_SYSCLK). | ||
47 | * | ||
48 | * The second parameter, CPUFreq, appears to be just for information. | ||
49 | * | ||
50 | * The third parameter can be used to name the interrupts in the system. | ||
51 | * For example, on the Cortex-M*, when using the classic periodic tick for | ||
52 | * ChibiOS (CH_CFG_ST_TIMEDELTA == 0), this parameter should include | ||
53 | * "I#15=OSTick" (interrupt #15 is the SysTick). When using the tick-less | ||
54 | * mode, this parameter could be tuned to show the ISR name of the timer | ||
55 | * module used as the OS timer. | ||
56 | * | ||
57 | * Also, you can include all other interrupts in this configuration string | ||
58 | * (eg. "I#15=OSTick,I#54=USART2"). | ||
59 | * | ||
60 | * See the SystemView documentation for more details. | ||
61 | * | ||
62 | * | ||
63 | * 4) | ||
64 | * Copy the file SYSVIEW_ChibiOS.txt (in the segger_bindings directory) to | ||
65 | * the following directory: | ||
66 | * | ||
67 | * Path\to\SystemView\Description\ | ||
68 | * | ||
69 | * This will allow SystemView to map the ChibiOS's task state values to names. | ||
70 | * | ||
71 | */ | ||
72 | |||
73 | #ifndef SYSVIEW_CHIBIOS_H | ||
74 | #define SYSVIEW_CHIBIOS_H | ||
75 | |||
76 | #include "SEGGER_SYSVIEW.h" | ||
77 | void SYSVIEW_ChibiOS_SendTaskInfo(const void *_tp); | ||
78 | void SYSVIEW_ChibiOS_Start(U32 SysFreq, U32 CPUFreq, const char *isr_description); | ||
79 | |||
80 | /********************************************************************/ | ||
81 | /* Checks */ | ||
82 | /********************************************************************/ | ||
83 | #if !(CH_CFG_USE_REGISTRY == TRUE) | ||
84 | #error "SYSVIEW integration requires CH_CFG_USE_REGISTRY" | ||
85 | #endif | ||
86 | |||
87 | #if defined(CH_CFG_THREAD_INIT_HOOK) | ||
88 | #error "SYSVIEW integration: rename CH_CFG_THREAD_INIT_HOOK to _CH_CFG_THREAD_INIT_HOOK" | ||
89 | #endif | ||
90 | |||
91 | #if defined(CH_CFG_THREAD_READY_HOOK) | ||
92 | #error "SYSVIEW integration: rename CH_CFG_THREAD_READY_HOOK to _CH_CFG_THREAD_READY_HOOK" | ||
93 | #endif | ||
94 | |||
95 | #if defined(CH_CFG_CONTEXT_SWITCH_HOOK) | ||
96 | #error "SYSVIEW integration: rename CH_CFG_CONTEXT_SWITCH_HOOK to _CH_CFG_CONTEXT_SWITCH_HOOK" | ||
97 | #endif | ||
98 | |||
99 | #if defined(CH_CFG_THREAD_EXIT_HOOK) | ||
100 | #error "SYSVIEW integration: rename CH_CFG_THREAD_EXIT_HOOK to _CH_CFG_THREAD_EXIT_HOOK" | ||
101 | #endif | ||
102 | |||
103 | #if defined(CH_CFG_IRQ_PROLOGUE_HOOK) | ||
104 | #error "SYSVIEW integration: rename CH_CFG_IRQ_PROLOGUE_HOOK to _CH_CFG_IRQ_PROLOGUE_HOOK" | ||
105 | #endif | ||
106 | |||
107 | #if defined(CH_CFG_IRQ_EPILOGUE_HOOK) | ||
108 | #error "SYSVIEW integration: rename CH_CFG_IRQ_EPILOGUE_HOOK to _CH_CFG_IRQ_EPILOGUE_HOOK" | ||
109 | #endif | ||
110 | |||
111 | #if defined(CH_CFG_SYSTEM_HALT_HOOK) | ||
112 | #error "SYSVIEW integration: rename CH_CFG_SYSTEM_HALT_HOOK to _CH_CFG_SYSTEM_HALT_HOOK" | ||
113 | #endif | ||
114 | |||
115 | #if !defined(_CH_CFG_THREAD_INIT_HOOK) | ||
116 | #define _CH_CFG_THREAD_INIT_HOOK(tp) do {} while(0) | ||
117 | #endif | ||
118 | |||
119 | #if !defined(_CH_CFG_THREAD_READY_HOOK) | ||
120 | #define _CH_CFG_THREAD_READY_HOOK(tp) do {} while(0) | ||
121 | #endif | ||
122 | |||
123 | #if !defined(_CH_CFG_CONTEXT_SWITCH_HOOK) | ||
124 | #define _CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) do {} while(0) | ||
125 | #endif | ||
126 | |||
127 | #if !defined(_CH_CFG_THREAD_EXIT_HOOK) | ||
128 | #define _CH_CFG_THREAD_EXIT_HOOK(tp) do {} while(0) | ||
129 | #endif | ||
130 | |||
131 | #if !defined(_CH_CFG_IRQ_PROLOGUE_HOOK) | ||
132 | #define _CH_CFG_IRQ_PROLOGUE_HOOK() do {} while(0) | ||
133 | #endif | ||
134 | |||
135 | #if !defined(_CH_CFG_IRQ_EPILOGUE_HOOK) | ||
136 | #define _CH_CFG_IRQ_EPILOGUE_HOOK() do {} while(0) | ||
137 | #endif | ||
138 | |||
139 | #if !defined(_CH_CFG_SYSTEM_HALT_HOOK) | ||
140 | #define _CH_CFG_SYSTEM_HALT_HOOK(reason) do {} while(0) | ||
141 | #endif | ||
142 | |||
143 | /* CH_CFG_THREAD_INIT_HOOK: | ||
144 | * | ||
145 | * We report the thread creation and we immediately send the TaskInfo | ||
146 | * structure, so that SystemView can show it as early as possible. | ||
147 | */ | ||
148 | #define CH_CFG_THREAD_INIT_HOOK(tp) { \ | ||
149 | _CH_CFG_THREAD_INIT_HOOK(tp); \ | ||
150 | SEGGER_SYSVIEW_OnTaskCreate((U32)tp); \ | ||
151 | SYSVIEW_ChibiOS_SendTaskInfo((const void *)tp); \ | ||
152 | } | ||
153 | |||
154 | /* CH_CFG_THREAD_READY_HOOK: | ||
155 | * | ||
156 | * This is an *extra* hook, not present in the "stock" ChibiOS code. It is | ||
157 | * important if you want SystemView to show all the ready threads, even if | ||
158 | * they are not executing. | ||
159 | * | ||
160 | * The hook should be placed just before the return lines of the chSchReadyI | ||
161 | * and the chSchReadyAheadI functions, in chschd.c: | ||
162 | * | ||
163 | * thread_t *chSchReadyAheadI(thread_t *tp) { | ||
164 | * ... | ||
165 | * CH_CFG_THREAD_READY_HOOK(tp); | ||
166 | * return tp; | ||
167 | * } | ||
168 | * | ||
169 | * thread_t *chSchReadyI(thread_t *tp) { | ||
170 | * ... | ||
171 | * CH_CFG_THREAD_READY_HOOK(tp); | ||
172 | * return tp; | ||
173 | * } | ||
174 | */ | ||
175 | #define CH_CFG_THREAD_READY_HOOK(tp) { \ | ||
176 | _CH_CFG_THREAD_READY_HOOK(tp); \ | ||
177 | SEGGER_SYSVIEW_OnTaskStartReady((U32)tp); \ | ||
178 | } | ||
179 | |||
180 | /* CH_CFG_CONTEXT_SWITCH_HOOK: | ||
181 | * | ||
182 | * This hook is called when switching context from Thread to Thread, or by the | ||
183 | * tail ISR exit sequence (see comments at CH_CFG_IRQ_EPILOGUE_HOOK). | ||
184 | * | ||
185 | * First, we report the switching-out of the "old" thread (otp), and then the | ||
186 | * switching-in of the "new" thread. Unfortunately, SystemView treats the idle | ||
187 | * thread as a special case, so we need to do some ugly handling here. | ||
188 | */ | ||
189 | #define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ | ||
190 | if (otp->hdr.pqueue.prio != IDLEPRIO) { \ | ||
191 | SEGGER_SYSVIEW_OnTaskStopReady((U32)otp, otp->state); \ | ||
192 | } \ | ||
193 | if (ntp->hdr.pqueue.prio == IDLEPRIO) { \ | ||
194 | SEGGER_SYSVIEW_OnIdle(); \ | ||
195 | } else { \ | ||
196 | SEGGER_SYSVIEW_OnTaskStartExec((U32)ntp); \ | ||
197 | } \ | ||
198 | _CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp); \ | ||
199 | } | ||
200 | |||
201 | #define CH_CFG_THREAD_EXIT_HOOK(tp) { \ | ||
202 | _CH_CFG_THREAD_EXIT_HOOK(tp); \ | ||
203 | SEGGER_SYSVIEW_OnTaskStopExec(); \ | ||
204 | } | ||
205 | |||
206 | /* CH_CFG_IRQ_PROLOGUE_HOOK: | ||
207 | * | ||
208 | * For the ARM Cortex-M* architectures, the PORT_IRQ_PROLOGUE doesn't contain | ||
209 | * any code, so the timestamp shown by SystemView for the ISR entry is quite | ||
210 | * accurate. | ||
211 | */ | ||
212 | #define CH_CFG_IRQ_PROLOGUE_HOOK() { \ | ||
213 | _dbg_check_enter_isr(); \ | ||
214 | SEGGER_SYSVIEW_RecordEnterISR(); \ | ||
215 | _CH_CFG_IRQ_PROLOGUE_HOOK(); \ | ||
216 | } | ||
217 | |||
218 | /* CH_CFG_IRQ_EPILOGUE_HOOK: | ||
219 | * | ||
220 | * When the ISR is at the tail, and preemption is required, we tell SystemView | ||
221 | * that we exit the ISR to the scheduler first so that the code between | ||
222 | * CH_CFG_IRQ_EPILOGUE_HOOK and the actual context switch will be shown as | ||
223 | * "scheduler". Otherwise, that time will be shown as belonging to the thread | ||
224 | * that was running before the first ISR. If the ISR is not at the tail, we | ||
225 | * simply tell SystemView that the ISR has been exited. If the ISR is at the | ||
226 | * tail but preemption is not required, we tell Systemview that we exit the ISR | ||
227 | * so that it shows that the last thread resumes execution. | ||
228 | * | ||
229 | * When the ISR is at the tail, and preemption is required, this hook will | ||
230 | * be immediately followed by CH_CFG_CONTEXT_SWITCH_HOOK (see | ||
231 | * _port_switch_from_isr()). | ||
232 | * | ||
233 | * Actually, this hook runs a bit early in the ISR exit sequence, so the | ||
234 | * scheduler time shown by SystemView will be underestimated. The ideal place | ||
235 | * to place these calls would be at _port_irq_epilogue. | ||
236 | * | ||
237 | * Note: Unfortunately, this hook is specific to the Cortex-M architecture | ||
238 | * until ChibiOS gets a generic "_isr_is_tail()" macro/function. | ||
239 | */ | ||
240 | #if defined(__GNUC__) | ||
241 | # if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__)) | ||
242 | # define _isr_is_tail() (_saved_lr != (regarm_t)0xFFFFFFF1U) | ||
243 | # elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)) | ||
244 | # define _isr_is_tail() ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0U) | ||
245 | # else | ||
246 | # error "SYSVIEW integration: unsupported architecture" | ||
247 | # endif | ||
248 | #elif defined(__ICCARM__) | ||
249 | # if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) | ||
250 | # define _isr_is_tail() (_saved_lr != (regarm_t)0xFFFFFFF1U) | ||
251 | # elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) | ||
252 | # define _isr_is_tail() ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0U) | ||
253 | # else | ||
254 | # error "SYSVIEW integration: unsupported architecture" | ||
255 | # endif | ||
256 | #elif defined(__CC_ARM) | ||
257 | # if (defined __TARGET_ARCH_6S_M) | ||
258 | # define _isr_is_tail() (_saved_lr != (regarm_t)0xFFFFFFF1U) | ||
259 | # elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) | ||
260 | # define _isr_is_tail() ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0U) | ||
261 | # else | ||
262 | # error "SYSVIEW integration: unsupported architecture" | ||
263 | # endif | ||
264 | #else | ||
265 | # error "SYSVIEW integration: unsupported compiler" | ||
266 | #endif | ||
267 | |||
268 | #define CH_CFG_IRQ_EPILOGUE_HOOK() { \ | ||
269 | _dbg_check_leave_isr(); \ | ||
270 | _CH_CFG_IRQ_EPILOGUE_HOOK(); \ | ||
271 | port_lock_from_isr(); \ | ||
272 | _dbg_enter_lock(); \ | ||
273 | if (_isr_is_tail() && chSchIsPreemptionRequired()) { \ | ||
274 | SEGGER_SYSVIEW_RecordExitISRToScheduler(); \ | ||
275 | } else { \ | ||
276 | SEGGER_SYSVIEW_RecordExitISR(); \ | ||
277 | } \ | ||
278 | _dbg_leave_lock(); \ | ||
279 | } | ||
280 | |||
281 | #define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ | ||
282 | _CH_CFG_SYSTEM_HALT_HOOK(reason); \ | ||
283 | SEGGER_SYSVIEW_Error(reason); \ | ||
284 | } | ||
285 | |||
286 | #endif | ||