您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

trice.c 43KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127
  1. //! \file trice.c
  2. //! \author Thomas.Hoehenleitner [at] seerose.net
  3. //! ///////////////////////////////////////////////////////////////////////////
  4. #include "trice.h"
  5. #include "cobs.h"
  6. #include "tcobs.h"
  7. #include "xtea.h"
  8. #if !TRICE_OFF
  9. // check configuration:
  10. #ifndef TRICE_DATA_OFFSET
  11. #error configuration: Check triceDefaultConfig.h or add "#define TRICE_DATA_OFFSET 16" to your triceConfig.h.
  12. #endif
  13. #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_AUXILIARY32 == 1)
  14. #error configuration: Only one bit width for direct output is supported.
  15. #endif
  16. #if (TRICE_DIRECT_AUXILIARY8 == 1) && (TRICE_DIRECT_AUXILIARY32 == 1)
  17. #error configuration: Only one bit width for direct output is supported.
  18. #endif
  19. #if (TRICE_DIRECT_AUXILIARY8 == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
  20. #error configuration: Only one bit width for direct output is supported.
  21. #endif
  22. #if (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1) && (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1)
  23. #error configuration: TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE not implemented: (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1)
  24. #endif
  25. #if (TRICE_DEFERRED_XTEA_ENCRYPT == 1) && (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_TCOBS) && (TRICE_CONFIG_WARNINGS == 1)
  26. #pragma message("configuration: XTEA with TCOBS is possible but not recommended. Encrypted data are more effective framed with COBS.")
  27. #endif
  28. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) && (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS) && (TRICE_CONFIG_WARNINGS == 1)
  29. #pragma message("configuration: XTEA with TCOBS is possible but not recommended. Encrypted data are more effective framed with COBS.")
  30. #endif
  31. #ifndef TRICE_DEFERRED_TRANSFER_MODE
  32. #error configuration: Check triceDefaultConfig.h or add "#define TRICE_DEFERRED_TRANSFER_MODE TRICE_SINGLE_PACK_MODE" to your triceConfig.h.
  33. #endif
  34. #if (TRICE_DEFERRED_TRANSFER_MODE != TRICE_SINGLE_PACK_MODE) && (TRICE_DEFERRED_TRANSFER_MODE != TRICE_MULTI_PACK_MODE)
  35. #error configuration: Check TRICE_DEFERRED_TRANSFER_MODE value.
  36. #endif
  37. #if (TRICE_DEFERRED_TRANSFER_MODE == TRICE_SINGLE_PACK_MODE) && (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DATA_OFFSET < 64) && (TRICE_CONFIG_WARNINGS == 1)
  38. #warning configuration: Because each Trice is encoded separately, several Trices can easy "eat" the TRICE_DATA_OFFSET, so make this value not too small.
  39. #endif
  40. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) && (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE) && (TRICE_CONFIG_WARNINGS == 1)
  41. #warning configuration: The Trice tool needs COBS (or TCOBS) framing for encrypted data.
  42. #endif
  43. #if (TRICE_DEFERRED_XTEA_ENCRYPT == 1) && (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_NONE) && (TRICE_CONFIG_WARNINGS == 1)
  44. #warning configuration: The Trice tool needs COBS (or TCOBS) framing for encrypted data.
  45. #endif
  46. #if (TRICE_DEFERRED_XTEA_ENCRYPT == 0) && (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_NONE) && (TRICE_CONFIG_WARNINGS == 1)
  47. #warning configuration: (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_NONE) is depreciated and not fully tested. Will probably not run error free.
  48. #endif
  49. #if (TRICE_DIRECT_OUTPUT == 0) && (TRICE_DEFERRED_OUTPUT == 0)
  50. #error configuration: need at least one output mode - (TRICE_DIRECT_OUTPUT == 1) and/or (TRICE_DEFERRED_OUTPUT == 0)
  51. #endif
  52. #if (TRICE_DEFERRED_OUTPUT == 0) && (TRICE_BUFFER == TRICE_RING_BUFFER)
  53. #error configuration: (TRICE_BUFFER == TRICE_RING_BUFFER) needs (TRICE_DEFERRED_OUTPUT == 1) or consider (TRICE_BUFFER == TRICE_STACK_BUFFER) or (TRICE_BUFFER == TRICE_STATIC_BUFFER)
  54. #endif
  55. #if (TRICE_DEFERRED_OUTPUT == 0) && (TRICE_BUFFER == TRICE_DOUBLE_BUFFER)
  56. #error configuration: (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) needs (TRICE_DEFERRED_OUTPUT == 1) or consider (TRICE_BUFFER == TRICE_STACK_BUFFER) or (TRICE_BUFFER == TRICE_STATIC_BUFFER)
  57. #endif
  58. #if (TRICE_DEFERRED_OUTPUT == 1) && (TRICE_BUFFER == TRICE_STACK_BUFFER)
  59. #error configuration: (TRICE_BUFFER == TRICE_STACK_BUFFER) needs (TRICE_DEFERRED_OUTPUT == 0)
  60. #endif
  61. #if (TRICE_DEFERRED_OUTPUT == 1) && (TRICE_BUFFER == TRICE_STATIC_BUFFER)
  62. #error configuration: (TRICE_BUFFER == TRICE_STATIC_BUFFER) needs (TRICE_DEFERRED_OUTPUT == 0)
  63. #endif
  64. #if (TRICE_CGO == 1) && (TRICE_CYCLE_COUNTER == 1) && (TRICE_CONFIG_WARNINGS == 1)
  65. #warning configuration: TRICE_CGO == 1 needs TRICE_CYCLE_COUNTER == 0 for successful tests.
  66. #endif
  67. #if (TRICE_DIRECT_OUTPUT == 1) && (TRICE_DIRECT_AUXILIARY8 == 0) && (TRICE_DIRECT_AUXILIARY32 == 0) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 0) && (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 0)
  68. #error configuration: TRICE_DIRECT_OUTPUT == 1 needs specified output channel, for example add "#define TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE 1" to your triceConfig.h
  69. #endif
  70. #if (TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING == 1) && (TRICE_DEFERRED_OUTPUT == 0)
  71. #error configuration: TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING == 1 needs TRICE_DEFERRED_OUTPUT == 1
  72. #endif
  73. #if (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1) && (TRICE_DIRECT_OUTPUT == 0)
  74. #error configuration: TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1 needs TRICE_DIRECT_OUTPUT == 1
  75. #endif
  76. #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
  77. #error configuration: only one RTT output channel is possible
  78. #endif
  79. #if (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
  80. #error configuration: only one RTT output channel is possible
  81. #endif
  82. #if (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1)
  83. #error configuration: only one RTT output channel is possible
  84. #endif
  85. #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_BUFFER_SIZE / 2 < TRICE_BUFFER_SIZE)
  86. #error configuration: TRICE_DEFERRED_BUFFER_SIZE too small
  87. #endif
  88. #if (TRICE_BUFFER == TRICE_RING_BUFFER) && (TRICE_DEFERRED_BUFFER_SIZE < TRICE_DATA_OFFSET + TRICE_SINGLE_MAX_SIZE)
  89. #error configuration: TRICE_DEFERRED_BUFFER_SIZE too small
  90. #endif
  91. #if (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1) && (TRICE_DIRECT_OUTPUT == 0)
  92. #error configuration: TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1 needs TRICE_DIRECT_OUTPUT == 1
  93. #endif
  94. #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_OUTPUT == 0)
  95. #error configuration: TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1 needs TRICE_DIRECT_OUTPUT == 1
  96. #endif
  97. #if defined(SEGGER_RTT) && (TRICE_BUFFER_SIZE > BUFFER_SIZE_UP)
  98. #error configuration: BUFFER_SIZE_UP too small
  99. #endif
  100. #if (TRICE_BUFFER == TRICE_STACK_BUFFER) && (TRICE_DIRECT_OUTPUT == 0)
  101. #error configuration: direct-only mode needs TRICE_DIRECT_OUTPUT == 1
  102. #endif
  103. #if (TRICE_BUFFER == TRICE_STATIC_BUFFER) && (TRICE_DIRECT_OUTPUT == 0)
  104. #error configuration: direct-only mode needs TRICE_DIRECT_OUTPUT == 1
  105. #endif
  106. #if (TRICE_DEFERRED_OUTPUT == 1) && (TRICE_DEFERRED_UARTA == 0) && (TRICE_DEFERRED_UARTB == 0) && (TRICE_DEFERRED_AUXILIARY8 == 0) && (TRICE_DEFERRED_AUXILIARY32 == 0)
  107. #error configuration: TRICE_DEFERRED_OUTPUT == 1 needs TRICE_DFERRED_UARTx or TRICE_DEFERRED_AUXILIARYx
  108. #endif
  109. #if (TRICE_DEFERRED_UARTA == 1) && !defined(TRICE_UARTA)
  110. #error configuration: deferred TRICE_DEFERRED_UARTA == 1 needs a defined TRICE_UARTA.
  111. #endif
  112. #if (TRICE_DEFERRED_UARTB == 1) && !defined(TRICE_UARTA)
  113. #error configuration: deferred TRICE_DEFERRED_UARTB == 1 needs a defined TRICE_UARTB.
  114. #endif
  115. #if TRICE_DATA_OFFSET & 3
  116. #error TRICE_DATA_OFFSET -all size values must be a multiple of 4!
  117. #endif
  118. #if TRICE_DATA_OFFSET < 8 && TRICE_BUFFER == TRICE_RING_BUFFER
  119. #warning TRICE_DATA_OFFSET should usually be at least 8 bytes, when TRICE_BUFFER == TRICE_RING_BUFFER.
  120. #endif
  121. #if TRICE_SINGLE_MAX_SIZE & 3
  122. #error TRICE_SINGLE_MAX_SIZE - all size values must be a multiple of 4!
  123. #endif
  124. #if TRICE_DEFERRED_BUFFER_SIZE & 3
  125. #error TRICE_DEFERRED_BUFFER_SIZE - all size values must be a multiple of 4!
  126. #endif
  127. #if (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1)
  128. #warning configuration: TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING is experimental
  129. #endif
  130. #if (TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING == 1)
  131. #warning configuration: TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING is experimental
  132. #endif
  133. #if (TRICE_DIRECT_AUXILIARY8 == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
  134. #error configuration: (TRICE_DIRECT_AUXILIARY8 == 1) allows (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) but not (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
  135. #endif
  136. // function prototypes:
  137. #if TRICE_DEFERRED_UARTA == 1
  138. void TriceNonBlockingWriteUartA(const void *buf, size_t nByte);
  139. #endif
  140. #if TRICE_DEFERRED_UARTB == 1
  141. void TriceNonBlockingWriteUartB(const void *buf, size_t nByte);
  142. #endif
  143. #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
  144. static void SEGGER_Write_RTT0_NoCheck32(const uint32_t *pData, unsigned NumW);
  145. #endif
  146. // global variables:
  147. //! TriceErrorCount is incremented, when data inside the internal trice buffer are corrupted.
  148. //! That could happen for example, when the buffer wrapped before data are sent (case TRICE_PROTECT==0).
  149. //! The user app should check this diagnostic value.
  150. unsigned TriceErrorCount = 0;
  151. //! triceCommand is the command receive buffer.
  152. char triceCommandBuffer[TRICE_COMMAND_SIZE_MAX + 1]; // with terminating 0
  153. //! triceCommandFlag ist set, when a command was received completely.
  154. int triceCommandFlag = 0; // updated
  155. #if TRICE_CYCLE_COUNTER == 1
  156. //! TriceCycle is increased and transmitted with each trice message, if enabled.
  157. uint8_t TriceCycle = 0xc0;
  158. #endif
  159. #if TRICE_DIAGNOSTICS == 1
  160. //! TriceDataOffsetDepthMax measures the max used offset space.
  161. int TriceDataOffsetDepthMax = 0;
  162. //! TriceSingleMaxWordCount is a diagnostics value usable to optimize buffer space TRICE_BUFFER_SIZE for a single trice message.
  163. unsigned TriceSingleMaxWordCount = 0;
  164. //! TriceDynStringBufTruncateCount couts how often a dynamic buffer was truncated because it was too long.
  165. unsigned TriceDynStringBufTruncateCount = 0;
  166. #if TRICE_PROTECT == 1
  167. #if TRICE_DIRECT_OUTPUT == 1
  168. unsigned TriceDirectOverflowCount = 0;
  169. #endif
  170. #if TRICE_DEFERRED_OUTPUT == 1
  171. unsigned TriceDeferredOverflowCount = 0;
  172. #endif
  173. #endif // #if TRICE_PROTECT == 1
  174. #endif // #if TRICE_DIAGNOSTICS == 1
  175. //! TriceInit needs to run before the first trice macro is executed.
  176. //! Not neseecary for all configurations.
  177. void TriceInit(void)
  178. {
  179. #if defined(SEGGER_RTT) && (TRICE_CGO == 0)
  180. // This is just to force the INIT() call inside SEGGER_RTT.c what allows to use
  181. // SEGGER_RTT_WriteNoLock or SEGGER_Write_RTT0_NoCheck32 instead of SEGGER_RTT_Write.
  182. SEGGER_RTT_Write(0, 0, 0); // lint !e534
  183. #endif
  184. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DEFERRED_XTEA_ENCRYPT == 1)
  185. XTEAInitTable();
  186. #endif
  187. #if TRICE_BUFFER == TRICE_RING_BUFFER && TRICE_RING_BUFFER_OVERFLOW_WATCH == 1
  188. TriceInitRingBufferMargins();
  189. #endif
  190. }
  191. //! triceDataLen returns encoded len.
  192. //! \param p points to nc
  193. //! To avoid alignment issues, the optional payload needs to start at a 32-bit boundary.
  194. //! The provided buffer starts also at a 32-bit boundary.
  195. //! To ensure, the first 16-bit value is ssiiiiiiI we do the following:
  196. //! - v__________________ v___________ v__ (32-bit alignment positions)
  197. //! - *da = 11iiiiiiI TT TT NC ... | ID(n): After writing 11iiiiiiI write the 32-bit TTTT value in 2 16-bit write operations.
  198. //! - *da = 10iiiiiiI 10iiiiiiI TT NC ... | Id(n): Write 10iiiiiiI as doubled value in one 32-bit operation into the trice buffer. The first 16-bit will be removed just before sending to the out channel.
  199. //! - *da = 01iiiiiiI NC ... | id(n): Just write 01iiiiiiI as 16-bit operation.
  200. //! - *da = 00xxxxxxX extended trices are not used yet, unspecified length >= 2
  201. //! - This way, after writing the 16-bit NC value the payload starts always at a 32-bit boundary.
  202. //! - With framing, user 0,1,2,3-byte messages allowed and ignored by the trice tool.
  203. size_t triceDataLen(const uint8_t *p)
  204. {
  205. uint16_t nc = TRICE_TTOHS(*(uint16_t *)p); // lint !e826
  206. size_t n = nc >> 8;
  207. if (n < 128)
  208. {
  209. return n;
  210. }
  211. return nc & 0x7fff;
  212. }
  213. #if TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1
  214. //! triceIDAndLen expects at buf a trice message and returns the ID for routing.
  215. //! \param pBuf is where the trice message starts.
  216. //! \param ppStart return the trice data start address. This is pBuf or 2 bytes later.
  217. //! \param triceID is filled positive ID value on success or negative on error.
  218. //! \retval is the netto trice length (without padding bytes), 0 on error.
  219. static size_t triceIDAndLen(uint32_t *pBuf, uint8_t **ppStart, int *triceID)
  220. {
  221. uint16_t *pTID = (uint16_t *)pBuf; // get TID address
  222. uint16_t TID = TRICE_TTOHS(*pTID); // type and id
  223. *triceID = 0x3FFF & TID;
  224. int triceType = TID >> 14;
  225. size_t len;
  226. uint8_t *pStart = (uint8_t *)pBuf;
  227. switch (triceType)
  228. {
  229. case TRICE_TYPE_S0: // S0 = no stamp
  230. len = 4 + triceDataLen(pStart + 2); // tyId
  231. break;
  232. case TRICE_TYPE_S2: // S2 = 16-bit stamp
  233. pStart += 2; // see Id(n) macro definition
  234. len = 6 + triceDataLen(pStart + 4); // tyId ts16
  235. break;
  236. case TRICE_TYPE_S4: // S4 = 32-bit stamp
  237. len = 8 + triceDataLen(pStart + 6); // tyId ts32
  238. break;
  239. default:
  240. // lint -fallthrugh
  241. case TRICE_TYPE_X0:
  242. TriceErrorCount++;
  243. *triceID = -__LINE__; // extended trices not supported (yet)
  244. return 0;
  245. }
  246. *ppStart = pStart;
  247. return len;
  248. }
  249. #endif // #if TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1
  250. //! TriceEncode expects at buf trice net data with net length len.
  251. //! It fills dst with the next trice data, which are encoded and framed or not, according the selected switches.
  252. //! The areas of dst and buf are allowed to overlap.
  253. //! \param encrypt, when 0, then without encryption, when 1, then with XTEA encryption.
  254. //! \param framing selects if and which framing is used.
  255. //! \param dst is the destination. It must be 32-bit aligned.
  256. //! \param buf is the source. This can be not 32-bit aligned.
  257. //! \param len is the source len.
  258. //! \retval is the encoded len with 0-delimiter byte.
  259. size_t TriceEncode(unsigned encrypt, unsigned framing, uint8_t *dst, const uint8_t *buf, size_t len)
  260. {
  261. #if TRICE_DIAGNOSTICS == 1
  262. int distance = buf - dst;
  263. if (distance < 4)
  264. {
  265. TriceErrorCount++;
  266. }
  267. int TriceDataOffsetDepth = TRICE_DATA_OFFSET - distance;
  268. TriceDataOffsetDepthMax = TriceDataOffsetDepth < TriceDataOffsetDepthMax ? TriceDataOffsetDepthMax : TriceDataOffsetDepth;
  269. #endif
  270. size_t encLen;
  271. const uint8_t *dat = buf;
  272. if (encrypt)
  273. {
  274. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DEFERRED_XTEA_ENCRYPT == 1)
  275. // Only multiple of 8 encryptable, but trice data are 32-bit aligned.
  276. // A 64-bit trice data aligning would waste RAM and costs a bit time during trice generation.
  277. // We need additional 4 bytes after each trice for the XTEA encryption.
  278. // Also, the framing could make the trice message a bit longer.
  279. // Therefore we copy the trice data to a place, we can use.
  280. // The location for XTEAEncrypt must lay on a 32-bit boundary.
  281. #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE)
  282. // special case: The data can be big, are compacted and behind them is space. So we can encrypt them in space
  283. dat = buf; // That is also for the framing afterwards.
  284. size_t len8 = (len + 7) & ~7; // Only multiple of 8 encryptable, so we adjust len.
  285. memset(((uint8_t *)buf) + len, 0, len8 - len); // clear padding space: ATTENTION! OK only for this compiler switch setting.
  286. len = len8;
  287. XTEAEncrypt((uint32_t *)dat, len8 >> 2);
  288. #else // #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE)
  289. // Let space in front for framing, free 4 bytes behind do a 32-bit align backwards.
  290. // uint32_t * loc = (uint32_t *)(((unsigned)dst + TRICE_DATA_OFFSET - 4) & ~3);
  291. // The computing above does not work, because, when several Trices, this "free" location
  292. // drifts into the unprocessed Trice data. So we create a buffer.
  293. // Not on the stack, because small stacks could be a problem here.
  294. static uint32_t loc[TRICE_SINGLE_MAX_SIZE >> 2];
  295. // Because dst + TRICE_DATA_OFFSET could be the buf value itself, we need to move at least 4 bytes.
  296. memmove(loc, buf, len); // We use not memcpy here, because dst and buf allowed to overlap.
  297. dat = (const uint8_t *)loc; // That is also for the framing afterwards.
  298. size_t len8 = (len + 7) & ~7; // Only multiple of 8 encryptable, so we adjust len.
  299. memset(((uint8_t *)loc) + len, 0, len8 - len); // clear padding space
  300. len = len8;
  301. XTEAEncrypt(loc, len8 >> 2);
  302. #endif // #else // #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE)
  303. #endif // #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DEFERRED_XTEA_ENCRYPT == 1)
  304. }
  305. switch (framing)
  306. {
  307. case TRICE_FRAMING_TCOBS:
  308. encLen = (size_t)TCOBSEncode(dst, dat, len);
  309. dst[encLen++] = 0; // Add zero as package delimiter.
  310. return encLen;
  311. case TRICE_FRAMING_COBS:
  312. encLen = (size_t)COBSEncode(dst, dat, len);
  313. dst[encLen++] = 0; // Add zero as package delimiter.
  314. return encLen;
  315. case TRICE_FRAMING_NONE:
  316. memmove(dst, dat, len);
  317. encLen = len;
  318. return encLen;
  319. }
  320. return 0; // unexpected
  321. }
  322. #if (TRICE_DIAGNOSTICS == 1) && defined(SEGGER_RTT)
  323. unsigned RTT0_writeDepthMax = 0; //! < RTT0_writeDepthMax is usable for diagnostics.
  324. static void triceSeggerRTTDiagnostics(void)
  325. {
  326. unsigned space;
  327. #if TRICE_CGO == 1 // automated tests
  328. space = TRICE_BUFFER_SIZE;
  329. #else
  330. space = SEGGER_RTT_GetAvailWriteSpace(0);
  331. #endif
  332. int writeDepth = BUFFER_SIZE_UP - space;
  333. #if (TRICE_PROTECT == 1)
  334. if (writeDepth < 0) // unexpected
  335. {
  336. for (;;)
  337. ;
  338. }
  339. #endif
  340. unsigned wd = (unsigned)writeDepth;
  341. RTT0_writeDepthMax = wd > RTT0_writeDepthMax ? wd : RTT0_writeDepthMax;
  342. }
  343. #endif // #if (TRICE_DIAGNOSTICS ==1) && defined(SEGGER_RTT)
  344. #define TRICE_DIRECT32 ((TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1) || (TRICE_DIRECT_AUXILIARY32 == 1))
  345. #define TRICE_DIRECT8 ((TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) || (TRICE_DIRECT_AUXILIARY8 == 1))
  346. #if TRICE_DIRECT32 && TRICE_DIRECT8
  347. #error configuration
  348. #endif
  349. #define TRICE_DIRECT32_ONLY TRICE_DIRECT32 && ((TRICE_BUFFER == TRICE_STACK_BUFFER) || (TRICE_BUFFER == TRICE_STATIC_BUFFER)) //!< direct only output
  350. #define TRICE_DIRECT32_ALSO TRICE_DIRECT32 && ((TRICE_BUFFER == TRICE_RING_BUFFER) || (TRICE_BUFFER == TRICE_DOUBLE_BUFFER)) //!< direct and deferred output
  351. #define TRICE_DIRECT8_ONLY TRICE_DIRECT8 && ((TRICE_BUFFER == TRICE_STACK_BUFFER) || (TRICE_BUFFER == TRICE_STATIC_BUFFER)) //!< direct only output
  352. #define TRICE_DIRECT8_ALSO TRICE_DIRECT8 && ((TRICE_BUFFER == TRICE_RING_BUFFER) || (TRICE_BUFFER == TRICE_DOUBLE_BUFFER)) //!< direct and deferred output
  353. #if TRICE_DIRECT32_ONLY && TRICE_DIRECT8_ONLY
  354. #error configuration
  355. #endif
  356. #if TRICE_DIRECT32_ALSO && TRICE_DIRECT8_ALSO
  357. #error configuration
  358. #endif
  359. #if TRICE_DIRECT32_ONLY && TRICE_DIRECT8_ALSO
  360. #error configuration
  361. #endif
  362. #if TRICE_DIRECT32_ALSO && TRICE_DIRECT8_ONLY
  363. #error configuration
  364. #endif
  365. #if TRICE_DIRECT32
  366. #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
  367. //! SEGGER_Write_RTT0_NoCheck32 was derived from SEGGER_RTT.c version 7.60g function _WriteNoCheck for speed reasons. If using a different version please review the code first.
  368. static void SEGGER_Write_RTT0_NoCheck32(const uint32_t *pData, unsigned NumW)
  369. {
  370. #if TRICE_CGO == 1 // automated tests
  371. TriceWriteDeviceCgo(pData, NumW << 2);
  372. #else // #if TRICE_CGO == 1
  373. unsigned NumWordsAtOnce;
  374. unsigned WrOff;
  375. unsigned RemW;
  376. #if TRICE_PROTECT == 1
  377. unsigned space = SEGGER_RTT_GetAvailWriteSpace(0);
  378. if (space < NumW << 2)
  379. {
  380. for (;;)
  381. ;
  382. }
  383. #endif
  384. // Get "to-host" ring buffer.
  385. // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
  386. static SEGGER_RTT_BUFFER_UP *const pRingUp0 = (SEGGER_RTT_BUFFER_UP *)((char *)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF);
  387. WrOff = pRingUp0->WrOff;
  388. RemW = (pRingUp0->SizeOfBuffer - WrOff) >> 2;
  389. volatile uint32_t *pDstW = (uint32_t *)((pRingUp0->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF); // lint !e826
  390. if (RemW > NumW) // All data fits before wrap around
  391. {
  392. WrOff += NumW << 2;
  393. while (NumW--)
  394. {
  395. *pDstW++ = *pData++;
  396. };
  397. RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
  398. pRingUp0->WrOff = WrOff;
  399. }
  400. else // We reach the end of the buffer, so need to wrap around
  401. {
  402. NumWordsAtOnce = RemW;
  403. while (NumWordsAtOnce--)
  404. {
  405. *pDstW++ = *pData++;
  406. };
  407. pDstW = (uint32_t *)(pRingUp0->pBuffer + SEGGER_RTT_UNCACHED_OFF); // lint !e826
  408. NumWordsAtOnce = NumW - RemW;
  409. while (NumWordsAtOnce--)
  410. {
  411. *pDstW++ = *pData++;
  412. };
  413. RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
  414. pRingUp0->WrOff = (NumW - RemW) << 2;
  415. }
  416. #if TRICE_DIAGNOSTICS == 1
  417. triceSeggerRTTDiagnostics();
  418. #endif
  419. #endif // #else // #if TRICE_CGO == 1
  420. }
  421. #endif // #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
  422. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
  423. //! directXEncode32 transforms buf to enc and adds a 0-delimiter and padding zeroes to the next uint32 boundary.
  424. //! \retval count of enc values
  425. static unsigned directXEncode32(uint32_t *enc, const void *buf, unsigned count)
  426. {
  427. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS)
  428. size_t lenX = COBSEncode(enc, buf, count << 2);
  429. #elif (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
  430. size_t lenX = TCOBSEncode(enc, buf, count << 2);
  431. #else
  432. #error configuration
  433. #endif
  434. size_t len4 = (lenX + 3 + 1) & ~3; // size with padding and with packet 0-delimiter
  435. int zeroesCount = len4 - lenX;
  436. memset(((uint8_t *)enc) + lenX, 0, zeroesCount);
  437. return len4 >> 2;
  438. }
  439. #endif // #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
  440. static void TriceDirectWrite32(const uint32_t *buf, unsigned count)
  441. {
  442. #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
  443. #if TRICE_PROTECT == 1
  444. #if TRICE_CGO == 1 // automated tests
  445. unsigned space = count << 2; // always enough space
  446. #else
  447. unsigned space = SEGGER_RTT_GetAvailWriteSpace(0);
  448. #endif
  449. if (space >= count << 2)
  450. {
  451. SEGGER_Write_RTT0_NoCheck32(buf, count);
  452. }
  453. else
  454. {
  455. #if TRICE_DIAGNOSTICS == 1
  456. TriceDirectOverflowCount++;
  457. #endif
  458. }
  459. #else // #if TRICE_PROTECT == 1
  460. #ifdef __GNUC__
  461. // https://stackoverflow.com/questions/5080848/disable-gcc-may-be-used-uninitialized-on-a-particular-variable
  462. #pragma GCC diagnostic push // save the actual diag context
  463. #ifndef __clang__
  464. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // disable maybe warnings
  465. #endif
  466. #endif // #ifdef __GNUC__
  467. // now impacted section of code
  468. SEGGER_Write_RTT0_NoCheck32(buf, count);
  469. #ifdef __GNUC__
  470. #pragma GCC diagnostic pop // restore previous diag context
  471. #endif // #ifdef __GNUC__
  472. #endif // #else // #if TRICE_PROTECT == 1
  473. #if TRICE_DIAGNOSTICS == 1
  474. triceSeggerRTTDiagnostics(); // todo: maybe not needed
  475. #endif
  476. #endif // #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
  477. #if TRICE_DIRECT_AUXILIARY32 == 1
  478. TriceNonBlockingDirectWrite32Auxiliary(buf, count);
  479. #endif // #if TRICE_DIRECT_AUXILIARY32 == 1
  480. }
  481. #endif // #if TRICE_DIRECT32
  482. #if TRICE_DIRECT8
  483. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
  484. //! directXEncode transforms buf to enc and adds a 0-delimiter and padding zeroes to the next uint32 boundary.
  485. static size_t directXEncode8(void *enc, const void *buf, unsigned len)
  486. {
  487. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS)
  488. size_t lenX = COBSEncode(enc, buf, len);
  489. #elif (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
  490. size_t lenX = TCOBSEncode(enc, buf, len);
  491. #else
  492. #error configuration
  493. #endif
  494. size_t len4 = (lenX + 1 + 3) & ~3;
  495. memset(enc + lenX, 0, len4 - lenX);
  496. return lenX + 1;
  497. }
  498. #endif // #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
  499. #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) || (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1)
  500. static void TriceWriteDeviceRtt0(const uint8_t *enc, size_t encLen)
  501. {
  502. #if TRICE_CGO == 1 // automated tests
  503. TriceWriteDeviceCgo(enc, encLen);
  504. #else // #if TRICE_CGO == 1
  505. #if TRICE_PROTECT == 1
  506. unsigned space = SEGGER_RTT_GetAvailWriteSpace(0);
  507. if (encLen <= space)
  508. {
  509. SEGGER_RTT_WriteNoLock(0, enc, encLen);
  510. }
  511. else
  512. {
  513. TriceDirectOverflowCount++;
  514. }
  515. #else // #if TRICE_PROTECT == 1
  516. SEGGER_RTT_WriteNoLock(0, enc, encLen);
  517. #endif // #else // #if TRICE_PROTECT == 1
  518. #endif // #else // #if TRICE_CGO == 1
  519. #if TRICE_DIAGNOSTICS == 1
  520. triceSeggerRTTDiagnostics(); // todo: maybe not needed
  521. #endif
  522. }
  523. #endif // #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) || (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1)
  524. static void TriceDirectWrite8(const uint8_t *enc, size_t encLen)
  525. {
  526. #if TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1
  527. TriceWriteDeviceRtt0(enc, encLen);
  528. #endif
  529. #if TRICE_DIRECT_AUXILIARY8
  530. TriceNonBlockingDirectWrite8Auxiliary(enc, encLen);
  531. #endif
  532. }
  533. #endif // #if TRICE_DIRECT8
  534. #if TRICE_DIRECT_OUTPUT == 1
  535. //! TriceNonBlockingDirectWrite copies a single trice from triceStart to output.
  536. //! This is the time critical part, executed inside TRICE_LEAVE.
  537. //! The trice data start at triceStart and include wordCount values with 1-3 padding bytes at the end.
  538. //! In front of triceStart are TRICE_DATA_OFFSET bytes space usable for optional in-buffer encoding. ??????? todo
  539. //! This is NOT the case, when using direct and deferred modes parallel, because for efficient RAM usage
  540. //! there is no gap between the Trices in double or ring buffer. Therefore, when enabling
  541. //! TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE together with a deferred mode, for efficiency the RTT output can only be unframed.
  542. //! The space behind the trice (at triceStart + wordCount) is usable because in direct mode this is writable.
  543. //! Also in combined modes (direct plus deferred) this is allowed, under certain circumstances:
  544. //! - TRICE_DOUBLE_BUFFER: The current Trice could be the last one and could have filled the double buffer to the end. So additional 4 bytes at the end are needed as scratc pad.
  545. //! - TRICE_RING_BUFFER: The max depth is not allowed and at the end is 4 bytes space needed.
  546. void TriceNonBlockingDirectWrite(uint32_t *triceStart, unsigned wordCount)
  547. {
  548. // The 16-bit stamped trices start with 2-times 16-bit ID for align and speed reasons.
  549. // The trice tool knows and expects that, when switch -packageFraming = NONE was applied.
  550. // The 2 additional transmit bytes are avoidable then but that would need a 2nd NONE option for the trice tool, what makes usage more confusing.
  551. // That the TRICE_FRAMING_NONE does not remove the 2 additional bytes for 16-bit stamped trices has the
  552. // main reason in the TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE option for the fast 32-bit transfer, what probably will be a common use case.
  553. // What happens here, is similar to TriceEncode but this is time critical code and we can do in-place encoding too.
  554. #if TRICE_DIRECT32_ONLY // Space at triceStart + wordCount is usable and we can destroy the data.
  555. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
  556. triceStart[wordCount++] = 0; // clear padding space
  557. wordCount &= ~1; // only multiple of 8 can be encrypted
  558. XTEAEncrypt(triceStart, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
  559. #endif
  560. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
  561. uint32_t *enc = triceStart;
  562. unsigned count = wordCount;
  563. #else
  564. static uint32_t enc[TRICE_BUFFER_SIZE >> 2]; // static buffer!
  565. unsigned count = directXEncode32(enc, triceStart, wordCount);
  566. #endif
  567. TriceDirectWrite32(enc, count);
  568. return;
  569. #elif TRICE_DIRECT8_ONLY // Space at triceStart + wordCount is usable and we can destroy the data.
  570. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
  571. triceStart[wordCount++] = 0; // clear padding space
  572. wordCount &= ~1; // only multiple of 8 can be encrypted
  573. XTEAEncrypt(triceStart, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
  574. #endif
  575. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
  576. uint8_t *enc = (uint8_t *)triceStart;
  577. unsigned len = wordCount << 2;
  578. #else
  579. static uint8_t enc[TRICE_BUFFER_SIZE]; // stack buffer!
  580. unsigned len = directXEncode8(enc, triceStart, wordCount << 2); // Up to 3 trailing zeroes are packed as well here.
  581. #endif
  582. TriceDirectWrite8(enc, len);
  583. return;
  584. #elif TRICE_DIRECT32_ALSO // Space at triceStart + wordCount is NOT usable and we can NOT destroy the data.
  585. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DIRECT_OUT_FRAMING != TRICE_FRAMING_NONE)
  586. static uint32_t enc[TRICE_BUFFER_SIZE >> 2]; // stack buffer!
  587. #endif
  588. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
  589. uint32_t *dat = enc + (TRICE_DATA_OFFSET >> 2);
  590. memcpy(dat, triceStart, wordCount << 2); // Trice data are 32-bit aligned.
  591. dat[wordCount++] = 0; // clear padding space
  592. wordCount &= ~1; // only multiple of 8 can be encrypted
  593. XTEAEncrypt(dat, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
  594. #else
  595. uint32_t *dat = triceStart;
  596. #endif
  597. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
  598. TriceDirectWrite32(dat, wordCount);
  599. #else
  600. unsigned count = directXEncode32(enc, dat, wordCount); // Up to 3 trailing zeroes are packed as well here.
  601. TriceDirectWrite32(enc, count);
  602. #endif
  603. return;
  604. #elif TRICE_DIRECT8_ALSO // Space at triceStart + wordCount is NOT usable and we can NOT destroy the data.
  605. #if TRICE_DIRECT_OUT_FRAMING != TRICE_FRAMING_NONE
  606. static uint32_t enc[TRICE_BUFFER_SIZE >> 2]; // stack buffer!
  607. #endif
  608. #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
  609. uint32_t *dat = enc + (TRICE_DATA_OFFSET >> 2);
  610. memcpy(dat, triceStart, wordCount << 2); // Trice data are 32-bit aligned.
  611. dat[wordCount++] = 0; // clear padding space
  612. wordCount &= ~1; // only multiple of 8 can be encrypted
  613. XTEAEncrypt(dat, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
  614. #else
  615. uint32_t *dat = triceStart;
  616. #endif
  617. #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
  618. TriceDirectWrite8((uint8_t *)dat, wordCount << 2);
  619. #else
  620. unsigned len = directXEncode8(enc, dat, wordCount << 2); // Up to 3 trailing zeroes are packed as well here.
  621. TriceDirectWrite8((uint8_t *)enc, len);
  622. #endif
  623. return;
  624. #else //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  625. #error configuration
  626. #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  627. }
  628. #endif // #if TRICE_DIRECT_OUTPUT == 1
  629. #if TRICE_DEFERRED_OUTPUT == 1
  630. // TriceNonBlockingDeferredWrite8 routes trice data to output channels.
  631. void TriceNonBlockingDeferredWrite8(int triceID, const uint8_t *enc, size_t encLen)
  632. {
  633. #if TRICE_DEFERRED_UARTA == 1
  634. #if (TRICE_UARTA_MIN_ID != 0) || (TRICE_UARTA_MAX_ID != 0)
  635. #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
  636. #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
  637. #endif
  638. if ((TRICE_UARTA_MIN_ID < triceID) && (triceID < TRICE_UARTA_MAX_ID))
  639. #else
  640. TRICE_UNUSED(triceID)
  641. #endif
  642. {
  643. TriceNonBlockingWriteUartA(enc, encLen);
  644. }
  645. #endif
  646. #if TRICE_DEFERRED_UARTB == 1
  647. #if (TRICE_UARTB_MIN_ID != 0) && (TRICE_UARTB_MAX_ID != 0)
  648. #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
  649. #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
  650. #endif
  651. if ((TRICE_UARTB_MIN_ID < triceID) && (triceID < TRICE_UARTB_MAX_ID))
  652. #else
  653. TRICE_UNUSED(triceID)
  654. #endif
  655. {
  656. TriceNonBlockingWriteUartB(enc, encLen);
  657. }
  658. #endif
  659. #if (TRICE_DEFERRED_AUXILIARY8 == 1)
  660. #if defined(TRICE_DEFERRED_AUXILIARY8_MIN_ID) && defined(TRICE_DEFERRED_AUXILIARY8_MAX_ID)
  661. #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
  662. #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
  663. #endif
  664. if ((TRICE_DEFERRED_AUXILIARY8_MIN_ID < triceID) && (triceID < TRICE_DEFERRED_AUXILIARY8_MAX_ID))
  665. #else
  666. TRICE_UNUSED(triceID)
  667. #endif
  668. {
  669. TriceNonBlockingDeferredWrite8Auxiliary(enc, encLen);
  670. }
  671. #endif
  672. #if (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1)
  673. #if defined(TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MIN_ID) && defined(TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MAX_ID)
  674. if ((TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MIN_ID < triceID) && (triceID < TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MAX_ID))
  675. #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
  676. #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
  677. #endif
  678. #else
  679. TRICE_UNUSED(triceID)
  680. #endif
  681. {
  682. TriceWriteDeviceRtt0(enc, encLen);
  683. }
  684. #endif
  685. // #if TRICE_LOG_OVER_MODBUS_FUNC24_ALSO == 1
  686. // #if defined(TRICE_MODBUS_MIN_ID) && defined(TRICE_MODBUS_MAX_ID)
  687. // if( (TRICE_MODBUS_MIN_ID < triceID) && (triceID < TRICE_MODBUS_MAX_ID) )
  688. // #else
  689. // TRICE_UNUSED(triceID)
  690. // #endif
  691. // TriceWriteDeviceModbus( enc, encLen );
  692. // #endif
  693. } // lint !e715 Info 715: Symbol 'triceID' not referenced
  694. #endif // #if TRICE_DEFERRED_OUTPUT == 1
  695. //! TriceOutDepth returns the amount of bytes not written yet from the slowest device.
  696. unsigned TriceOutDepth(void)
  697. {
  698. unsigned depth = 0;
  699. #if defined(SEGGER_RTT) || TRICE_DEFERRED_UARTA == 1 || TRICE_DEFERRED_UARTB == 1 || TRICE_CGO == 1
  700. unsigned d = 0;
  701. #endif
  702. TRICE_ENTER_CRITICAL_SECTION
  703. #ifdef SEGGER_RTT
  704. // When no RTT host is connected, the RTT buffer runs full.
  705. // If a RTT host is connected, it is assumed to be the fastest device.
  706. depth = d > depth ? d : depth;
  707. #endif
  708. #if TRICE_DEFERRED_UARTA == 1
  709. d = TriceOutDepthUartA(); // lint !e838
  710. depth = d > depth ? d : depth;
  711. #endif
  712. #if TRICE_DEFERRED_UARTB == 1
  713. d = TriceOutDepthUartB();
  714. depth = d > depth ? d : depth;
  715. #endif
  716. #if TRICE_CGO == 1 // automated tests
  717. d = TriceOutDepthCGO();
  718. depth = d > depth ? d : depth;
  719. #endif
  720. TRICE_LEAVE_CRITICAL_SECTION
  721. return depth;
  722. }
  723. #ifdef __GNUC__
  724. // https://stackoverflow.com/questions/5080848/disable-gcc-may-be-used-uninitialized-on-a-particular-variable
  725. #pragma GCC diagnostic push // save the actual diag context
  726. #ifndef __clang__
  727. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // disable maybe warnings
  728. #endif
  729. #endif // #ifdef __GNUC__
  730. // now impacted section of code
  731. //! TRICE_ASSERT writes trice data as fast as possible in a buffer.
  732. //! \param tid is a 16 bit Trice id in upper 2 bytes of a 32 bit value
  733. //! This is a helper macro and should not be used in user code.
  734. #define TRICE_ASSERT(tid) \
  735. TRICE_ENTER tid; \
  736. TRICE_CNTC(0); \
  737. TRICE_LEAVE
  738. void triceAssertTrue(int idN, char *msg, int flag)
  739. {
  740. TRICE_UNUSED(msg)
  741. if (!flag)
  742. {
  743. TRICE_ASSERT(id(idN));
  744. }
  745. }
  746. void TriceAssertTrue(int idN, char *msg, int flag)
  747. {
  748. TRICE_UNUSED(msg)
  749. if (!flag)
  750. {
  751. TRICE_ASSERT(Id(idN));
  752. }
  753. }
  754. void TRiceAssertTrue(int idN, char *msg, int flag)
  755. {
  756. TRICE_UNUSED(msg)
  757. if (!flag)
  758. {
  759. TRICE_ASSERT(ID(idN));
  760. }
  761. }
  762. void triceAssertFalse(int idN, char *msg, int flag)
  763. {
  764. TRICE_UNUSED(msg)
  765. if (flag)
  766. {
  767. TRICE_ASSERT(id(idN));
  768. }
  769. }
  770. void TriceAssertFalse(int idN, char *msg, int flag)
  771. {
  772. TRICE_UNUSED(msg)
  773. if (flag)
  774. {
  775. TRICE_ASSERT(Id(idN));
  776. }
  777. }
  778. void TRiceAssertFalse(int idN, char *msg, int flag)
  779. {
  780. TRICE_UNUSED(msg)
  781. if (flag)
  782. {
  783. TRICE_ASSERT(ID(idN));
  784. }
  785. }
  786. #ifdef __GNUC__
  787. #pragma GCC diagnostic pop // restore previous diag context
  788. #endif // #ifdef __GNUC__
  789. #ifdef TRICE_N
  790. void triceN(int tid, char *fmt, void *buf, uint32_t n)
  791. {
  792. TRICE_N(id(tid), fmt, buf, n);
  793. }
  794. void TriceN(int tid, char *fmt, void *buf, uint32_t n)
  795. {
  796. TRICE_N(Id(tid), fmt, buf, n);
  797. }
  798. void TRiceN(int tid, char *fmt, void *buf, uint32_t n)
  799. {
  800. TRICE_N(ID(tid), fmt, buf, n);
  801. }
  802. void trice8B(int tid, char *fmt, void *buf, uint32_t n)
  803. {
  804. TRICE8_B(id(tid), fmt, buf, n);
  805. }
  806. void Trice8B(int tid, char *fmt, void *buf, uint32_t n)
  807. {
  808. TRICE8_B(Id(tid), fmt, buf, n);
  809. }
  810. void TRice8B(int tid, char *fmt, void *buf, uint32_t n)
  811. {
  812. TRICE8_B(ID(tid), fmt, buf, n);
  813. }
  814. void trice16B(int tid, char *fmt, void *buf, uint32_t n)
  815. {
  816. TRICE16_B(id(tid), fmt, buf, n);
  817. }
  818. void Trice16B(int tid, char *fmt, void *buf, uint32_t n)
  819. {
  820. TRICE16_B(Id(tid), fmt, buf, n);
  821. }
  822. void TRice16B(int tid, char *fmt, void *buf, uint32_t n)
  823. {
  824. TRICE16_B(ID(tid), fmt, buf, n);
  825. }
  826. void trice32B(int tid, char *fmt, void *buf, uint32_t n)
  827. {
  828. TRICE32_B(id(tid), fmt, buf, n);
  829. }
  830. void Trice32B(int tid, char *fmt, void *buf, uint32_t n)
  831. {
  832. TRICE32_B(Id(tid), fmt, buf, n);
  833. }
  834. void TRice32B(int tid, char *fmt, void *buf, uint32_t n)
  835. {
  836. TRICE32_B(ID(tid), fmt, buf, n);
  837. }
  838. void trice64B(int tid, char *fmt, void *buf, uint32_t n)
  839. {
  840. TRICE64_B(id(tid), fmt, buf, n);
  841. }
  842. void Trice64B(int tid, char *fmt, void *buf, uint32_t n)
  843. {
  844. TRICE64_B(Id(tid), fmt, buf, n);
  845. }
  846. void TRice64B(int tid, char *fmt, void *buf, uint32_t n)
  847. {
  848. TRICE64_B(ID(tid), fmt, buf, n);
  849. }
  850. void trice8F(int tid, char *fmt, void *buf, uint32_t n)
  851. {
  852. TRICE8_F(id(tid), fmt, buf, n);
  853. }
  854. void Trice8F(int tid, char *fmt, void *buf, uint32_t n)
  855. {
  856. TRICE8_F(Id(tid), fmt, buf, n);
  857. }
  858. void TRice8F(int tid, char *fmt, void *buf, uint32_t n)
  859. {
  860. TRICE8_F(ID(tid), fmt, buf, n);
  861. }
  862. void trice16F(int tid, char *fmt, void *buf, uint32_t n)
  863. {
  864. TRICE16_F(id(tid), fmt, buf, n);
  865. }
  866. void Trice16F(int tid, char *fmt, void *buf, uint32_t n)
  867. {
  868. TRICE16_F(Id(tid), fmt, buf, n);
  869. }
  870. void TRice16F(int tid, char *fmt, void *buf, uint32_t n)
  871. {
  872. TRICE16_F(ID(tid), fmt, buf, n);
  873. }
  874. void trice32F(int tid, char *fmt, void *buf, uint32_t n)
  875. {
  876. TRICE32_F(id(tid), fmt, buf, n);
  877. }
  878. void Trice32F(int tid, char *fmt, void *buf, uint32_t n)
  879. {
  880. TRICE32_F(Id(tid), fmt, buf, n);
  881. }
  882. void TRice32F(int tid, char *fmt, void *buf, uint32_t n)
  883. {
  884. TRICE32_F(ID(tid), fmt, buf, n);
  885. }
  886. void trice64F(int tid, char *fmt, void *buf, uint32_t n)
  887. {
  888. TRICE64_F(id(tid), fmt, buf, n);
  889. }
  890. void Trice64F(int tid, char *fmt, void *buf, uint32_t n)
  891. {
  892. TRICE64_F(Id(tid), fmt, buf, n);
  893. }
  894. void TRice64F(int tid, char *fmt, void *buf, uint32_t n)
  895. {
  896. TRICE64_F(ID(tid), fmt, buf, n);
  897. }
  898. #endif // #ifdef TRICE_N
  899. #ifdef TRICE_S
  900. void triceS(int tid, char *fmt, char *runtimeGeneratedString)
  901. {
  902. TRICE_S(id(tid), fmt, runtimeGeneratedString);
  903. }
  904. void TriceS(int tid, char *fmt, char *runtimeGeneratedString)
  905. {
  906. TRICE_S(Id(tid), fmt, runtimeGeneratedString);
  907. }
  908. void TRiceS(int tid, char *fmt, char *runtimeGeneratedString)
  909. {
  910. TRICE_S(ID(tid), fmt, runtimeGeneratedString);
  911. }
  912. #endif // #ifdef TRICE_N
  913. #endif // #if !TRICE_OFF