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