1 /*******************************************************************************
\r
2 * Tracealyzer v3.0.2 Recorder Library
\r
3 * Percepio AB, www.percepio.com
\r
7 * Functions used by trcKernelHooks.h for storing various kernel events.
\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
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
34 * Tabs are used for indent in this file (1 tab = 4 spaces)
\r
36 * Copyright Percepio AB, 2014.
\r
38 ******************************************************************************/
\r
40 #include "trcKernel.h"
\r
42 #if (USE_TRACEALYZER_RECORDER == 1)
\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
51 #if (INCLUDE_MEMMANG_EVENTS == 1) && (TRACE_SCHEDULING_ONLY == 0)
\r
52 /* Current heap usage. Always updated. */
\r
53 static uint32_t heapMemUsage = 0;
\r
56 #if (TRACE_SCHEDULING_ONLY == 0)
\r
57 static uint32_t prvTraceGetParam(uint32_t, uint32_t);
\r
60 #if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
\r
62 static int readyEventsEnabled = 1;
\r
64 void vTraceSetReadyEventsEnabled(int status)
\r
66 readyEventsEnabled = status;
\r
69 /*******************************************************************************
\r
70 * vTraceStoreTaskReady
\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
80 TRACE_SR_ALLOC_CRITICAL_SECTION();
\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
89 if (! readyEventsEnabled)
\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
97 TRACE_ASSERT(handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );
\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
105 ***********************************************************************/
\r
107 vTraceError("Recorder busy - high priority ISR using syscall? (1)");
\r
111 trcCRITICAL_SECTION_BEGIN();
\r
112 if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
\r
114 if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))
\r
116 dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
\r
117 hnd8 = prvTraceGet8BitHandle(handle);
\r
118 tr = (TREvent*)xTraceNextFreeEventBufferSlot();
\r
121 tr->type = DIV_TASK_READY;
\r
123 tr->objHandle = hnd8;
\r
124 prvTraceUpdateCounters();
\r
128 trcCRITICAL_SECTION_END();
\r
132 /*******************************************************************************
\r
133 * vTraceStoreLowPower
\r
135 * This function stores a low power state.
\r
136 ******************************************************************************/
\r
137 void vTraceStoreLowPower(uint32_t flag)
\r
141 TRACE_SR_ALLOC_CRITICAL_SECTION();
\r
143 TRACE_ASSERT(flag <= 1, "vTraceStoreLowPower: Invalid flag value", );
\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
151 ***********************************************************************/
\r
153 vTraceError("Recorder busy - high priority ISR using syscall? (1)");
\r
157 trcCRITICAL_SECTION_BEGIN();
\r
158 if (RecorderDataPtr->recorderActive)
\r
160 dts = (uint16_t)prvTraceGetDTS(0xFFFF);
\r
161 lp = (LPEvent*)xTraceNextFreeEventBufferSlot();
\r
164 lp->type = LOW_POWER_BEGIN + ( uint8_t ) flag; /* BEGIN or END depending on flag */
\r
166 prvTraceUpdateCounters();
\r
169 trcCRITICAL_SECTION_END();
\r
172 /*******************************************************************************
\r
173 * vTraceStoreMemMangEvent
\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
184 #if (TRACE_SCHEDULING_ONLY == 0)
\r
192 TRACE_SR_ALLOC_CRITICAL_SECTION();
\r
194 if (RecorderDataPtr == NULL) // This happens in vTraceInitTraceData, if using dynamic allocation...
\r
197 if (signed_size < 0)
\r
198 size = (uint32_t)(- signed_size);
\r
200 size = (uint32_t)(signed_size);
\r
202 trcCRITICAL_SECTION_BEGIN();
\r
204 heapMemUsage += signed_size;
\r
206 if (RecorderDataPtr->recorderActive)
\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
211 dts1 = (uint8_t)prvTraceGetDTS(0xFF);
\r
212 size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
\r
213 ms = (MemEventSize *)xTraceNextFreeEventBufferSlot();
\r
218 ms->type = NULL_EVENT; /* Updated when all events are written */
\r
219 ms->size = size_low;
\r
220 prvTraceUpdateCounters();
\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
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
236 ma = (MemEventAddr *) xTraceNextFreeEventBufferSlot();
\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
249 trcCRITICAL_SECTION_END();
\r
250 #endif /* TRACE_SCHEDULING_ONLY */
\r
254 /*******************************************************************************
\r
255 * vTraceStoreKernelCall
\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
262 #if (TRACE_SCHEDULING_ONLY == 0)
\r
266 TRACE_SR_ALLOC_CRITICAL_SECTION();
\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
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
281 vTraceError("Recorder busy - high priority ISR using syscall? (2)");
\r
285 if (handle_of_last_logged_task == 0)
\r
290 trcCRITICAL_SECTION_BEGIN();
\r
291 if (RecorderDataPtr->recorderActive)
\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
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
299 dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
\r
300 hnd8 = prvTraceGet8BitHandle(objectNumber);
\r
301 kse = (KernelCall*) xTraceNextFreeEventBufferSlot();
\r
305 kse->type = (uint8_t)ecode;
\r
306 kse->objHandle = hnd8;
\r
307 prvTraceUpdateCounters();
\r
312 trcCRITICAL_SECTION_END();
\r
313 #endif /* TRACE_SCHEDULING_ONLY */
\r
316 /*******************************************************************************
\r
317 * vTraceStoreKernelCallWithParam
\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
328 #if (TRACE_SCHEDULING_ONLY == 0)
\r
329 KernelCallWithParamAndHandle * kse;
\r
333 TRACE_SR_ALLOC_CRITICAL_SECTION();
\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
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
348 vTraceError("Recorder busy - high priority ISR using syscall? (3)");
\r
352 trcCRITICAL_SECTION_BEGIN();
\r
353 if (RecorderDataPtr->recorderActive && handle_of_last_logged_task && (! inExcludedTask || nISRactive))
\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
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
366 kse->type = (uint8_t)evtcode;
\r
367 kse->objHandle = hnd8;
\r
369 prvTraceUpdateCounters();
\r
373 trcCRITICAL_SECTION_END();
\r
374 #endif /* TRACE_SCHEDULING_ONLY */
\r
377 #if (TRACE_SCHEDULING_ONLY == 0)
\r
379 /*******************************************************************************
\r
382 * Used for storing extra bytes for kernel calls with numeric parameters.
\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
390 TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF,
\r
391 "prvTraceGetParam: Invalid value for param_max", param);
\r
393 if (param <= param_max)
\r
399 xps = (XPSEvent*) xTraceNextFreeEventBufferSlot();
\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
408 return param & param_max;
\r
413 /*******************************************************************************
\r
414 * vTraceStoreKernelCallWithNumericParamOnly
\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
421 #if (TRACE_SCHEDULING_ONLY == 0)
\r
422 KernelCallWithParam16 * kse;
\r
424 uint16_t restParam;
\r
425 TRACE_SR_ALLOC_CRITICAL_SECTION();
\r
429 TRACE_ASSERT(evtcode < 0xFF,
\r
430 "vTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", );
\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
441 vTraceError("Recorder busy - high priority ISR using syscall? (4)");
\r
445 trcCRITICAL_SECTION_BEGIN();
\r
446 if (RecorderDataPtr->recorderActive && handle_of_last_logged_task
\r
447 && (! inExcludedTask || nISRactive))
\r
449 /* Check if the event code is excluded */
\r
450 if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
\r
452 dts6 = (uint8_t)prvTraceGetDTS(0xFF);
\r
453 restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
\r
454 kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();
\r
458 kse->type = (uint8_t)evtcode;
\r
459 kse->param = restParam;
\r
460 prvTraceUpdateCounters();
\r
464 trcCRITICAL_SECTION_END();
\r
465 #endif /* TRACE_SCHEDULING_ONLY */
\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
479 TRACE_SR_ALLOC_CRITICAL_SECTION();
\r
483 TRACE_ASSERT(task_handle <= NTask,
\r
484 "vTraceStoreTaskswitch: Invalid value for task_handle", );
\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
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
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
499 ***************************************************************************/
\r
501 /* Skip the event if the task has been excluded, using vTraceExcludeTask */
\r
502 if (TRACE_GET_TASK_FLAG_ISEXCLUDED(task_handle))
\r
505 inExcludedTask = 1;
\r
509 inExcludedTask = 0;
\r
512 trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();
\r
514 /* Skip the event if the same task is scheduled */
\r
515 if (task_handle == handle_of_last_logged_task)
\r
520 if (!RecorderDataPtr->recorderActive)
\r
525 /* If this event should be logged, log it! */
\r
526 if (skipEvent == 0)
\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
535 if (uiTraceGetObjectState(TRACE_CLASS_TASK,
\r
536 handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE)
\r
538 ts->type = TS_TASK_RESUME;
\r
542 ts->type = TS_TASK_BEGIN;
\r
546 ts->objHandle = hnd8;
\r
548 vTraceSetObjectState(TRACE_CLASS_TASK,
\r
549 handle_of_last_logged_task,
\r
550 TASK_STATE_INSTANCE_ACTIVE);
\r
552 prvTraceUpdateCounters();
\r
556 trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();
\r
559 /*******************************************************************************
\r
560 * vTraceStoreNameCloseEvent
\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
571 ObjCloseNameEvent * ce;
\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
580 if (RecorderDataPtr->recorderActive)
\r
582 uint8_t hnd8 = prvTraceGet8BitHandle(handle);
\r
583 name = TRACE_PROPERTY_NAME_GET(objectclass, handle);
\r
584 idx = prvTraceOpenSymbol(name, 0);
\r
586 // Interrupt disable not necessary, already done in trcHooks.h macro
\r
587 ce = (ObjCloseNameEvent*) xTraceNextFreeEventBufferSlot();
\r
590 ce->type = EVENTGROUP_OBJCLOSE_NAME + objectclass;
\r
591 ce->objHandle = hnd8;
\r
592 ce->symbolIndex = idx;
\r
593 prvTraceUpdateCounters();
\r
598 void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
\r
599 traceObjectClass objectclass)
\r
601 ObjClosePropEvent * pe;
\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
608 if (RecorderDataPtr->recorderActive)
\r
610 // Interrupt disable not necessary, already done in trcHooks.h macro
\r
611 pe = (ObjClosePropEvent*) xTraceNextFreeEventBufferSlot();
\r
614 if (objectclass == TRACE_CLASS_TASK)
\r
616 pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);
\r
620 pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
\r
622 pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;
\r
623 prvTraceUpdateCounters();
\r
629 void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t value)
\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
636 TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
\r
639 uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)
\r
641 TRACE_ASSERT(objectclass < TRACE_NCLASSES,
\r
642 "uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
\r
643 TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
\r
644 "uiTraceGetPriorityProperty: Invalid value for id", 0);
\r
646 return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
\r
649 void vTraceSetObjectState(uint8_t objectclass, objectHandleType id, uint8_t value)
\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
656 TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;
\r
659 uint8_t uiTraceGetObjectState(uint8_t objectclass, objectHandleType id)
\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
666 return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);
\r
669 void vTraceSetTaskInstanceFinished(objectHandleType handle)
\r
671 TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK],
\r
672 "vTraceSetTaskInstanceFinished: Invalid value for handle", );
\r
674 #if (USE_IMPLICIT_IFE_RULES == 1)
\r
675 TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
\r