]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernel.c
cf624c850b07b89a842cec2676c9f6e96578a50f
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-Trace / trcKernel.c
1 /*******************************************************************************\r
2  * Tracealyzer v2.7.7 Recorder Library\r
3  * Percepio AB, www.percepio.com\r
4  *\r
5  * trcKernel.c\r
6  *\r
7  * Functions used by trcKernelHooks.h for storing various kernel events.\r
8  *\r
9  * Terms of Use\r
10  * This software is copyright Percepio AB. The recorder library is free for\r
11  * use together with Percepio products. You may distribute the recorder library\r
12  * in its original form, including modifications in trcHardwarePort.c/.h\r
13  * given that these modification are clearly marked as your own modifications\r
14  * and documented in the initial comment section of these source files.\r
15  * This software is the intellectual property of Percepio AB and may not be\r
16  * sold or in other ways commercially redistributed without explicit written\r
17  * permission by Percepio AB.\r
18  *\r
19  * Disclaimer\r
20  * The trace tool and recorder library is being delivered to you AS IS and\r
21  * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
22  * not and cannot warrant the performance or results you may obtain by using the\r
23  * software or documentation. Percepio AB make no warranties, express or\r
24  * implied, as to noninfringement of third party rights, merchantability, or\r
25  * fitness for any particular purpose. In no event will Percepio AB, its\r
26  * technology partners, or distributors be liable to you for any consequential,\r
27  * incidental or special damages, including any lost profits or lost savings,\r
28  * even if a representative of Percepio AB has been advised of the possibility\r
29  * of such damages, or for any claim by any third party. Some jurisdictions do\r
30  * not allow the exclusion or limitation of incidental, consequential or special\r
31  * damages, or the exclusion of implied warranties or limitations on how long an\r
32  * implied warranty may last, so the above limitations may not apply to you.\r
33  *\r
34  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
35  *\r
36  * Copyright Percepio AB, 2012-2015.\r
37  * www.percepio.com\r
38  ******************************************************************************/\r
39 \r
40 #include "trcKernel.h"\r
41 \r
42 #if (USE_TRACEALYZER_RECORDER == 1)\r
43 \r
44 #include <stdint.h>\r
45 \r
46 /* Internal variables */\r
47 int8_t nISRactive = 0;\r
48 objectHandleType handle_of_last_logged_task = 0;\r
49 uint8_t inExcludedTask = 0;\r
50 \r
51 #if (INCLUDE_MEMMANG_EVENTS == 1)\r
52 /* Current heap usage. Always updated. */\r
53 static uint32_t heapMemUsage = 0;\r
54 #endif\r
55 \r
56 #if (TRACE_SCHEDULING_ONLY == 0)\r
57 static uint32_t prvTraceGetParam(uint32_t, uint32_t);\r
58 #endif\r
59 \r
60 #if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1\r
61 \r
62 static int readyEventsEnabled = 1;\r
63 \r
64 void vTraceSetReadyEventsEnabled(int status)\r
65 {\r
66         readyEventsEnabled = status;\r
67 }\r
68 \r
69 /*******************************************************************************\r
70  * vTraceStoreTaskReady\r
71  *\r
72  * This function stores a ready state for the task handle sent in as parameter.\r
73  ******************************************************************************/\r
74 void vTraceStoreTaskReady(objectHandleType handle)\r
75 {\r
76         uint16_t dts3;\r
77         TREvent* tr;\r
78         uint8_t hnd8;\r
79 \r
80         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
81 \r
82         if (handle == 0)\r
83         {\r
84                 /*  On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad\r
85                 placement of the trace macro. In that case, the events are ignored. */\r
86                 return;\r
87         }\r
88         \r
89         if (! readyEventsEnabled)\r
90         {\r
91                 /* When creating tasks, ready events are also created. If creating \r
92                 a "hidden" (not traced) task, we must therefore disable recording \r
93                 of ready events to avoid an undesired ready event... */\r
94                 return;\r
95         }\r
96 \r
97         TRACE_ASSERT(handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );\r
98 \r
99         if (recorder_busy)\r
100         {\r
101          /***********************************************************************\r
102          * This should never occur, as the tick- and kernel call ISR is on lowest\r
103          * interrupt priority and always are disabled during the critical sections\r
104          * of the recorder.\r
105          ***********************************************************************/\r
106 \r
107          vTraceError("Recorder busy - high priority ISR using syscall? (1)");\r
108          return;\r
109         }\r
110 \r
111         trcCRITICAL_SECTION_BEGIN();\r
112         if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
113         {\r
114                 if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))\r
115                 {\r
116                         dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
117                         hnd8 = prvTraceGet8BitHandle(handle);\r
118                         tr = (TREvent*)xTraceNextFreeEventBufferSlot();\r
119                         if (tr != NULL)\r
120                         {\r
121                                 tr->type = DIV_TASK_READY;\r
122                                 tr->dts = dts3;\r
123                                 tr->objHandle = hnd8;\r
124                                 prvTraceUpdateCounters();\r
125                         }\r
126                 }\r
127         }\r
128         trcCRITICAL_SECTION_END();\r
129 }\r
130 #endif\r
131 \r
132 /*******************************************************************************\r
133  * vTraceStoreLowPower\r
134  *\r
135  * This function stores a low power state.\r
136  ******************************************************************************/\r
137 void vTraceStoreLowPower(uint32_t flag)\r
138 {\r
139         uint16_t dts;\r
140         LPEvent* lp;\r
141         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
142 \r
143         TRACE_ASSERT(flag <= 1, "vTraceStoreLowPower: Invalid flag value", );\r
144 \r
145         if (recorder_busy)\r
146         {\r
147                 /***********************************************************************\r
148                 * This should never occur, as the tick- and kernel call ISR is on lowest\r
149                 * interrupt priority and always are disabled during the critical sections\r
150                 * of the recorder.\r
151                 ***********************************************************************/\r
152 \r
153                 vTraceError("Recorder busy - high priority ISR using syscall? (1)");\r
154                 return;\r
155         }\r
156 \r
157         trcCRITICAL_SECTION_BEGIN();\r
158         if (RecorderDataPtr->recorderActive)\r
159         {\r
160                 dts = (uint16_t)prvTraceGetDTS(0xFFFF);\r
161                 lp = (LPEvent*)xTraceNextFreeEventBufferSlot();\r
162                 if (lp != NULL)\r
163                 {\r
164                         lp->type = LOW_POWER_BEGIN + ( uint8_t ) flag; /* BEGIN or END depending on flag */\r
165                         lp->dts = dts;\r
166                         prvTraceUpdateCounters();\r
167                 }\r
168         }\r
169         trcCRITICAL_SECTION_END();\r
170 }\r
171 \r
172 /*******************************************************************************\r
173  * vTraceStoreMemMangEvent\r
174  *\r
175  * This function stores malloc and free events. Each call requires two records,\r
176  * for size and address respectively. The event code parameter (ecode) is applied\r
177  * to the first record (size) and the following address record gets event\r
178  * code "ecode + 1", so make sure this is respected in the event code table.\r
179  * Note: On "free" calls, the signed_size parameter should be negative.\r
180  ******************************************************************************/\r
181 #if (INCLUDE_MEMMANG_EVENTS == 1)\r
182 void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size)\r
183 {       \r
184 #if (TRACE_SCHEDULING_ONLY == 0)\r
185         uint8_t dts1;\r
186         MemEventSize * ms;\r
187         MemEventAddr * ma;\r
188         uint16_t size_low;\r
189         uint16_t addr_low;\r
190         uint8_t addr_high;\r
191         uint32_t size;\r
192         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
193 \r
194         if (RecorderDataPtr == NULL) // This happens in vTraceInitTraceData, if using dynamic allocation...\r
195                 return;\r
196         \r
197         if (signed_size < 0)\r
198                 size = (uint32_t)(- signed_size);\r
199         else\r
200                 size = (uint32_t)(signed_size);\r
201 \r
202         trcCRITICAL_SECTION_BEGIN();\r
203         \r
204         heapMemUsage += signed_size;\r
205         \r
206         if (RecorderDataPtr->recorderActive)\r
207         {\r
208                 /* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */\r
209                 if (nISRactive || !inExcludedTask)\r
210                 {\r
211                         dts1 = (uint8_t)prvTraceGetDTS(0xFF);\r
212                         size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);\r
213                         ms = (MemEventSize *)xTraceNextFreeEventBufferSlot();\r
214 \r
215                         if (ms != NULL)\r
216                         {\r
217                                 ms->dts = dts1;\r
218                                 ms->type = NULL_EVENT; /* Updated when all events are written */\r
219                                 ms->size = size_low;\r
220                                 prvTraceUpdateCounters();\r
221 \r
222                                 /* Storing a second record with address (signals "failed" if null) */\r
223                                 #if (HEAP_SIZE_BELOW_16M)\r
224                                     /* If the heap address range is within 16 MB, i.e., the upper 8 bits\r
225                                         of addresses are constant, this optimization avoids storing an extra\r
226                                         event record by ignoring the upper 8 bit of the address */\r
227                                         addr_low = address & 0xFFFF;          \r
228                                         addr_high = (address >> 16) & 0xFF;\r
229                                 #else\r
230                                     /* The whole 32 bit address is stored using a second event record\r
231                                         for the upper 16 bit */\r
232                                         addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);\r
233                                         addr_high = 0;\r
234                                 #endif\r
235 \r
236                                 ma = (MemEventAddr *) xTraceNextFreeEventBufferSlot();\r
237                                 if (ma != NULL)\r
238                                 {\r
239                                         ma->addr_low = addr_low;\r
240                                         ma->addr_high = addr_high;\r
241                                         ma->type = ( ( uint8_t) ecode ) + 1; /* Note this! */\r
242                                         ms->type = (uint8_t)ecode;\r
243                                         prvTraceUpdateCounters();                                       \r
244                                         RecorderDataPtr->heapMemUsage = heapMemUsage;\r
245                                 }\r
246                         }\r
247                 }\r
248         }\r
249         trcCRITICAL_SECTION_END();\r
250 #endif /* TRACE_SCHEDULING_ONLY */\r
251 }\r
252 #endif\r
253 \r
254 /*******************************************************************************\r
255  * vTraceStoreKernelCall\r
256  *\r
257  * This is the main integration point for storing kernel calls, and\r
258  * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes).\r
259  ******************************************************************************/\r
260 void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)\r
261 {\r
262 #if (TRACE_SCHEDULING_ONLY == 0)\r
263         KernelCall * kse;\r
264         uint16_t dts1;\r
265         uint8_t hnd8;\r
266         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
267 \r
268         TRACE_ASSERT(ecode < 0xFF, "vTraceStoreKernelCall: ecode >= 0xFF", );\r
269         TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", );\r
270         TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCall: Invalid value for objectNumber", );\r
271 \r
272         if (recorder_busy)\r
273         {\r
274                 /*************************************************************************\r
275                 * This may occur if a high-priority ISR is illegally using a system call,\r
276                 * or creates a user event.\r
277                 * Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls\r
278                 * or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).\r
279                 *************************************************************************/\r
280 \r
281                 vTraceError("Recorder busy - high priority ISR using syscall? (2)");\r
282                 return;\r
283         }\r
284 \r
285         if (handle_of_last_logged_task == 0)\r
286         {\r
287                 return;\r
288         }\r
289 \r
290         trcCRITICAL_SECTION_BEGIN();\r
291         if (RecorderDataPtr->recorderActive)\r
292         {\r
293                 /* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */\r
294                 if (nISRactive || !inExcludedTask)\r
295                 {\r
296                         /* Check if the referenced object or the event code is excluded */\r
297                         if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))\r
298                         {\r
299                                 dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
300                                 hnd8 = prvTraceGet8BitHandle(objectNumber);\r
301                                 kse = (KernelCall*) xTraceNextFreeEventBufferSlot();\r
302                                 if (kse != NULL)\r
303                                 {\r
304                                         kse->dts = dts1;\r
305                                         kse->type = (uint8_t)ecode;\r
306                                         kse->objHandle = hnd8;\r
307                                         prvTraceUpdateCounters();\r
308                                 }\r
309                         }\r
310                 }\r
311         }\r
312         trcCRITICAL_SECTION_END();\r
313 #endif /* TRACE_SCHEDULING_ONLY */\r
314 }\r
315 \r
316 /*******************************************************************************\r
317  * vTraceStoreKernelCallWithParam\r
318  *\r
319  * Used for storing kernel calls with a handle and a numeric parameter. If the\r
320  * numeric parameter does not fit in one byte, and extra XPS event is inserted\r
321  * before the kernel call event containing the three upper bytes.\r
322  ******************************************************************************/\r
323 void vTraceStoreKernelCallWithParam(uint32_t evtcode,\r
324                                                                         traceObjectClass objectClass,\r
325                                                                         uint32_t objectNumber,\r
326                                                                         uint32_t param)\r
327 {\r
328 #if (TRACE_SCHEDULING_ONLY == 0)\r
329         KernelCallWithParamAndHandle * kse;\r
330         uint8_t dts2;\r
331         uint8_t hnd8;\r
332         uint8_t p8;\r
333         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
334 \r
335         TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCall: evtcode >= 0xFF", );\r
336         TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", );\r
337         TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCallWithParam: Invalid value for objectNumber", );\r
338 \r
339         if (recorder_busy)\r
340         {\r
341                 /*************************************************************************\r
342                 * This may occur if a high-priority ISR is illegally using a system call,\r
343                 * or creates a user event.\r
344                 * Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls\r
345                 * or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).\r
346                 *************************************************************************/\r
347 \r
348                 vTraceError("Recorder busy - high priority ISR using syscall? (3)");\r
349                 return;\r
350         }\r
351 \r
352         trcCRITICAL_SECTION_BEGIN();\r
353         if (RecorderDataPtr->recorderActive && handle_of_last_logged_task && (! inExcludedTask || nISRactive))\r
354         {\r
355                 /* Check if the referenced object or the event code is excluded */\r
356                 if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) &&\r
357                         !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))\r
358                 {\r
359                         dts2 = (uint8_t)prvTraceGetDTS(0xFF);\r
360                         p8 = (uint8_t) prvTraceGetParam(0xFF, param);\r
361                         hnd8 = prvTraceGet8BitHandle((objectHandleType)objectNumber);\r
362                         kse = (KernelCallWithParamAndHandle*) xTraceNextFreeEventBufferSlot();\r
363                         if (kse != NULL)\r
364                         {\r
365                                 kse->dts = dts2;\r
366                                 kse->type = (uint8_t)evtcode;\r
367                                 kse->objHandle = hnd8;\r
368                                 kse->param = p8;\r
369                                 prvTraceUpdateCounters();\r
370                         }\r
371                 }\r
372         }\r
373         trcCRITICAL_SECTION_END();\r
374 #endif /* TRACE_SCHEDULING_ONLY */\r
375 }\r
376 \r
377 #if (TRACE_SCHEDULING_ONLY == 0)\r
378 \r
379 /*******************************************************************************\r
380  * prvTraceGetParam\r
381  *\r
382  * Used for storing extra bytes for kernel calls with numeric parameters.\r
383  *\r
384  * May only be called within a critical section!\r
385  ******************************************************************************/\r
386 static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)\r
387 {\r
388         XPSEvent* xps;\r
389 \r
390         TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF,\r
391                 "prvTraceGetParam: Invalid value for param_max", param);\r
392 \r
393         if (param <= param_max)\r
394         {\r
395                 return param;\r
396         }\r
397         else\r
398         {\r
399                 xps = (XPSEvent*) xTraceNextFreeEventBufferSlot();\r
400                 if (xps != NULL)\r
401                 {\r
402                         xps->type = DIV_XPS;\r
403                         xps->xps_8 = (param & (0xFF00 & ~param_max)) >> 8;\r
404                         xps->xps_16 = (param & (0xFFFF0000 & ~param_max)) >> 16;\r
405                         prvTraceUpdateCounters();\r
406                 }\r
407 \r
408                 return param & param_max;\r
409         }\r
410 }\r
411 #endif\r
412 \r
413 /*******************************************************************************\r
414  * vTraceStoreKernelCallWithNumericParamOnly\r
415  *\r
416  * Used for storing kernel calls with numeric parameters only. This is\r
417  * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment.\r
418  ******************************************************************************/\r
419 void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)\r
420 {\r
421 #if (TRACE_SCHEDULING_ONLY == 0)\r
422         KernelCallWithParam16 * kse;\r
423         uint8_t dts6;\r
424         uint16_t restParam;\r
425         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
426 \r
427         restParam = 0;\r
428 \r
429         TRACE_ASSERT(evtcode < 0xFF,\r
430                 "vTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", );\r
431 \r
432         if (recorder_busy)\r
433         {\r
434                 /*************************************************************************\r
435                 * This may occur if a high-priority ISR is illegally using a system call,\r
436                 * or creates a user event.\r
437                 * Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls\r
438                 * or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).\r
439                 *************************************************************************/\r
440 \r
441                 vTraceError("Recorder busy - high priority ISR using syscall? (4)");\r
442                 return;\r
443         }\r
444 \r
445         trcCRITICAL_SECTION_BEGIN();\r
446         if (RecorderDataPtr->recorderActive && handle_of_last_logged_task\r
447                 && (! inExcludedTask || nISRactive))\r
448         {\r
449                 /* Check if the event code is excluded */\r
450                 if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))\r
451                 {\r
452                         dts6 = (uint8_t)prvTraceGetDTS(0xFF);\r
453                         restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);\r
454                         kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();\r
455                         if (kse != NULL)\r
456                         {\r
457                                 kse->dts = dts6;\r
458                                 kse->type = (uint8_t)evtcode;\r
459                                 kse->param = restParam;\r
460                                 prvTraceUpdateCounters();\r
461                         }\r
462                 }\r
463         }\r
464         trcCRITICAL_SECTION_END();\r
465 #endif /* TRACE_SCHEDULING_ONLY */\r
466 }\r
467 \r
468 /*******************************************************************************\r
469  * vTraceStoreTaskswitch\r
470  * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart.\r
471  * At this point interrupts are assumed to be disabled!\r
472  ******************************************************************************/\r
473 void vTraceStoreTaskswitch(objectHandleType task_handle)\r
474 {\r
475         uint16_t dts3;\r
476         TSEvent* ts;\r
477         int8_t skipEvent;\r
478         uint8_t hnd8;\r
479         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
480 \r
481         skipEvent = 0;\r
482 \r
483         TRACE_ASSERT(task_handle <= NTask,\r
484                 "vTraceStoreTaskswitch: Invalid value for task_handle", );\r
485 \r
486         /***************************************************************************\r
487         This is used to detect if a high-priority ISRs is illegally using the\r
488         recorder ISR trace functions (vTraceStoreISRBegin and ...End) while the\r
489         recorder is busy with a task-level event or lower priority ISR event.\r
490 \r
491         If this is detected, it triggers a call to vTraceError with the error\r
492         "Illegal call to vTraceStoreISRBegin/End". If you get this error, it means\r
493         that the macro trcCRITICAL_SECTION_BEGIN does not disable this ISR, as required.\r
494 \r
495         Note: Setting recorder_busy is normally handled in our macros\r
496         trcCRITICAL_SECTION_BEGIN and _END, but is needed explicitly in this\r
497         function since critical sections should not be used in the context switch\r
498         event...)\r
499         ***************************************************************************/\r
500 \r
501         /* Skip the event if the task has been excluded, using vTraceExcludeTask */\r
502         if (TRACE_GET_TASK_FLAG_ISEXCLUDED(task_handle))\r
503         {\r
504                 skipEvent = 1;\r
505                 inExcludedTask = 1;\r
506         }\r
507         else\r
508         {\r
509                 inExcludedTask = 0;\r
510         }\r
511 \r
512         trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();\r
513 \r
514         /* Skip the event if the same task is scheduled */\r
515         if (task_handle == handle_of_last_logged_task)\r
516         {\r
517                 skipEvent = 1;\r
518         }\r
519 \r
520         if (!RecorderDataPtr->recorderActive)\r
521         {\r
522                 skipEvent = 1;\r
523         }\r
524 \r
525         /* If this event should be logged, log it! */\r
526         if (skipEvent == 0)\r
527         {\r
528                 dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
529                 handle_of_last_logged_task = task_handle;\r
530                 hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);\r
531                 ts = (TSEvent*)xTraceNextFreeEventBufferSlot();\r
532 \r
533                 if (ts != NULL)\r
534                 {\r
535                         if (uiTraceGetObjectState(TRACE_CLASS_TASK,\r
536                                 handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE)\r
537                         {\r
538                                 ts->type = TS_TASK_RESUME;\r
539                         }\r
540                         else\r
541                         {\r
542                                 ts->type = TS_TASK_BEGIN;\r
543                         }\r
544 \r
545                         ts->dts = dts3;\r
546                         ts->objHandle = hnd8;\r
547 \r
548                         vTraceSetObjectState(TRACE_CLASS_TASK,\r
549                                                                         handle_of_last_logged_task,\r
550                                                                         TASK_STATE_INSTANCE_ACTIVE);\r
551 \r
552                         prvTraceUpdateCounters();\r
553                 }\r
554         }\r
555 \r
556         trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();\r
557 }\r
558 \r
559 /*******************************************************************************\r
560  * vTraceStoreNameCloseEvent\r
561  *\r
562  * Updates the symbol table with the name of this object from the dynamic\r
563  * objects table and stores a "close" event, holding the mapping between handle\r
564  * and name (a symbol table handle). The stored name-handle mapping is thus the\r
565  * "old" one, valid up until this point.\r
566  ******************************************************************************/\r
567 #if (INCLUDE_OBJECT_DELETE == 1)\r
568 void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,\r
569                                                                                 traceObjectClass objectclass)\r
570 {\r
571         ObjCloseNameEvent * ce;\r
572         const char * name;\r
573         traceLabel idx;\r
574 \r
575         TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
576                 "vTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", );\r
577         TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
578                 "vTraceStoreObjectNameOnCloseEvent: Invalid value for handle", );\r
579 \r
580         if (RecorderDataPtr->recorderActive)\r
581         {\r
582                 uint8_t hnd8 = prvTraceGet8BitHandle(handle);\r
583                 name = TRACE_PROPERTY_NAME_GET(objectclass, handle);\r
584                 idx = prvTraceOpenSymbol(name, 0);\r
585 \r
586                 // Interrupt disable not necessary, already done in trcHooks.h macro\r
587                 ce = (ObjCloseNameEvent*) xTraceNextFreeEventBufferSlot();\r
588                 if (ce != NULL)\r
589                 {\r
590                         ce->type = EVENTGROUP_OBJCLOSE_NAME + objectclass;\r
591                         ce->objHandle = hnd8;\r
592                         ce->symbolIndex = idx;\r
593                         prvTraceUpdateCounters();\r
594                 }\r
595         }\r
596 }\r
597 \r
598 void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,\r
599                                                                                          traceObjectClass objectclass)\r
600 {\r
601         ObjClosePropEvent * pe;\r
602 \r
603         TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
604                 "vTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", );\r
605         TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
606                 "vTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", );\r
607 \r
608         if (RecorderDataPtr->recorderActive)\r
609         {\r
610                 // Interrupt disable not necessary, already done in trcHooks.h macro\r
611                 pe = (ObjClosePropEvent*) xTraceNextFreeEventBufferSlot();\r
612                 if (pe != NULL)\r
613                 {\r
614                         if (objectclass == TRACE_CLASS_TASK)\r
615                         {\r
616                                 pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);\r
617                         }\r
618                         else\r
619                         {\r
620                                 pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);\r
621                         }\r
622                         pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;\r
623                         prvTraceUpdateCounters();\r
624                 }\r
625         }\r
626 }\r
627 #endif\r
628 \r
629 void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t value)\r
630 {\r
631         TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
632                 "vTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", );\r
633         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
634                 "vTraceSetPriorityProperty: Invalid value for id", );\r
635 \r
636         TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;\r
637 }\r
638 \r
639 uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)\r
640 {\r
641         TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
642                 "uiTraceGetPriorityProperty: Invalid objectclass number (>= TRACE_NCLASSES)", 0);\r
643         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
644                 "uiTraceGetPriorityProperty: Task handle exceeds NTask. You may need to increase this constant in trcConfig.h.", 0);\r
645 \r
646         return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);\r
647 }\r
648 \r
649 void vTraceSetObjectState(uint8_t objectclass, objectHandleType id, uint8_t value)\r
650 {\r
651         TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
652                 "vTraceSetObjectState: objectclass >= TRACE_NCLASSES", );\r
653         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
654                 "vTraceSetObjectState: Invalid value for id", );\r
655 \r
656         TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;\r
657 }\r
658 \r
659 uint8_t uiTraceGetObjectState(uint8_t objectclass, objectHandleType id)\r
660 {\r
661         TRACE_ASSERT(objectclass < TRACE_NCLASSES,\r
662                 "uiTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);\r
663         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],\r
664                 "uiTraceGetObjectState: Invalid value for id", 0);\r
665 \r
666         return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);\r
667 }\r
668 \r
669 void vTraceSetTaskInstanceFinished(objectHandleType handle)\r
670 {\r
671         TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK],\r
672                 "vTraceSetTaskInstanceFinished: Invalid value for handle", );\r
673 \r
674 #if (USE_IMPLICIT_IFE_RULES == 1)\r
675         TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;\r
676 #endif\r
677 }\r
678 \r
679 #endif\r