1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.9.2
3 * Copyright 2023 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for ISR tagging.
9 */
10
11 #include <trcRecorder.h>
12
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1) && (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
14
15 TraceISRData_t* pxTraceISRData TRC_CFG_RECORDER_DATA_ATTRIBUTE;
16
xTraceISRInitialize(TraceISRData_t * pxBuffer)17 traceResult xTraceISRInitialize(TraceISRData_t *pxBuffer)
18 {
19 uint32_t uiCoreIndex;
20 uint32_t uiStackIndex;
21
22 /* This should never fail */
23 TRC_ASSERT(pxBuffer != (void*)0);
24
25 pxTraceISRData = pxBuffer;
26
27 for (uiCoreIndex = 0u; uiCoreIndex < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreIndex++)
28 {
29 TraceISRCoreData_t* pxCoreData = &pxTraceISRData->cores[uiCoreIndex];
30
31 /* Initialize ISR stack */
32 for (uiStackIndex = 0u; uiStackIndex < (uint32_t)(TRC_CFG_MAX_ISR_NESTING); uiStackIndex++)
33 {
34 pxCoreData->handleStack[uiStackIndex] = 0;
35 }
36
37 pxCoreData->stackIndex = -1;
38 pxCoreData->isPendingContextSwitch = 0u;
39 }
40
41 xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ISR);
42
43 return TRC_SUCCESS;
44 }
45
46 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceISRRegister(const char * szName,uint32_t uiPriority,TraceISRHandle_t * pxISRHandle)47 traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t *pxISRHandle)
48 {
49 TraceEntryHandle_t xEntryHandle;
50 uint32_t i, uiLength = 0u;
51
52 /* We need to check this */
53 if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR) == 0U)
54 {
55 return TRC_FAIL;
56 }
57
58 /* This should never fail */
59 TRC_ASSERT(pxISRHandle != (void*)0);
60
61 if (szName == (void*)0)
62 {
63 szName = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
64 }
65
66 /* Always save in symbol table, in case the recording has not yet started */
67 /* We need to check this */
68 if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
69 {
70 return TRC_FAIL;
71 }
72
73 for (i = 0u; (szName[i] != (char)0) && (i < 128u); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
74
75 uiLength = i;
76
77 /* This should never fail */
78 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szName, uiLength) == TRC_SUCCESS);
79
80 /* This should never fail */
81 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, 0u, (TraceUnsignedBaseType_t)uiPriority) == TRC_SUCCESS);
82
83 *pxISRHandle = (TraceISRHandle_t)xEntryHandle;
84
85 return xTraceEventCreateData2(
86 PSF_EVENT_DEFINE_ISR,
87 (TraceUnsignedBaseType_t)xEntryHandle,
88 (TraceUnsignedBaseType_t)uiPriority,
89 (TraceUnsignedBaseType_t*)szName,
90 uiLength + 1
91 );
92 }
93
xTraceISRBegin(TraceISRHandle_t xISRHandle)94 traceResult xTraceISRBegin(TraceISRHandle_t xISRHandle)
95 {
96 TraceISRCoreData_t* pxCoreData;
97 TRACE_ALLOC_CRITICAL_SECTION();
98
99 /* This should never fail */
100 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
101
102 TRACE_ENTER_CRITICAL_SECTION();
103
104 /* We are at the start of a possible ISR chain.
105 * No context switches should have been triggered now.
106 */
107 pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
108
109 if (pxCoreData->stackIndex == -1)
110 {
111 pxCoreData->isPendingContextSwitch = 0u;
112 }
113
114 if (pxCoreData->stackIndex < ((TRC_CFG_MAX_ISR_NESTING) - 1))
115 {
116 pxCoreData->stackIndex++;
117 pxCoreData->handleStack[pxCoreData->stackIndex] = xISRHandle;
118
119 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
120 (void)xTraceEventCreate1(PSF_EVENT_ISR_BEGIN, (TraceUnsignedBaseType_t)xISRHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
121 #endif
122 }
123 else
124 {
125 TRACE_EXIT_CRITICAL_SECTION();
126
127 (void)xTraceError(TRC_ERROR_ISR_NESTING_OVERFLOW);
128
129 return TRC_FAIL;
130 }
131
132 TRACE_EXIT_CRITICAL_SECTION();
133
134 return TRC_SUCCESS;
135 }
136
xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired)137 traceResult xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired)
138 {
139 TraceISRCoreData_t* pxCoreData;
140 TRACE_ALLOC_CRITICAL_SECTION();
141
142 (void)xIsTaskSwitchRequired;
143
144 /* This should never fail */
145 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
146
147 TRACE_ENTER_CRITICAL_SECTION();
148
149 pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
150
151 pxCoreData->stackIndex--;
152
153 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
154 /* Is there a pending task-switch? (perhaps from an earlier ISR) */
155 pxCoreData->isPendingContextSwitch |= (uint32_t)xIsTaskSwitchRequired;
156
157 if (pxCoreData->stackIndex >= 0)
158 {
159 /* Store return to interrupted ISR (if nested ISRs)*/
160 (void)xTraceEventCreate1(PSF_EVENT_ISR_RESUME, (TraceUnsignedBaseType_t)pxCoreData->handleStack[pxCoreData->stackIndex]); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/
161 }
162 else
163 {
164 /* Store return to interrupted task, if no context switch will occur in between. */
165 if ((pxCoreData->isPendingContextSwitch == 0U) || (xTraceKernelPortIsSchedulerSuspended() == 1U)) /*cstat !MISRAC2004-13.7_b For some kernel ports xTraceKernelPortIsSchedulerSuspended() will never return 1, and that is expected*/
166 {
167 (void)xTraceEventCreate1(PSF_EVENT_TASK_ACTIVATE, (TraceUnsignedBaseType_t)xTraceTaskGetCurrentReturn()); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
168 }
169 }
170 #endif
171
172 TRACE_EXIT_CRITICAL_SECTION();
173
174 return TRC_SUCCESS;
175 }
176
177 #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
178
xTraceISRGetCurrentNesting(int32_t * puiValue)179 traceResult xTraceISRGetCurrentNesting(int32_t* puiValue)
180 {
181 /* This should never fail */
182 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
183
184 /* This should never fail */
185 TRC_ASSERT(puiValue != (void*)0);
186
187 TraceISRCoreData_t* pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
188 *puiValue = pxCoreData->stackIndex;
189
190 return TRC_SUCCESS;
191 }
192
xTraceISRGetCurrentNestingReturned(void)193 int32_t xTraceISRGetCurrentNestingReturned(void)
194 {
195 /* This should never fail */
196 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
197
198 return pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()].stackIndex;
199 }
200
xTraceISRGetCurrent(TraceISRHandle_t * pxISRHandle)201 traceResult xTraceISRGetCurrent(TraceISRHandle_t* pxISRHandle)
202 {
203 /* This should never fail */
204 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
205
206 /* This should never fail */
207 TRC_ASSERT(pxISRHandle != (void*)0);
208
209 TraceISRCoreData_t* pxCoreData = &pxTraceISRData->cores[TRC_CFG_GET_CURRENT_CORE()];
210
211 if (pxCoreData->stackIndex < 0)
212 {
213 return TRC_FAIL;
214 }
215
216 *pxISRHandle = pxCoreData->handleStack[pxCoreData->stackIndex];
217
218 return TRC_SUCCESS;
219 }
220
221 #endif
222
223 /* DEPRECATED */
224 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceSetISRProperties(const char * szName,uint32_t uiPriority)225 TraceISRHandle_t xTraceSetISRProperties(const char* szName, uint32_t uiPriority)
226 {
227 TraceISRHandle_t xISRHandle = 0;
228
229 (void)xTraceISRRegister(szName, uiPriority, &xISRHandle);
230
231 return xISRHandle;
232 }
233
234 #endif
235