]> begriffs open source - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernel.c
Update trace recorder to include heap tracing and new v8 features.
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-Trace / trcKernel.c
1 /*******************************************************************************\r
2  * Tracealyzer v2.6.0 Recorder Library\r
3  * Percepio AB, www.percepio.com\r
4  *\r
5  * trcKernel.c\r
6  *\r
7  * Functions used by trcKernelHooks.h.\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  * Copyright Percepio AB, 2013.\r
35  * www.percepio.com\r
36  ******************************************************************************/\r
37 \r
38 #include "trcKernel.h"\r
39 \r
40 #if (USE_TRACEALYZER_RECORDER == 1)\r
41 \r
42 #include <stdint.h>\r
43 \r
44 /* Internal variables */\r
45 uint8_t nISRactive = 0;\r
46 objectHandleType handle_of_last_logged_task = 0;\r
47 uint8_t inExcludedTask = 0;\r
48 \r
49 static uint32_t prvTraceGetParam(uint32_t, uint32_t);\r
50 \r
51 #if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1\r
52 /*******************************************************************************\r
53  * vTraceStoreTaskReady\r
54  *\r
55  * This function stores a ready state for the task handle sent in as parameter.\r
56  ******************************************************************************/\r
57 void vTraceStoreTaskReady(objectHandleType handle)\r
58 {\r
59     uint16_t dts3;\r
60     TREvent* tr;\r
61         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
62         \r
63         TRACE_ASSERT(handle > 0 && handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );\r
64 \r
65     if (recorder_busy)\r
66     {\r
67       /***********************************************************************\r
68       * This should never occur, as the tick- and kernel call ISR is on lowest\r
69       * interrupt priority and always are disabled during the critical sections\r
70       * of the recorder.\r
71       ***********************************************************************/\r
72 \r
73       vTraceError("Recorder busy - high priority ISR using syscall? (1)");\r
74       return;\r
75     }\r
76 \r
77         trcCRITICAL_SECTION_BEGIN();\r
78     if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
79         {\r
80                 if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))\r
81                 {\r
82                         dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
83                         if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
84                         {\r
85                                 uint8_t hnd8 = prvTraceGet8BitHandle(handle);\r
86 \r
87                                 tr = (TREvent*)xTraceNextFreeEventBufferSlot();\r
88 \r
89                                 if (tr != NULL)\r
90                                 {\r
91                                         tr->type = DIV_TASK_READY;\r
92                                         tr->dts = dts3;\r
93                                         tr->objHandle = hnd8;\r
94 \r
95                                         prvTraceUpdateCounters();\r
96                                 }\r
97                         }\r
98                 }\r
99         }\r
100         trcCRITICAL_SECTION_END();\r
101 }\r
102 #endif\r
103 \r
104 /*******************************************************************************\r
105  * vTraceStoreLowPower\r
106  *\r
107  * This function stores a low power state.\r
108  ******************************************************************************/\r
109 void vTraceStoreLowPower(uint32_t flag)\r
110 {\r
111     uint16_t dts;\r
112     LPEvent* lp;\r
113         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
114         \r
115         TRACE_ASSERT(flag <= 1, "vTraceStoreLowPower: Invalid flag value", );\r
116 \r
117     if (recorder_busy)\r
118     {\r
119                 /***********************************************************************\r
120                 * This should never occur, as the tick- and kernel call ISR is on lowest\r
121                 * interrupt priority and always are disabled during the critical sections\r
122                 * of the recorder.\r
123                 ***********************************************************************/\r
124           \r
125                 vTraceError("Recorder busy - high priority ISR using syscall? (1)");\r
126                 return;\r
127     }\r
128         \r
129         trcCRITICAL_SECTION_BEGIN();\r
130     if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
131         {\r
132                 dts = (uint16_t)prvTraceGetDTS(0xFFFF);\r
133                 if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
134                 {\r
135                         lp = (LPEvent*)xTraceNextFreeEventBufferSlot();\r
136                         if (lp != NULL)\r
137                         {\r
138                                 lp->type = LOW_POWER_BEGIN + ( uint8_t ) flag; /* BEGIN or END depending on flag */\r
139                                 lp->dts = dts;\r
140 \r
141                                 prvTraceUpdateCounters();\r
142                         }\r
143                 }\r
144         }\r
145         trcCRITICAL_SECTION_END();\r
146 }\r
147 \r
148 /*******************************************************************************\r
149  * vTraceStoreMemMangEvent\r
150  *\r
151  * This function stores malloc and free events. Each call requires two records,\r
152  * for size and address respectively. The event code parameter (ecode) is applied \r
153  * to the first record (size) and the following address record gets event \r
154  * code "ecode + 1", so make sure this is respected in the event code table.\r
155  ******************************************************************************/\r
156 #if (INCLUDE_MEMMANG_EVENTS == 1)\r
157 void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, uint32_t size)\r
158 {\r
159         uint8_t dts1;\r
160         MemEventSize * ms;\r
161         MemEventAddr * ma;\r
162         uint16_t size_low;\r
163         uint16_t addr_low;\r
164         uint8_t addr_high;\r
165         \r
166         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
167 \r
168         trcCRITICAL_SECTION_BEGIN();\r
169         if (RecorderDataPtr->recorderActive)\r
170         {\r
171                 /* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */\r
172                 if (nISRactive || !inExcludedTask)\r
173                 {\r
174                         dts1 = (uint8_t)prvTraceGetDTS(0xFF);\r
175                         \r
176                         size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);\r
177                         \r
178                         ms = (MemEventSize *)xTraceNextFreeEventBufferSlot();\r
179                         if (ms != NULL)\r
180                         {\r
181                                 ms->dts = dts1;\r
182                                 ms->type = (uint8_t)ecode;\r
183                                 ms->size = size_low;\r
184                                 prvTraceUpdateCounters();\r
185                                 \r
186                                 /* Storing a second record with address (signals "failed" if null) */\r
187                                 #if (HEAP_SIZE_BELOW_16M)\r
188                                         addr_low = address & 0xFFFF;\r
189                                         addr_high = (address >> 16) & 0xFF;\r
190                                 #else\r
191                                         addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);\r
192                                         addr_high = 0;\r
193                                 #endif\r
194                                 \r
195                                 ma = (MemEventAddr *) xTraceNextFreeEventBufferSlot();\r
196                                 \r
197                                 if (ma != NULL)\r
198                                 {\r
199                                         ma->addr_low = addr_low;\r
200                                         ma->addr_high = addr_high;\r
201                                         ma->type = ( ( uint8_t) ecode ) + 1;  /* Note this! */\r
202                                         prvTraceUpdateCounters();                               \r
203                                 }\r
204                         }\r
205                 }\r
206         }\r
207         trcCRITICAL_SECTION_END();      \r
208 }\r
209 #endif\r
210 \r
211 /*******************************************************************************\r
212  * vTraceStoreKernelCall\r
213  *\r
214  * This is the main integration point for storing kernel calls, and\r
215  * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes).\r
216  ******************************************************************************/\r
217 void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)\r
218 {\r
219     KernelCall * kse;\r
220     uint16_t dts1;\r
221     TRACE_SR_ALLOC_CRITICAL_SECTION();\r
222 \r
223     TRACE_ASSERT(ecode < 0xFF, "vTraceStoreKernelCall: ecode >= 0xFF", );\r
224     TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", );\r
225     TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCall: Invalid value for objectNumber", );\r
226 \r
227     if (recorder_busy)\r
228     {\r
229         /*************************************************************************\r
230         * This may occur if a high-priority ISR is illegally using a system call,\r
231         * or creates a user event.\r
232         * Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls\r
233         * or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).\r
234         *************************************************************************/\r
235 \r
236         vTraceError("Recorder busy - high priority ISR using syscall? (2)");\r
237         return;\r
238     }\r
239 \r
240     if (handle_of_last_logged_task == 0)\r
241     {\r
242         return;\r
243     }\r
244 \r
245         trcCRITICAL_SECTION_BEGIN();\r
246     if (RecorderDataPtr->recorderActive)\r
247     {\r
248         /* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */\r
249         if (nISRactive || !inExcludedTask)\r
250         {\r
251             /* Check if the referenced object or the event code is excluded */\r
252             if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))\r
253             {                \r
254                 dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
255 \r
256                 if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
257                 {\r
258                                         uint8_t hnd8 = prvTraceGet8BitHandle(objectNumber);\r
259 \r
260                     kse = (KernelCall*) xTraceNextFreeEventBufferSlot();\r
261                     if (kse != NULL)\r
262                     {\r
263                         kse->dts = dts1;\r
264                         kse->type = (uint8_t)ecode;\r
265                         kse->objHandle = hnd8;\r
266                         prvTraceUpdateCounters();\r
267                     }\r
268                 }                \r
269             }\r
270         }\r
271     }\r
272         trcCRITICAL_SECTION_END();\r
273 }\r
274 \r
275 /*******************************************************************************\r
276  * vTraceStoreKernelCallWithParam\r
277  *\r
278  * Used for storing kernel calls with a handle and a numeric parameter. If the \r
279  * numeric parameter does not fit in one byte, and extra XPS event is inserted\r
280  * before the kernel call event containing the three upper bytes.\r
281  ******************************************************************************/\r
282 void vTraceStoreKernelCallWithParam(uint32_t evtcode,\r
283                                     traceObjectClass objectClass,\r
284                                     uint32_t objectNumber,\r
285                                     uint32_t param)\r
286 {\r
287     KernelCallWithParamAndHandle * kse;\r
288     uint8_t dts2;       \r
289     TRACE_SR_ALLOC_CRITICAL_SECTION();\r
290 \r
291         TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCall: evtcode >= 0xFF", );\r
292         TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", );\r
293         TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCallWithParam: Invalid value for objectNumber", );\r
294 \r
295         if (recorder_busy)\r
296     {\r
297         /*************************************************************************\r
298         * This may occur if a high-priority ISR is illegally using a system call,\r
299         * or creates a user event.\r
300         * Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls\r
301         * or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).\r
302         *************************************************************************/\r
303 \r
304         vTraceError("Recorder busy - high priority ISR using syscall? (3)");\r
305         return;\r
306     }\r
307 \r
308         trcCRITICAL_SECTION_BEGIN();\r
309     if (RecorderDataPtr->recorderActive && handle_of_last_logged_task &&\r
310         (! inExcludedTask || nISRactive))\r
311     {\r
312         \r
313         /* Check if the referenced object or the event code is excluded */\r
314         if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))\r
315         {            \r
316             dts2 = (uint8_t)prvTraceGetDTS(0xFF);\r
317 \r
318             if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
319             {\r
320                                 uint8_t p8 = (uint8_t) prvTraceGetParam(0xFF, param);\r
321                                 \r
322                                 uint8_t hnd8 = prvTraceGet8BitHandle((objectHandleType)objectNumber);\r
323 \r
324                 kse = (KernelCallWithParamAndHandle*) xTraceNextFreeEventBufferSlot();\r
325                 if (kse != NULL)\r
326                 {\r
327                     kse->dts = dts2;\r
328                     kse->type = (uint8_t)evtcode;\r
329                     kse->objHandle = hnd8; \r
330                     kse->param = p8;\r
331                     prvTraceUpdateCounters();\r
332                 }\r
333             }            \r
334         }\r
335     }\r
336         trcCRITICAL_SECTION_END();\r
337 }\r
338 \r
339 /*******************************************************************************\r
340  * prvTraceGetParam\r
341  *\r
342  * Used for storing extra bytes for kernel calls with numeric parameters.\r
343  *\r
344  * May only be called within a critical section!\r
345  ******************************************************************************/\r
346 static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)\r
347 {\r
348         XPSEvent* xps;\r
349         \r
350         TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF, "prvTraceGetParam: Invalid value for param_max", param);\r
351         \r
352         if (param <= param_max)\r
353         {\r
354                 return param;\r
355         }\r
356         else\r
357         {\r
358                 xps = (XPSEvent*) xTraceNextFreeEventBufferSlot();\r
359                 if (xps != NULL)\r
360                 {\r
361                         xps->type = DIV_XPS;\r
362                         xps->xps_8 = (param & (0xFF00 & ~param_max)) >> 8;\r
363                         xps->xps_16 = (param & (0xFFFF0000 & ~param_max)) >> 16;\r
364                         prvTraceUpdateCounters();\r
365                 }\r
366 \r
367                 return param & param_max;\r
368         }\r
369 }\r
370 \r
371 /*******************************************************************************\r
372  * vTraceStoreKernelCallWithNumericParamOnly\r
373  *\r
374  * Used for storing kernel calls with numeric parameters only. This is\r
375  * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment.\r
376  ******************************************************************************/\r
377 void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)\r
378 {\r
379     KernelCallWithParam16 * kse;\r
380     uint8_t dts6;\r
381         uint16_t restParam;\r
382     TRACE_SR_ALLOC_CRITICAL_SECTION();\r
383 \r
384         restParam = 0;\r
385 \r
386         TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", );\r
387         \r
388         if (recorder_busy)\r
389     {\r
390         /*************************************************************************\r
391         * This may occur if a high-priority ISR is illegally using a system call,\r
392         * or creates a user event.\r
393         * Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls\r
394         * or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).\r
395         *************************************************************************/\r
396 \r
397         vTraceError("Recorder busy - high priority ISR using syscall? (4)");\r
398         return;\r
399     }\r
400         \r
401         trcCRITICAL_SECTION_BEGIN();\r
402     if (RecorderDataPtr->recorderActive && handle_of_last_logged_task\r
403         && (! inExcludedTask || nISRactive))\r
404     {\r
405         /* Check if the event code is excluded */\r
406         if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))\r
407         {            \r
408             dts6 = (uint8_t)prvTraceGetDTS(0xFF);\r
409 \r
410             if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
411             {\r
412                                 restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);\r
413 \r
414                                 if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
415                                 {\r
416                                         kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();\r
417                                         if (kse != NULL)\r
418                                         {\r
419                                                 kse->dts = dts6;\r
420                                                 kse->type = (uint8_t)evtcode;\r
421                                                 kse->param = restParam;\r
422                                                 prvTraceUpdateCounters();\r
423                                         }\r
424                                 }\r
425             }            \r
426         }\r
427     }\r
428         trcCRITICAL_SECTION_END();\r
429 }\r
430 \r
431 /*******************************************************************************\r
432  * vTraceStoreTaskswitch\r
433  * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart.\r
434  * At this point interrupts are assumed to be disabled!\r
435  ******************************************************************************/\r
436 void vTraceStoreTaskswitch(objectHandleType task_handle)\r
437 {\r
438     uint16_t dts3;\r
439     TSEvent* ts;\r
440     int8_t skipEvent;\r
441         TRACE_SR_ALLOC_CRITICAL_SECTION();\r
442                 \r
443         skipEvent = 0;\r
444 \r
445         TRACE_ASSERT(task_handle <= NTask, "vTraceStoreTaskswitch: Invalid value for task_handle", );\r
446         \r
447     /***************************************************************************\r
448     This is used to detect if a high-priority ISRs is illegally using the\r
449     recorder ISR trace functions (vTraceStoreISRBegin and ...End) while the\r
450     recorder is busy with a task-level event or lower priority ISR event.\r
451 \r
452     If this is detected, it triggers a call to vTraceError with the error\r
453     "Illegal call to vTraceStoreISRBegin/End". If you get this error, it means\r
454     that the macro trcCRITICAL_SECTION_BEGIN does not disable this ISR, as required.\r
455 \r
456     Note: Setting recorder_busy is normally handled in our macros\r
457     trcCRITICAL_SECTION_BEGIN and _END, but is needed explicitly in this\r
458     function since critical sections should not be used in the context switch\r
459     event...)\r
460     ***************************************************************************/\r
461     \r
462     /* Skip the event if the task has been excluded, using vTraceExcludeTask */\r
463     if (TRACE_GET_TASK_FLAG_ISEXCLUDED(task_handle))\r
464     {\r
465         skipEvent = 1;\r
466         inExcludedTask = 1;\r
467     }\r
468     else\r
469         {\r
470         inExcludedTask = 0;\r
471         }\r
472 \r
473         trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();\r
474 \r
475         /* Skip the event if the same task is scheduled */\r
476         if (task_handle == handle_of_last_logged_task)\r
477         {\r
478                 skipEvent = 1;\r
479         }\r
480         \r
481     if (!RecorderDataPtr->recorderActive)\r
482     {\r
483         skipEvent = 1;\r
484     }\r
485 \r
486     /* If this event should be logged, log it! */\r
487     if (skipEvent == 0)\r
488     {\r
489         dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
490 \r
491         if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
492         {\r
493                         uint8_t hnd8;\r
494             handle_of_last_logged_task = task_handle;\r
495                         hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);\r
496 \r
497             ts = (TSEvent*)xTraceNextFreeEventBufferSlot();\r
498 \r
499             if (ts != NULL)\r
500             {\r
501                 if (uiTraceGetObjectState(TRACE_CLASS_TASK,\r
502                     handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE)\r
503                 {\r
504                     ts->type = TS_TASK_RESUME;\r
505                 }\r
506                 else\r
507                 {\r
508                     ts->type = TS_TASK_BEGIN;\r
509                 }\r
510 \r
511                 ts->dts = dts3;\r
512                 ts->objHandle = hnd8;\r
513 \r
514                 vTraceSetObjectState(TRACE_CLASS_TASK,\r
515                                      handle_of_last_logged_task,\r
516                                      TASK_STATE_INSTANCE_ACTIVE);\r
517 \r
518                 prvTraceUpdateCounters();\r
519             }\r
520         }\r
521     }\r
522 \r
523         trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();\r
524 }\r
525 \r
526 /*******************************************************************************\r
527  * vTraceStoreNameCloseEvent\r
528  *\r
529  * Updates the symbol table with the name of this object from the dynamic\r
530  * objects table and stores a "close" event, holding the mapping between handle\r
531  * and name (a symbol table handle). The stored name-handle mapping is thus the\r
532  * "old" one, valid up until this point.\r
533  ******************************************************************************/\r
534 #if (INCLUDE_OBJECT_DELETE == 1)\r
535 void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,\r
536                                        traceObjectClass objectclass)\r
537 {\r
538     ObjCloseNameEvent * ce;\r
539     const char * name;\r
540     traceLabel idx;\r
541 \r
542         TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", );\r
543         TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceStoreObjectNameOnCloseEvent: Invalid value for handle", );\r
544 \r
545     if (RecorderDataPtr->recorderActive)\r
546         {\r
547                 uint8_t hnd8 = prvTraceGet8BitHandle(handle);\r
548 \r
549                 name = TRACE_PROPERTY_NAME_GET(objectclass, handle);\r
550 \r
551                 idx = prvTraceOpenSymbol(name, 0);\r
552 \r
553                 // Interrupt disable not necessary, already done in trcHooks.h macro\r
554                 ce = (ObjCloseNameEvent*) xTraceNextFreeEventBufferSlot();\r
555                 if (ce != NULL)\r
556                 {\r
557                         ce->type = EVENTGROUP_OBJCLOSE_NAME + objectclass;\r
558                         ce->objHandle = hnd8; \r
559                         ce->symbolIndex = idx;\r
560                         prvTraceUpdateCounters();\r
561                 }\r
562         }\r
563 }\r
564 \r
565 void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,\r
566                                              traceObjectClass objectclass)\r
567 {\r
568     ObjClosePropEvent * pe;\r
569         \r
570     TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", );\r
571     TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", );\r
572 \r
573     if (RecorderDataPtr->recorderActive)\r
574         {\r
575                 // Interrupt disable not necessary, already done in trcHooks.h macro\r
576                 pe = (ObjClosePropEvent*) xTraceNextFreeEventBufferSlot();\r
577                 if (pe != NULL)\r
578                 {\r
579                         if (objectclass == TRACE_CLASS_TASK)\r
580                         {\r
581                                 pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);\r
582                                 pe->arg2 = 0; // Legacy - IFE info removed.\r
583                                 pe->arg3 = 0; // Legacy - IFE info removed.\r
584                         }else{\r
585                                 pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);\r
586                         }\r
587                         pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;\r
588                         prvTraceUpdateCounters();\r
589                 }\r
590         }\r
591 }\r
592 #endif\r
593 \r
594 void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t value)\r
595 {\r
596         TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", );\r
597         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceSetPriorityProperty: Invalid value for id", );\r
598 \r
599     TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;\r
600 }\r
601 \r
602 uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)\r
603 {\r
604         TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);\r
605         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceGetPriorityProperty: Invalid value for id", 0);\r
606 \r
607     return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);\r
608 }\r
609 \r
610 void vTraceSetObjectState(uint8_t objectclass, objectHandleType id, uint8_t value)\r
611 {\r
612         TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceSetObjectState: objectclass >= TRACE_NCLASSES", );\r
613         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceSetObjectState: Invalid value for id", );\r
614         \r
615     TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;\r
616 }\r
617 \r
618 uint8_t uiTraceGetObjectState(uint8_t objectclass, objectHandleType id)\r
619 {\r
620         TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);\r
621         TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceGetObjectState: Invalid value for id", 0);\r
622         \r
623     return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);\r
624 }\r
625 \r
626 void vTraceSetTaskInstanceFinished(objectHandleType handle)\r
627 {\r
628         TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK], "vTraceSetTaskInstanceFinished: Invalid value for handle", );\r
629         \r
630 #if (USE_IMPLICIT_IFE_RULES == 1)\r
631     TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;    \r
632 #endif\r
633 }\r
634 \r
635 #endif