ChibiOS  21.6.0
chtrace.c
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3  2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4 
5  This file is part of ChibiOS.
6 
7  ChibiOS is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation version 3 of the License.
10 
11  ChibiOS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /**
21  * @file rt/src/chtrace.c
22  * @brief Tracer code.
23  *
24  * @addtogroup trace
25  * @details System events tracing service.
26  * @{
27  */
28 
29 #include "ch.h"
30 
31 /*===========================================================================*/
32 /* Module local definitions. */
33 /*===========================================================================*/
34 
35 /*===========================================================================*/
36 /* Module exported variables. */
37 /*===========================================================================*/
38 
39 /*===========================================================================*/
40 /* Module local types. */
41 /*===========================================================================*/
42 
43 /*===========================================================================*/
44 /* Module local variables. */
45 /*===========================================================================*/
46 
47 /*===========================================================================*/
48 /* Module local functions. */
49 /*===========================================================================*/
50 
51 #if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__)
52 /**
53  * @brief Writes a time stamp and increases the trace buffer pointer.
54  *
55  * @notapi
56  */
57 NOINLINE static void trace_next(os_instance_t *oip) {
58 
60 #if PORT_SUPPORTS_RT == TRUE
62 #else
63  oip->trace_buffer.ptr->rtstamp = (rtcnt_t)0;
64 #endif
65 
66  /* Trace hook, useful in order to interface debug tools.*/
68 
70  oip->trace_buffer.ptr = &oip->trace_buffer.buffer[0];
71  }
72 }
73 #endif
74 
75 /*===========================================================================*/
76 /* Module exported functions. */
77 /*===========================================================================*/
78 
79 #if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__)
80 /**
81  * @brief Circular trace buffer initialization.
82  * @note Internal use only.
83  *
84  * @param[out] tbp pointer to the @p trace_buffer_t structure
85  *
86  * @notapi
87  */
89  unsigned i;
90 
91  tbp->suspended = (uint16_t)~CH_DBG_TRACE_MASK;
93  tbp->ptr = &tbp->buffer[0];
94  for (i = 0U; i < (unsigned)CH_DBG_TRACE_BUFFER_SIZE; i++) {
95  tbp->buffer[i].type = CH_TRACE_TYPE_UNUSED;
96  }
97 }
98 
99 /**
100  * @brief Inserts in the circular debug trace buffer a ready record.
101  *
102  * @param[in] tp the thread that just become ready
103  * @param[in] msg the thread ready message
104  *
105  * @notapi
106  */
107 void __trace_ready(thread_t *tp, msg_t msg) {
108  os_instance_t *oip = currcore;
109 
110  if ((oip->trace_buffer.suspended & CH_DBG_TRACE_MASK_READY) == 0U) {
111  oip->trace_buffer.ptr->type = CH_TRACE_TYPE_READY;
112  oip->trace_buffer.ptr->state = (uint8_t)tp->state;
113  oip->trace_buffer.ptr->u.rdy.tp = tp;
114  oip->trace_buffer.ptr->u.rdy.msg = msg;
115  trace_next(oip);
116  }
117 }
118 
119 /**
120  * @brief Inserts in the circular debug trace buffer a context switch record.
121  *
122  * @param[in] ntp the thread being switched in
123  * @param[in] otp the thread being switched out
124  *
125  * @notapi
126  */
127 void __trace_switch(thread_t *ntp, thread_t *otp) {
128  os_instance_t *oip = currcore;
129 
130  if ((oip->trace_buffer.suspended & CH_DBG_TRACE_MASK_SWITCH) == 0U) {
131  oip->trace_buffer.ptr->type = CH_TRACE_TYPE_SWITCH;
132  oip->trace_buffer.ptr->state = (uint8_t)otp->state;
133  oip->trace_buffer.ptr->u.sw.ntp = ntp;
134  oip->trace_buffer.ptr->u.sw.wtobjp = otp->u.wtobjp;
135  trace_next(oip);
136  }
137 }
138 
139 /**
140  * @brief Inserts in the circular debug trace buffer an ISR-enter record.
141  *
142  * @param[in] isr name of the isr
143  *
144  * @notapi
145  */
146 void __trace_isr_enter(const char *isr) {
147  os_instance_t *oip = currcore;
148 
149  if ((oip->trace_buffer.suspended & CH_DBG_TRACE_MASK_ISR) == 0U) {
151  oip->trace_buffer.ptr->type = CH_TRACE_TYPE_ISR_ENTER;
152  oip->trace_buffer.ptr->state = 0U;
153  oip->trace_buffer.ptr->u.isr.name = isr;
154  trace_next(oip);
156  }
157 }
158 
159 /**
160  * @brief Inserts in the circular debug trace buffer an ISR-leave record.
161  *
162  * @param[in] isr name of the isr
163  *
164  * @notapi
165  */
166 void __trace_isr_leave(const char *isr) {
167  os_instance_t *oip = currcore;
168 
169  if ((oip->trace_buffer.suspended & CH_DBG_TRACE_MASK_ISR) == 0U) {
171  oip->trace_buffer.ptr->type = CH_TRACE_TYPE_ISR_LEAVE;
172  oip->trace_buffer.ptr->state = 0U;
173  oip->trace_buffer.ptr->u.isr.name = isr;
174  trace_next(oip);
176  }
177 }
178 
179 /**
180  * @brief Inserts in the circular debug trace buffer an halt record.
181  *
182  * @param[in] reason the halt error string
183  *
184  * @notapi
185  */
186 void __trace_halt(const char *reason) {
187  os_instance_t *oip = currcore;
188 
189  if ((oip->trace_buffer.suspended & CH_DBG_TRACE_MASK_HALT) == 0U) {
190  oip->trace_buffer.ptr->type = CH_TRACE_TYPE_HALT;
191  oip->trace_buffer.ptr->state = 0;
192  oip->trace_buffer.ptr->u.halt.reason = reason;
193  trace_next(oip);
194  }
195 }
196 
197 /**
198  * @brief Adds an user trace record to the trace buffer.
199  *
200  * @param[in] up1 user parameter 1
201  * @param[in] up2 user parameter 2
202  *
203  * @iclass
204  */
205 void chTraceWriteI(void *up1, void *up2) {
206  os_instance_t *oip = currcore;
207 
208  chDbgCheckClassI();
209 
210  if ((oip->trace_buffer.suspended & CH_DBG_TRACE_MASK_USER) == 0U) {
211  oip->trace_buffer.ptr->type = CH_TRACE_TYPE_USER;
212  oip->trace_buffer.ptr->state = 0;
213  oip->trace_buffer.ptr->u.user.up1 = up1;
214  oip->trace_buffer.ptr->u.user.up2 = up2;
215  trace_next(oip);
216  }
217 }
218 
219 /**
220  * @brief Adds an user trace record to the trace buffer.
221  *
222  * @param[in] up1 user parameter 1
223  * @param[in] up2 user parameter 2
224  *
225  * @api
226  */
227 void chTraceWrite(void *up1, void *up2) {
228 
229  chSysLock();
230  chTraceWriteI(up1, up2);
231  chSysUnlock();
232 }
233 
234 /**
235  * @brief Suspends one or more trace events.
236  *
237  * @param[in] mask mask of the trace events to be suspended
238  *
239  * @iclass
240  */
241 void chTraceSuspendI(uint16_t mask) {
242 
243  chDbgCheckClassI();
244 
245  currcore->trace_buffer.suspended |= mask;
246 }
247 
248 /**
249  * @brief Suspends one or more trace events.
250  *
251  * @param[in] mask mask of the trace events to be suspended
252  *
253  * @api
254  */
255 void chTraceSuspend(uint16_t mask) {
256 
257  chSysLock();
258  chTraceSuspendI(mask);
259  chSysUnlock();
260 }
261 
262 /**
263  * @brief Resumes one or more trace events.
264  *
265  * @param[in] mask mask of the trace events to be resumed
266  *
267  * @iclass
268  */
269 void chTraceResumeI(uint16_t mask) {
270 
271  chDbgCheckClassI();
272 
273  currcore->trace_buffer.suspended &= ~mask;
274 }
275 
276 /**
277  * @brief Resumes one or more trace events.
278  *
279  * @param[in] mask mask of the trace events to be resumed
280  *
281  * @api
282  */
283 void chTraceResume(uint16_t mask) {
284 
285  chSysLock();
286  chTraceResumeI(mask);
287  chSysUnlock();
288 }
289 #endif /* CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED */
290 
291 /** @} */
chVTGetSystemTimeX
#define chVTGetSystemTimeX()
Current system time.
Definition: nil/include/ch.h:1254
trace_next
static NOINLINE void trace_next(os_instance_t *oip)
Writes a time stamp and increases the trace buffer pointer.
Definition: chtrace.c:57
chTraceResumeI
void chTraceResumeI(uint16_t mask)
Resumes one or more trace events.
Definition: chtrace.c:269
currcore
#define currcore
Access to current core's instance structure.
Definition: chsys.h:90
chTraceWriteI
void chTraceWriteI(void *up1, void *up2)
Adds an user trace record to the trace buffer.
Definition: chtrace.c:205
CH_DBG_TRACE_BUFFER_SIZE
#define CH_DBG_TRACE_BUFFER_SIZE
Trace buffer entries.
Definition: chtrace.h:91
ch_os_instance::trace_buffer
trace_buffer_t trace_buffer
Trace buffer.
Definition: chobjects.h:438
__trace_halt
void __trace_halt(const char *reason)
Inserts in the circular debug trace buffer an halt record.
Definition: chtrace.c:186
ch_os_instance
System instance data structure.
Definition: chobjects.h:394
NOINLINE
#define NOINLINE
Makes functions not inlineable.
Definition: chtypes.h:91
port_unlock_from_isr
static void port_unlock_from_isr(void)
Kernel-unlock action from an interrupt handler.
Definition: chcore.h:377
trace_event_t::sw
struct trace_event_t::@2::@3 sw
Structure representing a context switch.
msg_t
int32_t msg_t
Definition: chearly.h:88
trace_event_t::isr
struct trace_event_t::@2::@5 isr
Structure representing an ISR enter.
chSysGetRealtimeCounterX
#define chSysGetRealtimeCounterX()
Returns the current value of the system real time counter.
Definition: chsys.h:292
trace_buffer_t::size
uint16_t size
Trace buffer size (entries).
Definition: chtrace.h:200
trace_buffer_t::buffer
trace_event_t buffer[CH_DBG_TRACE_BUFFER_SIZE]
Ring buffer.
Definition: chtrace.h:208
trace_event_t::rdy
struct trace_event_t::@2::@4 rdy
Structure representing a thread becoming ready.
trace_event_t::rtstamp
uint32_t rtstamp
Accurate time stamp.
Definition: chtrace.h:122
trace_event_t::time
systime_t time
System time stamp of the switch event.
Definition: chtrace.h:126
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
trace_event_t::type
uint32_t type
Record type.
Definition: chtrace.h:112
CH_CFG_TRACE_HOOK
#define CH_CFG_TRACE_HOOK(tep)
Trace hook.
Definition: rt/templates/chconf.h:798
rtcnt_t
port_rtcnt_t rtcnt_t
Definition: chearly.h:77
chTraceSuspend
void chTraceSuspend(uint16_t mask)
Suspends one or more trace events.
Definition: chtrace.c:255
ch_thread::u
union ch_thread::@1 u
State-specific fields.
trace_buffer_t
Trace buffer header.
Definition: chtrace.h:192
trace_event_t::state
uint32_t state
Switched out thread state.
Definition: chtrace.h:116
ch_thread::wtobjp
void * wtobjp
Pointer to a generic "wait" object.
Definition: chobjects.h:256
trace_event_t::halt
struct trace_event_t::@2::@6 halt
Structure representing an halt.
chTraceResume
void chTraceResume(uint16_t mask)
Resumes one or more trace events.
Definition: chtrace.c:283
port_lock_from_isr
static void port_lock_from_isr(void)
Kernel-lock action from an interrupt handler.
Definition: chcore.h:367
__trace_isr_leave
void __trace_isr_leave(const char *isr)
Inserts in the circular debug trace buffer an ISR-leave record.
Definition: chtrace.c:166
ch_thread::state
tstate_t state
Current thread state.
Definition: chobjects.h:206
__trace_isr_enter
void __trace_isr_enter(const char *isr)
Inserts in the circular debug trace buffer an ISR-enter record.
Definition: chtrace.c:146
__trace_ready
void __trace_ready(thread_t *tp, msg_t msg)
Inserts in the circular debug trace buffer a ready record.
Definition: chtrace.c:107
chTraceWrite
void chTraceWrite(void *up1, void *up2)
Adds an user trace record to the trace buffer.
Definition: chtrace.c:227
trace_event_t::user
struct trace_event_t::@2::@7 user
User trace structure.
trace_buffer_t::suspended
uint16_t suspended
Suspended trace sources mask.
Definition: chtrace.h:196
__trace_object_init
void __trace_object_init(trace_buffer_t *tbp)
Circular trace buffer initialization.
Definition: chtrace.c:88
trace_buffer_t::ptr
trace_event_t * ptr
Pointer to the buffer front.
Definition: chtrace.h:204
__trace_switch
void __trace_switch(thread_t *ntp, thread_t *otp)
Inserts in the circular debug trace buffer a context switch record.
Definition: chtrace.c:127
chSysUnlock
#define chSysUnlock()
Leaves the kernel lock state.
Definition: nil/include/ch.h:1053
chTraceSuspendI
void chTraceSuspendI(uint16_t mask)
Suspends one or more trace events.
Definition: chtrace.c:241
chSysLock
#define chSysLock()
Enters the kernel lock state.
Definition: nil/include/ch.h:1043