trcEntryTable.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /*
  2. * 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 of the entry table.
  9. */
  10. #include <trcRecorder.h>
  11. #if (TRC_USE_TRACEALYZER_RECORDER == 1) && (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
  12. #include <string.h>
  13. /* (EntryAddress >= FirstEntryAddress) && (EntryAddress < EntryAddressOutsideArray) */
  14. #define VALIDATE_ENTRY_HANDLE(xEntryHandle) (((void*)(xEntryHandle) >= (void*)&pxEntryTable->axEntries[0]) && ((void*)(xEntryHandle) < (void*)&pxEntryTable->axEntries[TRC_ENTRY_TABLE_SLOTS]))
  15. /*cstat !MISRAC2004-19.4 Suppress macro check*/
  16. #define GIVE_ENTRY_INDEX(xIndex) pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = (xIndex); pxIndexTable->uiFreeIndexCount++
  17. /*cstat !MISRAC2004-19.4 Suppress macro check*/
  18. #define GET_FREE_INDEX_COUNT() pxIndexTable->uiFreeIndexCount
  19. /* Index = (EntryAddress - FirstEntryAddress) / EntrySize */
  20. #define CALCULATE_ENTRY_INDEX(xEntryHandle) (TraceEntryIndex_t)(((TraceUnsignedBaseType_t)(xEntryHandle) - (TraceUnsignedBaseType_t)&pxEntryTable->axEntries[0]) / sizeof(TraceEntry_t))
  21. /* Private function definitions */
  22. static traceResult prvEntryIndexInitialize(void);
  23. static traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex);
  24. /* Variables */
  25. static TraceEntryTable_t *pxEntryTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
  26. static TraceEntryIndexTable_t *pxIndexTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
  27. traceResult xTraceEntryIndexTableInitialize(TraceEntryIndexTable_t* const pxBuffer)
  28. {
  29. /* This should never fail */
  30. TRC_ASSERT(pxBuffer != (void*)0);
  31. pxIndexTable = pxBuffer;
  32. return prvEntryIndexInitialize();
  33. }
  34. traceResult xTraceEntryTableInitialize(TraceEntryTable_t* const pxBuffer)
  35. {
  36. uint32_t i, j;
  37. /* This should never fail */
  38. TRC_ASSERT(pxBuffer != (void*)0);
  39. /* This should never fail */
  40. TRC_ASSERT((TRC_ENTRY_TABLE_SLOTS) != 0);
  41. pxEntryTable = pxBuffer;
  42. pxEntryTable->uxSlots = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_SLOTS);
  43. pxEntryTable->uxEntrySymbolLength = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE);
  44. pxEntryTable->uxEntryStateCount = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT);
  45. for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
  46. {
  47. pxEntryTable->axEntries[i].pvAddress = 0;
  48. for (j = 0u; j < TRC_ENTRY_TABLE_STATE_COUNT; j++)
  49. {
  50. pxEntryTable->axEntries[i].xStates[j] = (TraceUnsignedBaseType_t)0;
  51. }
  52. pxEntryTable->axEntries[i].szSymbol[0] = (char)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
  53. }
  54. xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY);
  55. return TRC_SUCCESS;
  56. }
  57. traceResult xTraceEntryCreate(TraceEntryHandle_t *pxEntryHandle)
  58. {
  59. uint32_t i;
  60. TraceEntryIndex_t xIndex;
  61. TraceEntry_t *pxEntry;
  62. TRACE_ALLOC_CRITICAL_SECTION();
  63. /* We always check this */
  64. if (xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY) == 0U)
  65. {
  66. return TRC_FAIL;
  67. }
  68. /* This should never fail */
  69. TRC_ASSERT(pxEntryHandle != (void*)0);
  70. TRACE_ENTER_CRITICAL_SECTION();
  71. if (prvEntryIndexTake(&xIndex) != TRC_SUCCESS)
  72. {
  73. (void)xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM);
  74. TRACE_EXIT_CRITICAL_SECTION();
  75. return TRC_FAIL;
  76. }
  77. pxEntry = &pxEntryTable->axEntries[xIndex];
  78. pxEntry->pvAddress = (void*)pxEntry; /* We set a temporary address */
  79. for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_STATE_COUNT); i++)
  80. {
  81. pxEntry->xStates[i] = (TraceUnsignedBaseType_t)0;
  82. }
  83. pxEntry->uiOptions = 0u;
  84. pxEntry->szSymbol[0] = (char)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
  85. *pxEntryHandle = (TraceEntryHandle_t)pxEntry;
  86. TRACE_EXIT_CRITICAL_SECTION();
  87. return TRC_SUCCESS;
  88. }
  89. traceResult xTraceEntryDelete(TraceEntryHandle_t xEntryHandle)
  90. {
  91. TraceEntryIndex_t xIndex;
  92. TRACE_ALLOC_CRITICAL_SECTION();
  93. /* This should never fail */
  94. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  95. /* This should never fail */
  96. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  97. /* Calculate the index based on the entry address */
  98. /* Does not need to be locked. */
  99. /* This should never fail */
  100. xIndex = CALCULATE_ENTRY_INDEX(xEntryHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/ /*cstat !MISRAC2004-17.2 !MISRAC2012-Rule-18.2 !MISRAC2012-Rule-18.4 Suppress pointer comparison check*/
  101. TRC_ASSERT((uint32_t)xIndex < (uint32_t)(TRC_ENTRY_TABLE_SLOTS));
  102. TRACE_ENTER_CRITICAL_SECTION();
  103. if (((TraceEntry_t*)xEntryHandle)->pvAddress == 0)
  104. {
  105. /* Someone else has deleted this already? */
  106. TRACE_EXIT_CRITICAL_SECTION();
  107. return TRC_FAIL;
  108. }
  109. /* A valid address, so we assume it is OK. */
  110. /* We clear the address field which is used on host to see if entries are active. */
  111. ((TraceEntry_t*)xEntryHandle)->pvAddress = 0;
  112. /* Give back the index */
  113. GIVE_ENTRY_INDEX(xIndex);
  114. TRACE_EXIT_CRITICAL_SECTION();
  115. return TRC_SUCCESS;
  116. }
  117. traceResult xTraceEntryFind(const void* const pvAddress, TraceEntryHandle_t* pxEntryHandle)
  118. {
  119. uint32_t i;
  120. TraceEntry_t* pxEntry;
  121. /* This should never fail */
  122. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  123. /* This should never fail */
  124. TRC_ASSERT(pxEntryHandle != (void*)0);
  125. /* This should never fail */
  126. TRC_ASSERT(pvAddress != (void*)0);
  127. for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
  128. {
  129. pxEntry = &pxEntryTable->axEntries[i];
  130. if (pxEntry->pvAddress == pvAddress)
  131. {
  132. *pxEntryHandle = (TraceEntryHandle_t)pxEntry;
  133. return TRC_SUCCESS;
  134. }
  135. }
  136. return TRC_FAIL;
  137. }
  138. /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
  139. traceResult xTraceEntrySetSymbol(const TraceEntryHandle_t xEntryHandle, const char* szSymbol, uint32_t uiLength)
  140. {
  141. /* This should never fail */
  142. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  143. if (szSymbol == (void*)0)
  144. {
  145. szSymbol = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
  146. uiLength = 0u; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
  147. }
  148. /* Remember the longest symbol name */
  149. (void)xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH, (int32_t)uiLength);
  150. if (uiLength >= (uint32_t)(TRC_ENTRY_TABLE_SYMBOL_LENGTH))
  151. {
  152. /* No room for null termination. Set to max. */
  153. uiLength = (uint32_t)(TRC_ENTRY_TABLE_SYMBOL_LENGTH); /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
  154. }
  155. else
  156. {
  157. /* Include null termination by increasing the size by 1 */
  158. uiLength = uiLength + 1u; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
  159. }
  160. /* Does not need to be locked. */
  161. /* This should never fail */
  162. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  163. /* This will also copy the null termination, if possible */
  164. memcpy(((TraceEntry_t*)xEntryHandle)->szSymbol, szSymbol, uiLength);
  165. return TRC_SUCCESS;
  166. }
  167. traceResult xTraceEntryGetCount(uint32_t* puiCount)
  168. {
  169. /* This should never fail */
  170. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  171. /* This should never fail */
  172. TRC_ASSERT(puiCount != (void*)0);
  173. *puiCount = (uint32_t)(TRC_ENTRY_TABLE_SLOTS) - GET_FREE_INDEX_COUNT();
  174. return TRC_SUCCESS;
  175. }
  176. traceResult xTraceEntryGetAtIndex(uint32_t index, TraceEntryHandle_t* pxEntryHandle)
  177. {
  178. /* This should never fail */
  179. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  180. /* This should never fail */
  181. TRC_ASSERT(index < (uint32_t)(TRC_ENTRY_TABLE_SLOTS));
  182. /* This should never fail */
  183. TRC_ASSERT(pxEntryHandle != (void*)0);
  184. *pxEntryHandle = (TraceEntryHandle_t)&pxEntryTable->axEntries[index];
  185. return TRC_SUCCESS;
  186. }
  187. #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
  188. traceResult xTraceEntryCreateWithAddress(void* const pvAddress, TraceEntryHandle_t* pxEntryHandle)
  189. {
  190. /* This should never fail */
  191. TRC_ASSERT(pvAddress != (void*)0);
  192. return TRC_ENTRY_CREATE_WITH_ADDRESS(pvAddress, pxEntryHandle);
  193. }
  194. traceResult xTraceEntrySetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t uxState)
  195. {
  196. /* This should never fail */
  197. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  198. /* This should never fail */
  199. TRC_ASSERT(uxStateIndex < (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT));
  200. /* This should never fail */
  201. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  202. return TRC_ENTRY_SET_STATE(xEntryHandle, uxStateIndex, uxState);
  203. }
  204. traceResult xTraceEntrySetOptions(const TraceEntryHandle_t xEntryHandle, uint32_t uiMask)
  205. {
  206. /* This should never fail */
  207. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  208. /* Does not need to be locked. */
  209. /* This should never fail */
  210. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  211. return TRC_ENTRY_SET_OPTIONS(xEntryHandle, uiMask);
  212. }
  213. traceResult xTraceEntryClearOptions(const TraceEntryHandle_t xEntryHandle, uint32_t uiMask)
  214. {
  215. /* This should never fail */
  216. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  217. /* Does not need to be locked. */
  218. /* This should never fail */
  219. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  220. return TRC_ENTRY_CLEAR_OPTIONS(xEntryHandle, uiMask);
  221. }
  222. traceResult xTraceEntryGetAddress(const TraceEntryHandle_t xEntryHandle, void **ppvAddress)
  223. {
  224. /* This should never fail */
  225. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  226. /* This should never fail */
  227. TRC_ASSERT(ppvAddress != (void*)0);
  228. /* Does not need to be locked. */
  229. /* This should never fail */
  230. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  231. return TRC_ENTRY_GET_ADDRESS(xEntryHandle, ppvAddress);
  232. }
  233. void* xTraceEntryGetAddressReturn(const TraceEntryHandle_t xEntryHandle)
  234. {
  235. /* This should never fail */
  236. TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY), return (void*)0);
  237. /* Does not need to be locked. */
  238. /* This should never fail */
  239. TRC_ASSERT_CUSTOM_ON_FAIL(VALIDATE_ENTRY_HANDLE(xEntryHandle), return (void*)0); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  240. return TRC_ENTRY_GET_ADDRESS_RETURN(xEntryHandle);
  241. }
  242. /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
  243. traceResult xTraceEntryGetSymbol(const TraceEntryHandle_t xEntryHandle, const char** pszSymbol)
  244. {
  245. /* This should never fail */
  246. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  247. /* This should never fail */
  248. TRC_ASSERT(pszSymbol != (void*)0);
  249. /* Does not need to be locked. */
  250. /* This should never fail */
  251. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  252. return TRC_ENTRY_GET_SYMBOL(xEntryHandle, pszSymbol);
  253. }
  254. traceResult xTraceEntryGetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t *puxState)
  255. {
  256. /* This should never fail */
  257. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  258. /* This should never fail */
  259. TRC_ASSERT(puxState != (void*)0);
  260. /* This should never fail */
  261. TRC_ASSERT(uxStateIndex < (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT));
  262. /* Does not need to be locked. */
  263. /* This should never fail */
  264. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  265. return TRC_ENTRY_GET_STATE(xEntryHandle, uxStateIndex, puxState);
  266. }
  267. /*cstat !MISRAC2012-Rule-8.13 Suppress const check for xEntryHandle*/
  268. TraceUnsignedBaseType_t xTraceEntryGetStateReturn(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex)
  269. {
  270. return TRC_ENTRY_GET_STATE_RETURN(xEntryHandle, uxStateIndex);
  271. }
  272. traceResult xTraceEntryGetOptions(const TraceEntryHandle_t xEntryHandle, uint32_t *puiOptions)
  273. {
  274. /* This should never fail */
  275. TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
  276. /* This should never fail */
  277. TRC_ASSERT(puiOptions != (void*)0);
  278. /* Does not need to be locked. */
  279. /* This should never fail */
  280. TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
  281. return TRC_ENTRY_GET_OPTIONS(xEntryHandle, puiOptions);
  282. }
  283. #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
  284. /* PRIVATE FUNCTIONS */
  285. static traceResult prvEntryIndexInitialize(void)
  286. {
  287. uint32_t i;
  288. for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
  289. {
  290. pxIndexTable->axFreeIndexes[i] = (TraceEntryIndex_t)i;
  291. }
  292. pxIndexTable->uiFreeIndexCount = TRC_ENTRY_TABLE_SLOTS;
  293. return TRC_SUCCESS;
  294. }
  295. static traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex)
  296. {
  297. /* Critical Section must be active! */
  298. TraceEntryIndex_t xIndex;
  299. if (pxIndexTable->uiFreeIndexCount == 0u)
  300. {
  301. return TRC_FAIL;
  302. }
  303. /* Always take the first item */
  304. xIndex = pxIndexTable->axFreeIndexes[0];
  305. pxIndexTable->uiFreeIndexCount--;
  306. /* Move the last item to the first slot, to avoid holes */
  307. pxIndexTable->axFreeIndexes[0] = pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount];
  308. #if (TRC_ENTRY_TABLE_SLOTS > 256)
  309. pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = UINT16_MAX;
  310. #else
  311. pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = UINT8_MAX;
  312. #endif
  313. *pxIndex = xIndex;
  314. return TRC_SUCCESS;
  315. }
  316. #endif