1 /*******************************************************************************
\r
2 * Trace Recorder Library for Tracealyzer v3.0.2
\r
3 * Percepio AB, www.percepio.com
\r
7 * Public interface and configurations for the trace recorder library.
\r
10 * This software (the "Tracealyzer Recorder Library") is the intellectual
\r
11 * property of Percepio AB and may not be sold or in other ways commercially
\r
12 * redistributed without explicit written permission by Percepio AB.
\r
14 * Separate conditions applies for the SEGGER branded source code included.
\r
16 * The recorder library is free for use together with Percepio products.
\r
17 * You may distribute the recorder library in its original form, but public
\r
18 * distribution of modified versions require approval by Percepio AB.
\r
21 * The trace tool and recorder library is being delivered to you AS IS and
\r
22 * Percepio AB makes no warranty as to its use or performance. Percepio AB does
\r
23 * not and cannot warrant the performance or results you may obtain by using the
\r
24 * software or documentation. Percepio AB make no warranties, express or
\r
25 * implied, as to noninfringement of third party rights, merchantability, or
\r
26 * fitness for any particular purpose. In no event will Percepio AB, its
\r
27 * technology partners, or distributors be liable to you for any consequential,
\r
28 * incidental or special damages, including any lost profits or lost savings,
\r
29 * even if a representative of Percepio AB has been advised of the possibility
\r
30 * of such damages, or for any claim by any third party. Some jurisdictions do
\r
31 * not allow the exclusion or limitation of incidental, consequential or special
\r
32 * damages, or the exclusion of implied warranties or limitations on how long an
\r
33 * implied warranty may last, so the above limitations may not apply to you.
\r
35 * Tabs are used for indent in this file (1 tab = 4 spaces)
\r
37 * Copyright Percepio AB, 2015.
\r
39 ******************************************************************************/
\r
41 #ifndef _TRC_RECORDER_H
\r
42 #define _TRC_RECORDER_H
\r
48 #include "trcConfig.h"
\r
49 #include "trcKernelPort.h"
\r
50 #include "trcHardwarePort.h"
\r
52 #if (USE_TRACEALYZER_RECORDER == 1)
\r
54 /*** User API *****************************************************************/
\r
56 /******************************************************************************
\r
59 * Generates "User Events", with unformatted text.
\r
61 * User Events can be used for very efficient application logging, and are shown
\r
62 * as yellow labels in the main trace view.
\r
64 * You may group User Events into User Event Channels. The yellow User Event
\r
65 * labels shows the logged string, preceeded by the channel name within
\r
66 * brackets. For example:
\r
68 * "[MyChannel] Hello World!"
\r
70 * The User Event Channels are shown in the View Filter, which makes it easy to
\r
71 * select what User Events you wish to display. User Event Channels are created
\r
72 * using vTraceStoreUserEventChannelName().
\r
76 * char* error_uechannel = vTraceStoreUserEventChannelName("Errors");
\r
78 * vTracePrint(error_uechannel, "Shouldn't reach this code!");
\r
80 ******************************************************************************/
\r
81 void vTracePrint(const char* chn, const char* str);
\r
83 /******************************************************************************
\r
86 * Generates "User Events", with formatted text and data, similar to a "printf".
\r
87 * It is very fast since the actual formatting is done on the host side when the
\r
88 * trace is displayed.
\r
90 * User Events can be used for very efficient application logging, and are shown
\r
91 * as yellow labels in the main trace view.
\r
92 * An advantage of User Events is that data can be plotted in the "User Event
\r
93 * Signal Plot" view, visualizing any data you log as User Events, discrete
\r
94 * states or control system signals (e.g. system inputs or outputs).
\r
96 * You may group User Events into User Event Channels. The yellow User Event
\r
97 * labels show the logged string, preceeded by the channel name within brackets.
\r
101 * "[MyChannel] Hello World!"
\r
103 * The User Event Channels are shown in the View Filter, which makes it easy to
\r
104 * select what User Events you wish to display. User Event Channels are created
\r
105 * using vTraceStoreUserEventChannelName().
\r
109 * char* adc_uechannel = vTraceStoreUserEventChannelName("ADC User Events");
\r
111 * vTracePrint(adc_uechannel,
\r
112 * "ADC channel %d: %lf volts",
\r
113 * ch, (double)adc_reading/(double)scale);
\r
115 * All data arguments are assumed to be 32 bt wide. The following formats are
\r
116 * supported in v2.8:
\r
117 * %d - signed integer
\r
118 * %u - unsigned integer
\r
119 * %X - hexadecimal (uppercase)
\r
120 * %x - hexadecimal (lowercase)
\r
121 * %s - string (currently, this must be an earlier stored symbol name)
\r
123 * Up to 15 data arguments are allowed, with a total size of maximum 60 byte
\r
124 * including 8 byte for the base event fields and the format string. So with
\r
125 * one data argument, the maximum string length is 48 chars. If this is exceeded
\r
126 * the string is truncated (4 bytes at a time).
\r
128 ******************************************************************************/
\r
129 void vTracePrintF(const char* chn, const char* fmt, ...);
\r
131 /*******************************************************************************
\r
132 * vTraceStoreUserEventChannelName(const char* name)
\r
134 * Parameter name: the channel name to store (const string literal)
\r
136 * Stores a name for a user event channel, returns the handle (just a pointer
\r
137 * to the provided string). Typically assigned to a "channel" variable that
\r
138 * keeps it for later calls to vTracePrintF();
\r
139 ******************************************************************************/
\r
140 char* vTraceStoreUserEventChannelName(const char* name);
\r
142 /*******************************************************************************
\r
143 * vTraceStoreKernelObjectName(void* object, const char* name)
\r
145 * Parameter object: pointer to the kernel object that shall be named
\r
146 * Parameter name: the name to store (const string literal)
\r
148 * Stores a name for kernel objects (Semaphore, Mailbox, etc.).
\r
149 ******************************************************************************/
\r
150 void vTraceStoreKernelObjectName(void* object, const char* name);
\r
152 /*******************************************************************************
\r
153 * vTraceSetISRProperties(const char* name, char priority)
\r
155 * Parameter name: the name to give the the ISR, also serves as handle.
\r
156 * Parameter priority: the priority level of the ISR.
\r
158 * Stores a name and priority level for an Interrupt Service Routine, to allow
\r
159 * for better visualization. The string address is used as a unique handle.
\r
163 * vTraceSetISRProperties("ISRTimer1", ISRPriorityTimer1);
\r
165 * void ISR_handler()
\r
167 * vTraceStoreISRBegin("ISRTimer1");
\r
169 * vTraceStoreISREnd(0);
\r
171 ******************************************************************************/
\r
172 void vTraceSetISRProperties(const char* name, char priority);
\r
174 /*******************************************************************************
\r
175 * vTraceStoreISRBegin(void* handle);
\r
177 * Parameter handle: ID of the ISR, which is "name" in vTraceSetISRProperties
\r
179 * Registers the beginning of an Interrupt Service Routine (ISR), i.e., or an
\r
180 * exception handler.
\r
184 * vTraceSetISRProperties("ISRTimer1", ISRPriorityTimer1);
\r
186 * void ISR_handler()
\r
188 * vTraceStoreISRBegin("ISRTimer1");
\r
190 * vTraceStoreISREnd(0);
\r
192 ******************************************************************************/
\r
193 void vTraceStoreISRBegin(void* handle);
\r
195 /*******************************************************************************
\r
196 * vTraceStoreISREnd
\r
198 * Registers the end of an Interrupt Service Routine.
\r
200 * This function attempts to automatically detect if a task switch will take
\r
201 * place when interrupt ends. If this is possible depends on the kernel port.
\r
204 * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
\r
206 * vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);
\r
208 * void ISR_handler()
\r
210 * vTraceStoreISRBegin("ISRTimer1");
\r
212 * vTraceStoreISREnd();
\r
215 ******************************************************************************/
\r
216 void vTraceStoreISREnd(void);
\r
218 /*******************************************************************************
\r
219 * vTraceStoreISREndManual
\r
221 * Registers the end of an Interrupt Service Routine.
\r
223 * The parameter isTaskSwitchRequired indicates if the interrupt has requested a
\r
224 * task-switch (= 1) or if the interrupt returns to the earlier context (= 0)
\r
227 * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
\r
229 * vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);
\r
231 * void ISR_handler()
\r
233 * vTraceStoreISRBegin("ISRTimer1");
\r
235 * vTraceStoreISREndManual(0);
\r
238 ******************************************************************************/
\r
239 void vTraceStoreISREndManual(int isTaskSwitchRequired);
\r
241 /*******************************************************************************
\r
242 * vTraceInstanceFinishNow
\r
244 * Creates an event that ends the current task instance at this very instant.
\r
245 * This makes the viewer to splits the current fragment at this point and begin
\r
246 * a new actor instance, even if no task-switch has occurred.
\r
247 *****************************************************************************/
\r
248 void vTraceInstanceFinishedNow(void);
\r
250 /*******************************************************************************
\r
251 * vTraceInstanceFinishedNext
\r
253 * Marks the current "task instance" as finished on the next kernel call.
\r
255 * If that kernel call is blocking, the instance ends after the blocking event
\r
256 * and the corresponding return event is then the start of the next instance.
\r
257 * If the kernel call is not blocking, the viewer instead splits the current
\r
258 * fragment right before the kernel call, which makes this call the first event
\r
259 * of the next instance.
\r
260 *****************************************************************************/
\r
261 void vTraceInstanceFinishedNext(void);
\r
264 /******************************************************************************/
\r
265 /*** INTERNAL FUNCTIONS *******************************************************/
\r
266 /******************************************************************************/
\r
268 /* Saves a symbol name (task name etc.) in symbol table */
\r
269 void vTraceSaveSymbol(void *address, const char *name);
\r
271 /* Deletes a symbol name (task name etc.) from symbol table */
\r
272 void vTraceDeleteSymbol(void *address);
\r
274 /* Saves an object data entry (task base priority) in object data table */
\r
275 void vTraceSaveObjectData(void *address, uint32_t data);
\r
277 /* Removes an object data entry (task base priority) from object data table */
\r
278 void vTraceDeleteObjectData(void *address);
\r
280 /* Store an event with zero parameters (event ID only) */
\r
281 void vTraceStoreEvent0(uint16_t eventID);
\r
283 /* Store an event with one 32-bit parameter (pointer address or an int) */
\r
284 void vTraceStoreEvent1(uint16_t eventID, uint32_t param1);
\r
286 /* Store an event with two 32-bit parameters */
\r
287 void vTraceStoreEvent2(uint16_t eventID, uint32_t param1, uint32_t param2);
\r
289 /* Store an event with three 32-bit parameters */
\r
290 void vTraceStoreEvent3( uint16_t eventID,
\r
295 /* Stores an event with <nParam> 32-bit integer parameters */
\r
296 void vTraceStoreEvent(int nParam, uint16_t EventID, ...);
\r
298 /* Stories an event with a string and <nParam> 32-bit integer parameters */
\r
299 void vTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...);
\r
301 /* The data structure for commands (a bit overkill) */
\r
304 unsigned char cmdCode;
\r
305 unsigned char param1;
\r
306 unsigned char param2;
\r
307 unsigned char param3;
\r
308 unsigned char param4;
\r
309 unsigned char param5;
\r
310 unsigned char checksumLSB;
\r
311 unsigned char checksumMSB;
\r
312 } TracealyzerCommandType;
\r
314 /* Checks if the provided command is a valid command */
\r
315 int isValidCommand(TracealyzerCommandType* cmd);
\r
317 /* Executed the received command (Start or Stop) */
\r
318 void processCommand(TracealyzerCommandType* cmd);
\r
320 /* Backwards compatibility macros with old recorder */
\r
321 #define vTraceInitTraceData() Trace_Init()
\r
322 #define uiTraceStart() (1)
\r
323 #define vTraceStart()
\r
324 #define vTraceStop()
\r
326 #else /*(USE_TRACEALYZER_RECORDER == 1)*/
\r
328 #define vTraceStoreEvent0(e)
\r
329 #define vTraceStoreEvent1(e, param1)
\r
330 #define vTraceStoreEvent2(e, param1, param2)
\r
331 #define vTraceStoreEvent3(e, param1, param2, param3)
\r
332 #define vTraceStoreUserEventChannelName(x) 0
\r
333 #define vTracePrint(chn, ...)
\r
334 #define vTracePrintF(chn, ...)
\r
335 #define vTraceInstanceFinishedNow()
\r
336 #define vTraceInstanceFinishedNext()
\r
337 #define vTraceStoreISRBegin(x)
\r
338 #define vTraceStoreISREnd()
\r
339 #define vTraceStoreISREndManual(x)
\r
340 #define vTraceSetISRProperties(a, b)
\r
341 #define vTraceStoreKernelObjectName(a, b)
\r
343 /* Backwards compatibility macros with old recorder */
\r
344 #define vTraceInitTraceData()
\r
345 #define uiTraceStart() (1)
\r
346 #define vTraceStart()
\r
347 #define vTraceStop()
\r
349 #endif /*(USE_TRACEALYZER_RECORDER == 1)*/
\r
351 extern void psfError(int errCode);
\r
353 #define PSF_ASSERT(_assert, _err) if (! (_assert)){ psfError(_err); return; }
\r
355 #define PSF_ERROR_NONE 0
\r
356 #define PSF_ERROR_EVENT_CODE_TOO_LARGE 1
\r
357 #define PSF_ERROR_ISR_NESTING_OVERFLOW 2
\r
363 #endif /* _TRC_RECORDER_H */
\r