/*******************************************************************************\r
- * Tracealyzer v2.7.7 Recorder Library\r
+ * Tracealyzer v3.0.2 Recorder Library\r
* Percepio AB, www.percepio.com\r
*\r
* trcUser.c\r
*\r
* Tabs are used for indent in this file (1 tab = 4 spaces)\r
*\r
- * Copyright Percepio AB, 2012-2015.\r
+ * Copyright Percepio AB, 2014.\r
* www.percepio.com\r
******************************************************************************/\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-\r
#include "trcUser.h"\r
\r
#if (USE_TRACEALYZER_RECORDER == 1)\r
\r
#define MAX_ISR_NESTING 16\r
static uint8_t isrstack[MAX_ISR_NESTING];\r
+int32_t isPendingContextSwitch = 0;\r
\r
/*******************************************************************************\r
* vTraceSetISRProperties\r
return;\r
}\r
trcCRITICAL_SECTION_BEGIN();\r
+ \r
+ if (nISRactive == 0)\r
+ isPendingContextSwitch = 0; /* We are at the start of a possible ISR chain. No context switches should have been triggered now. */\r
+ \r
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)\r
{\r
\r
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid value for handle", );\r
-\r
+ \r
dts4 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
\r
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */\r
{\r
TSEvent* ts;\r
uint16_t dts5;\r
+ uint8_t hnd8 = 0, type = 0;\r
+ \r
TRACE_SR_ALLOC_CRITICAL_SECTION();\r
\r
if (! RecorderDataPtr->recorderActive || ! handle_of_last_logged_task)\r
}\r
\r
trcCRITICAL_SECTION_BEGIN();\r
- if (pendingISR == 0)\r
+ isPendingContextSwitch |= pendingISR; /* Is there a pending context switch right now? */\r
+ nISRactive--;\r
+ if (nISRactive > 0)\r
{\r
- uint8_t hnd8, type;\r
- dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
-\r
- if (nISRactive > 1)\r
- {\r
- /* return to another isr */\r
- type = TS_ISR_RESUME;\r
- hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive]);\r
- }\r
- else\r
- {\r
- /* return to task */\r
- type = TS_TASK_RESUME;\r
- hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);\r
- }\r
+ /* Return to another isr */\r
+ type = TS_ISR_RESUME;\r
+ hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive - 1]); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */\r
+ }\r
+ else if (isPendingContextSwitch == 0)\r
+ {\r
+ /* No context switch has been triggered by any ISR in the chain. Return to task */\r
+ type = TS_TASK_RESUME;\r
+ hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);\r
+ }\r
+ else\r
+ {\r
+ /* Context switch has been triggered by some ISR. We expect a proper context switch event shortly so we do nothing. */\r
+ }\r
\r
+ if (type != 0)\r
+ {\r
+ dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);\r
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();\r
if (ts != NULL)\r
{\r
ptrLastISRExitEvent = (uint8_t*)ts;\r
#endif \r
}\r
- nISRactive--;\r
\r
#if (SELECTED_PORT == PORT_ARM_CortexM)\r
DWTCycleCountAtLastISRExit = REG_DWT_CYCCNT;\r
*\r
* Calling xTraceOpenLabel multiple times will not create duplicate entries, but\r
* it is of course faster to just do it once, and then keep the handle for later\r
- * use. If you don´t have any data arguments, only a text label/string, it is\r
+ * use. If you don�t have any data arguments, only a text label/string, it is\r
* better to use vTraceUserEvent - it is faster.\r
*\r
* Format specifiers supported:\r