| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127 |
- //! \file trice.c
- //! \author Thomas.Hoehenleitner [at] seerose.net
- //! ///////////////////////////////////////////////////////////////////////////
-
- #include "trice.h"
- #include "cobs.h"
- #include "tcobs.h"
- #include "xtea.h"
-
- #if !TRICE_OFF
-
- // check configuration:
-
- #ifndef TRICE_DATA_OFFSET
- #error configuration: Check triceDefaultConfig.h or add "#define TRICE_DATA_OFFSET 16" to your triceConfig.h.
- #endif
-
- #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_AUXILIARY32 == 1)
- #error configuration: Only one bit width for direct output is supported.
- #endif
-
- #if (TRICE_DIRECT_AUXILIARY8 == 1) && (TRICE_DIRECT_AUXILIARY32 == 1)
- #error configuration: Only one bit width for direct output is supported.
- #endif
-
- #if (TRICE_DIRECT_AUXILIARY8 == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
- #error configuration: Only one bit width for direct output is supported.
- #endif
-
- #if (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1) && (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1)
- #error configuration: TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE not implemented: (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1)
- #endif
-
- #if (TRICE_DEFERRED_XTEA_ENCRYPT == 1) && (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_TCOBS) && (TRICE_CONFIG_WARNINGS == 1)
- #pragma message("configuration: XTEA with TCOBS is possible but not recommended. Encrypted data are more effective framed with COBS.")
- #endif
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) && (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS) && (TRICE_CONFIG_WARNINGS == 1)
- #pragma message("configuration: XTEA with TCOBS is possible but not recommended. Encrypted data are more effective framed with COBS.")
- #endif
-
- #ifndef TRICE_DEFERRED_TRANSFER_MODE
- #error configuration: Check triceDefaultConfig.h or add "#define TRICE_DEFERRED_TRANSFER_MODE TRICE_SINGLE_PACK_MODE" to your triceConfig.h.
- #endif
-
- #if (TRICE_DEFERRED_TRANSFER_MODE != TRICE_SINGLE_PACK_MODE) && (TRICE_DEFERRED_TRANSFER_MODE != TRICE_MULTI_PACK_MODE)
- #error configuration: Check TRICE_DEFERRED_TRANSFER_MODE value.
- #endif
-
- #if (TRICE_DEFERRED_TRANSFER_MODE == TRICE_SINGLE_PACK_MODE) && (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DATA_OFFSET < 64) && (TRICE_CONFIG_WARNINGS == 1)
- #warning configuration: Because each Trice is encoded separately, several Trices can easy "eat" the TRICE_DATA_OFFSET, so make this value not too small.
- #endif
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) && (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE) && (TRICE_CONFIG_WARNINGS == 1)
- #warning configuration: The Trice tool needs COBS (or TCOBS) framing for encrypted data.
- #endif
-
- #if (TRICE_DEFERRED_XTEA_ENCRYPT == 1) && (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_NONE) && (TRICE_CONFIG_WARNINGS == 1)
- #warning configuration: The Trice tool needs COBS (or TCOBS) framing for encrypted data.
- #endif
-
- #if (TRICE_DEFERRED_XTEA_ENCRYPT == 0) && (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_NONE) && (TRICE_CONFIG_WARNINGS == 1)
- #warning configuration: (TRICE_DEFERRED_OUT_FRAMING == TRICE_FRAMING_NONE) is depreciated and not fully tested. Will probably not run error free.
- #endif
-
- #if (TRICE_DIRECT_OUTPUT == 0) && (TRICE_DEFERRED_OUTPUT == 0)
- #error configuration: need at least one output mode - (TRICE_DIRECT_OUTPUT == 1) and/or (TRICE_DEFERRED_OUTPUT == 0)
- #endif
-
- #if (TRICE_DEFERRED_OUTPUT == 0) && (TRICE_BUFFER == TRICE_RING_BUFFER)
- #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)
- #endif
-
- #if (TRICE_DEFERRED_OUTPUT == 0) && (TRICE_BUFFER == TRICE_DOUBLE_BUFFER)
- #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)
- #endif
-
- #if (TRICE_DEFERRED_OUTPUT == 1) && (TRICE_BUFFER == TRICE_STACK_BUFFER)
- #error configuration: (TRICE_BUFFER == TRICE_STACK_BUFFER) needs (TRICE_DEFERRED_OUTPUT == 0)
- #endif
-
- #if (TRICE_DEFERRED_OUTPUT == 1) && (TRICE_BUFFER == TRICE_STATIC_BUFFER)
- #error configuration: (TRICE_BUFFER == TRICE_STATIC_BUFFER) needs (TRICE_DEFERRED_OUTPUT == 0)
- #endif
-
- #if (TRICE_CGO == 1) && (TRICE_CYCLE_COUNTER == 1) && (TRICE_CONFIG_WARNINGS == 1)
- #warning configuration: TRICE_CGO == 1 needs TRICE_CYCLE_COUNTER == 0 for successful tests.
- #endif
-
- #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)
- #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
- #endif
-
- #if (TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING == 1) && (TRICE_DEFERRED_OUTPUT == 0)
- #error configuration: TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING == 1 needs TRICE_DEFERRED_OUTPUT == 1
- #endif
-
- #if (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1) && (TRICE_DIRECT_OUTPUT == 0)
- #error configuration: TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1 needs TRICE_DIRECT_OUTPUT == 1
- #endif
-
- #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
- #error configuration: only one RTT output channel is possible
- #endif
-
- #if (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
- #error configuration: only one RTT output channel is possible
- #endif
-
- #if (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1)
- #error configuration: only one RTT output channel is possible
- #endif
-
- #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_BUFFER_SIZE / 2 < TRICE_BUFFER_SIZE)
- #error configuration: TRICE_DEFERRED_BUFFER_SIZE too small
- #endif
-
- #if (TRICE_BUFFER == TRICE_RING_BUFFER) && (TRICE_DEFERRED_BUFFER_SIZE < TRICE_DATA_OFFSET + TRICE_SINGLE_MAX_SIZE)
- #error configuration: TRICE_DEFERRED_BUFFER_SIZE too small
- #endif
-
- #if (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1) && (TRICE_DIRECT_OUTPUT == 0)
- #error configuration: TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1 needs TRICE_DIRECT_OUTPUT == 1
- #endif
-
- #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) && (TRICE_DIRECT_OUTPUT == 0)
- #error configuration: TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1 needs TRICE_DIRECT_OUTPUT == 1
- #endif
-
- #if defined(SEGGER_RTT) && (TRICE_BUFFER_SIZE > BUFFER_SIZE_UP)
- #error configuration: BUFFER_SIZE_UP too small
- #endif
-
- #if (TRICE_BUFFER == TRICE_STACK_BUFFER) && (TRICE_DIRECT_OUTPUT == 0)
- #error configuration: direct-only mode needs TRICE_DIRECT_OUTPUT == 1
- #endif
-
- #if (TRICE_BUFFER == TRICE_STATIC_BUFFER) && (TRICE_DIRECT_OUTPUT == 0)
- #error configuration: direct-only mode needs TRICE_DIRECT_OUTPUT == 1
- #endif
-
- #if (TRICE_DEFERRED_OUTPUT == 1) && (TRICE_DEFERRED_UARTA == 0) && (TRICE_DEFERRED_UARTB == 0) && (TRICE_DEFERRED_AUXILIARY8 == 0) && (TRICE_DEFERRED_AUXILIARY32 == 0)
- #error configuration: TRICE_DEFERRED_OUTPUT == 1 needs TRICE_DFERRED_UARTx or TRICE_DEFERRED_AUXILIARYx
- #endif
-
- #if (TRICE_DEFERRED_UARTA == 1) && !defined(TRICE_UARTA)
- #error configuration: deferred TRICE_DEFERRED_UARTA == 1 needs a defined TRICE_UARTA.
- #endif
-
- #if (TRICE_DEFERRED_UARTB == 1) && !defined(TRICE_UARTA)
- #error configuration: deferred TRICE_DEFERRED_UARTB == 1 needs a defined TRICE_UARTB.
- #endif
-
- #if TRICE_DATA_OFFSET & 3
- #error TRICE_DATA_OFFSET -all size values must be a multiple of 4!
- #endif
-
- #if TRICE_DATA_OFFSET < 8 && TRICE_BUFFER == TRICE_RING_BUFFER
- #warning TRICE_DATA_OFFSET should usually be at least 8 bytes, when TRICE_BUFFER == TRICE_RING_BUFFER.
- #endif
-
- #if TRICE_SINGLE_MAX_SIZE & 3
- #error TRICE_SINGLE_MAX_SIZE - all size values must be a multiple of 4!
- #endif
-
- #if TRICE_DEFERRED_BUFFER_SIZE & 3
- #error TRICE_DEFERRED_BUFFER_SIZE - all size values must be a multiple of 4!
- #endif
-
- #if (TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1)
- #warning configuration: TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING is experimental
- #endif
-
- #if (TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING == 1)
- #warning configuration: TRICE_DEFERRED_OUTPUT_IS_WITH_ROUTING is experimental
- #endif
-
- #if (TRICE_DIRECT_AUXILIARY8 == 1) && (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
- #error configuration: (TRICE_DIRECT_AUXILIARY8 == 1) allows (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) but not (TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1)
- #endif
-
- // function prototypes:
-
- #if TRICE_DEFERRED_UARTA == 1
- void TriceNonBlockingWriteUartA(const void *buf, size_t nByte);
- #endif
-
- #if TRICE_DEFERRED_UARTB == 1
- void TriceNonBlockingWriteUartB(const void *buf, size_t nByte);
- #endif
-
- #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
- static void SEGGER_Write_RTT0_NoCheck32(const uint32_t *pData, unsigned NumW);
- #endif
-
- // global variables:
-
- //! TriceErrorCount is incremented, when data inside the internal trice buffer are corrupted.
- //! That could happen for example, when the buffer wrapped before data are sent (case TRICE_PROTECT==0).
- //! The user app should check this diagnostic value.
- unsigned TriceErrorCount = 0;
-
- //! triceCommand is the command receive buffer.
- char triceCommandBuffer[TRICE_COMMAND_SIZE_MAX + 1]; // with terminating 0
-
- //! triceCommandFlag ist set, when a command was received completely.
- int triceCommandFlag = 0; // updated
-
- #if TRICE_CYCLE_COUNTER == 1
-
- //! TriceCycle is increased and transmitted with each trice message, if enabled.
- uint8_t TriceCycle = 0xc0;
-
- #endif
-
- #if TRICE_DIAGNOSTICS == 1
-
- //! TriceDataOffsetDepthMax measures the max used offset space.
- int TriceDataOffsetDepthMax = 0;
-
- //! TriceSingleMaxWordCount is a diagnostics value usable to optimize buffer space TRICE_BUFFER_SIZE for a single trice message.
- unsigned TriceSingleMaxWordCount = 0;
-
- //! TriceDynStringBufTruncateCount couts how often a dynamic buffer was truncated because it was too long.
- unsigned TriceDynStringBufTruncateCount = 0;
-
- #if TRICE_PROTECT == 1
-
- #if TRICE_DIRECT_OUTPUT == 1
- unsigned TriceDirectOverflowCount = 0;
- #endif
-
- #if TRICE_DEFERRED_OUTPUT == 1
- unsigned TriceDeferredOverflowCount = 0;
- #endif
-
- #endif // #if TRICE_PROTECT == 1
-
- #endif // #if TRICE_DIAGNOSTICS == 1
-
- //! TriceInit needs to run before the first trice macro is executed.
- //! Not neseecary for all configurations.
- void TriceInit(void)
- {
- #if defined(SEGGER_RTT) && (TRICE_CGO == 0)
- // This is just to force the INIT() call inside SEGGER_RTT.c what allows to use
- // SEGGER_RTT_WriteNoLock or SEGGER_Write_RTT0_NoCheck32 instead of SEGGER_RTT_Write.
- SEGGER_RTT_Write(0, 0, 0); // lint !e534
- #endif
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DEFERRED_XTEA_ENCRYPT == 1)
- XTEAInitTable();
- #endif
-
- #if TRICE_BUFFER == TRICE_RING_BUFFER && TRICE_RING_BUFFER_OVERFLOW_WATCH == 1
- TriceInitRingBufferMargins();
- #endif
- }
-
- //! triceDataLen returns encoded len.
- //! \param p points to nc
- //! To avoid alignment issues, the optional payload needs to start at a 32-bit boundary.
- //! The provided buffer starts also at a 32-bit boundary.
- //! To ensure, the first 16-bit value is ssiiiiiiI we do the following:
- //! - v__________________ v___________ v__ (32-bit alignment positions)
- //! - *da = 11iiiiiiI TT TT NC ... | ID(n): After writing 11iiiiiiI write the 32-bit TTTT value in 2 16-bit write operations.
- //! - *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.
- //! - *da = 01iiiiiiI NC ... | id(n): Just write 01iiiiiiI as 16-bit operation.
- //! - *da = 00xxxxxxX extended trices are not used yet, unspecified length >= 2
- //! - This way, after writing the 16-bit NC value the payload starts always at a 32-bit boundary.
- //! - With framing, user 0,1,2,3-byte messages allowed and ignored by the trice tool.
- size_t triceDataLen(const uint8_t *p)
- {
- uint16_t nc = TRICE_TTOHS(*(uint16_t *)p); // lint !e826
- size_t n = nc >> 8;
- if (n < 128)
- {
- return n;
- }
- return nc & 0x7fff;
- }
-
- #if TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1
-
- //! triceIDAndLen expects at buf a trice message and returns the ID for routing.
- //! \param pBuf is where the trice message starts.
- //! \param ppStart return the trice data start address. This is pBuf or 2 bytes later.
- //! \param triceID is filled positive ID value on success or negative on error.
- //! \retval is the netto trice length (without padding bytes), 0 on error.
- static size_t triceIDAndLen(uint32_t *pBuf, uint8_t **ppStart, int *triceID)
- {
- uint16_t *pTID = (uint16_t *)pBuf; // get TID address
- uint16_t TID = TRICE_TTOHS(*pTID); // type and id
- *triceID = 0x3FFF & TID;
- int triceType = TID >> 14;
- size_t len;
- uint8_t *pStart = (uint8_t *)pBuf;
- switch (triceType)
- {
- case TRICE_TYPE_S0: // S0 = no stamp
- len = 4 + triceDataLen(pStart + 2); // tyId
- break;
- case TRICE_TYPE_S2: // S2 = 16-bit stamp
- pStart += 2; // see Id(n) macro definition
- len = 6 + triceDataLen(pStart + 4); // tyId ts16
- break;
- case TRICE_TYPE_S4: // S4 = 32-bit stamp
- len = 8 + triceDataLen(pStart + 6); // tyId ts32
- break;
- default:
- // lint -fallthrugh
- case TRICE_TYPE_X0:
- TriceErrorCount++;
- *triceID = -__LINE__; // extended trices not supported (yet)
- return 0;
- }
- *ppStart = pStart;
- return len;
- }
-
- #endif // #if TRICE_DIRECT_OUTPUT_IS_WITH_ROUTING == 1
-
- //! TriceEncode expects at buf trice net data with net length len.
- //! It fills dst with the next trice data, which are encoded and framed or not, according the selected switches.
- //! The areas of dst and buf are allowed to overlap.
- //! \param encrypt, when 0, then without encryption, when 1, then with XTEA encryption.
- //! \param framing selects if and which framing is used.
- //! \param dst is the destination. It must be 32-bit aligned.
- //! \param buf is the source. This can be not 32-bit aligned.
- //! \param len is the source len.
- //! \retval is the encoded len with 0-delimiter byte.
- size_t TriceEncode(unsigned encrypt, unsigned framing, uint8_t *dst, const uint8_t *buf, size_t len)
- {
- #if TRICE_DIAGNOSTICS == 1
- int distance = buf - dst;
- if (distance < 4)
- {
- TriceErrorCount++;
- }
- int TriceDataOffsetDepth = TRICE_DATA_OFFSET - distance;
- TriceDataOffsetDepthMax = TriceDataOffsetDepth < TriceDataOffsetDepthMax ? TriceDataOffsetDepthMax : TriceDataOffsetDepth;
- #endif
-
- size_t encLen;
- const uint8_t *dat = buf;
-
- if (encrypt)
- {
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DEFERRED_XTEA_ENCRYPT == 1)
-
- // Only multiple of 8 encryptable, but trice data are 32-bit aligned.
- // A 64-bit trice data aligning would waste RAM and costs a bit time during trice generation.
- // We need additional 4 bytes after each trice for the XTEA encryption.
- // Also, the framing could make the trice message a bit longer.
- // Therefore we copy the trice data to a place, we can use.
- // The location for XTEAEncrypt must lay on a 32-bit boundary.
- #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE)
-
- // special case: The data can be big, are compacted and behind them is space. So we can encrypt them in space
- dat = buf; // That is also for the framing afterwards.
- size_t len8 = (len + 7) & ~7; // Only multiple of 8 encryptable, so we adjust len.
- memset(((uint8_t *)buf) + len, 0, len8 - len); // clear padding space: ATTENTION! OK only for this compiler switch setting.
- len = len8;
- XTEAEncrypt((uint32_t *)dat, len8 >> 2);
-
- #else // #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE)
-
- // Let space in front for framing, free 4 bytes behind do a 32-bit align backwards.
- // uint32_t * loc = (uint32_t *)(((unsigned)dst + TRICE_DATA_OFFSET - 4) & ~3);
- // The computing above does not work, because, when several Trices, this "free" location
- // drifts into the unprocessed Trice data. So we create a buffer.
- // Not on the stack, because small stacks could be a problem here.
- static uint32_t loc[TRICE_SINGLE_MAX_SIZE >> 2];
-
- // Because dst + TRICE_DATA_OFFSET could be the buf value itself, we need to move at least 4 bytes.
- memmove(loc, buf, len); // We use not memcpy here, because dst and buf allowed to overlap.
- dat = (const uint8_t *)loc; // That is also for the framing afterwards.
- size_t len8 = (len + 7) & ~7; // Only multiple of 8 encryptable, so we adjust len.
- memset(((uint8_t *)loc) + len, 0, len8 - len); // clear padding space
- len = len8;
- XTEAEncrypt(loc, len8 >> 2);
-
- #endif // #else // #if (TRICE_BUFFER == TRICE_DOUBLE_BUFFER) && (TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE)
-
- #endif // #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DEFERRED_XTEA_ENCRYPT == 1)
- }
-
- switch (framing)
- {
- case TRICE_FRAMING_TCOBS:
- encLen = (size_t)TCOBSEncode(dst, dat, len);
- dst[encLen++] = 0; // Add zero as package delimiter.
- return encLen;
- case TRICE_FRAMING_COBS:
- encLen = (size_t)COBSEncode(dst, dat, len);
- dst[encLen++] = 0; // Add zero as package delimiter.
- return encLen;
- case TRICE_FRAMING_NONE:
- memmove(dst, dat, len);
- encLen = len;
- return encLen;
- }
-
- return 0; // unexpected
- }
-
- #if (TRICE_DIAGNOSTICS == 1) && defined(SEGGER_RTT)
-
- unsigned RTT0_writeDepthMax = 0; //! < RTT0_writeDepthMax is usable for diagnostics.
-
- static void triceSeggerRTTDiagnostics(void)
- {
- unsigned space;
- #if TRICE_CGO == 1 // automated tests
- space = TRICE_BUFFER_SIZE;
- #else
- space = SEGGER_RTT_GetAvailWriteSpace(0);
- #endif
- int writeDepth = BUFFER_SIZE_UP - space;
- #if (TRICE_PROTECT == 1)
- if (writeDepth < 0) // unexpected
- {
- for (;;)
- ;
- }
- #endif
- unsigned wd = (unsigned)writeDepth;
- RTT0_writeDepthMax = wd > RTT0_writeDepthMax ? wd : RTT0_writeDepthMax;
- }
-
- #endif // #if (TRICE_DIAGNOSTICS ==1) && defined(SEGGER_RTT)
-
- #define TRICE_DIRECT32 ((TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1) || (TRICE_DIRECT_AUXILIARY32 == 1))
- #define TRICE_DIRECT8 ((TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) || (TRICE_DIRECT_AUXILIARY8 == 1))
-
- #if TRICE_DIRECT32 && TRICE_DIRECT8
- #error configuration
- #endif
-
- #define TRICE_DIRECT32_ONLY TRICE_DIRECT32 && ((TRICE_BUFFER == TRICE_STACK_BUFFER) || (TRICE_BUFFER == TRICE_STATIC_BUFFER)) //!< direct only output
- #define TRICE_DIRECT32_ALSO TRICE_DIRECT32 && ((TRICE_BUFFER == TRICE_RING_BUFFER) || (TRICE_BUFFER == TRICE_DOUBLE_BUFFER)) //!< direct and deferred output
-
- #define TRICE_DIRECT8_ONLY TRICE_DIRECT8 && ((TRICE_BUFFER == TRICE_STACK_BUFFER) || (TRICE_BUFFER == TRICE_STATIC_BUFFER)) //!< direct only output
- #define TRICE_DIRECT8_ALSO TRICE_DIRECT8 && ((TRICE_BUFFER == TRICE_RING_BUFFER) || (TRICE_BUFFER == TRICE_DOUBLE_BUFFER)) //!< direct and deferred output
-
- #if TRICE_DIRECT32_ONLY && TRICE_DIRECT8_ONLY
- #error configuration
- #endif
-
- #if TRICE_DIRECT32_ALSO && TRICE_DIRECT8_ALSO
- #error configuration
- #endif
-
- #if TRICE_DIRECT32_ONLY && TRICE_DIRECT8_ALSO
- #error configuration
- #endif
-
- #if TRICE_DIRECT32_ALSO && TRICE_DIRECT8_ONLY
- #error configuration
- #endif
-
- #if TRICE_DIRECT32
-
- #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
-
- //! 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.
- static void SEGGER_Write_RTT0_NoCheck32(const uint32_t *pData, unsigned NumW)
- {
- #if TRICE_CGO == 1 // automated tests
- TriceWriteDeviceCgo(pData, NumW << 2);
- #else // #if TRICE_CGO == 1
-
- unsigned NumWordsAtOnce;
- unsigned WrOff;
- unsigned RemW;
-
- #if TRICE_PROTECT == 1
- unsigned space = SEGGER_RTT_GetAvailWriteSpace(0);
- if (space < NumW << 2)
- {
- for (;;)
- ;
- }
- #endif
- // Get "to-host" ring buffer.
- // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
- static SEGGER_RTT_BUFFER_UP *const pRingUp0 = (SEGGER_RTT_BUFFER_UP *)((char *)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF);
- WrOff = pRingUp0->WrOff;
- RemW = (pRingUp0->SizeOfBuffer - WrOff) >> 2;
- volatile uint32_t *pDstW = (uint32_t *)((pRingUp0->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF); // lint !e826
-
- if (RemW > NumW) // All data fits before wrap around
- {
- WrOff += NumW << 2;
- while (NumW--)
- {
- *pDstW++ = *pData++;
- };
- RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
- pRingUp0->WrOff = WrOff;
- }
- else // We reach the end of the buffer, so need to wrap around
- {
- NumWordsAtOnce = RemW;
- while (NumWordsAtOnce--)
- {
- *pDstW++ = *pData++;
- };
- pDstW = (uint32_t *)(pRingUp0->pBuffer + SEGGER_RTT_UNCACHED_OFF); // lint !e826
- NumWordsAtOnce = NumW - RemW;
- while (NumWordsAtOnce--)
- {
- *pDstW++ = *pData++;
- };
- RTT__DMB(); // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
- pRingUp0->WrOff = (NumW - RemW) << 2;
- }
- #if TRICE_DIAGNOSTICS == 1
- triceSeggerRTTDiagnostics();
- #endif
-
- #endif // #else // #if TRICE_CGO == 1
- }
-
- #endif // #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
-
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
-
- //! directXEncode32 transforms buf to enc and adds a 0-delimiter and padding zeroes to the next uint32 boundary.
- //! \retval count of enc values
- static unsigned directXEncode32(uint32_t *enc, const void *buf, unsigned count)
- {
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS)
- size_t lenX = COBSEncode(enc, buf, count << 2);
- #elif (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
- size_t lenX = TCOBSEncode(enc, buf, count << 2);
- #else
- #error configuration
- #endif
-
- size_t len4 = (lenX + 3 + 1) & ~3; // size with padding and with packet 0-delimiter
- int zeroesCount = len4 - lenX;
- memset(((uint8_t *)enc) + lenX, 0, zeroesCount);
- return len4 >> 2;
- }
-
- #endif // #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
-
- static void TriceDirectWrite32(const uint32_t *buf, unsigned count)
- {
- #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
-
- #if TRICE_PROTECT == 1
-
- #if TRICE_CGO == 1 // automated tests
- unsigned space = count << 2; // always enough space
- #else
- unsigned space = SEGGER_RTT_GetAvailWriteSpace(0);
- #endif
-
- if (space >= count << 2)
- {
- SEGGER_Write_RTT0_NoCheck32(buf, count);
- }
- else
- {
- #if TRICE_DIAGNOSTICS == 1
- TriceDirectOverflowCount++;
- #endif
- }
-
- #else // #if TRICE_PROTECT == 1
-
- #ifdef __GNUC__
- // https://stackoverflow.com/questions/5080848/disable-gcc-may-be-used-uninitialized-on-a-particular-variable
- #pragma GCC diagnostic push // save the actual diag context
- #ifndef __clang__
- #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // disable maybe warnings
- #endif
- #endif // #ifdef __GNUC__
- // now impacted section of code
- SEGGER_Write_RTT0_NoCheck32(buf, count);
- #ifdef __GNUC__
- #pragma GCC diagnostic pop // restore previous diag context
- #endif // #ifdef __GNUC__
-
- #endif // #else // #if TRICE_PROTECT == 1
-
- #if TRICE_DIAGNOSTICS == 1
- triceSeggerRTTDiagnostics(); // todo: maybe not needed
- #endif
-
- #endif // #if TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE == 1
-
- #if TRICE_DIRECT_AUXILIARY32 == 1
- TriceNonBlockingDirectWrite32Auxiliary(buf, count);
- #endif // #if TRICE_DIRECT_AUXILIARY32 == 1
- }
-
- #endif // #if TRICE_DIRECT32
-
- #if TRICE_DIRECT8
-
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
-
- //! directXEncode transforms buf to enc and adds a 0-delimiter and padding zeroes to the next uint32 boundary.
- static size_t directXEncode8(void *enc, const void *buf, unsigned len)
- {
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS)
- size_t lenX = COBSEncode(enc, buf, len);
- #elif (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
- size_t lenX = TCOBSEncode(enc, buf, len);
- #else
- #error configuration
- #endif
-
- size_t len4 = (lenX + 1 + 3) & ~3;
- memset(enc + lenX, 0, len4 - lenX);
- return lenX + 1;
- }
-
- #endif // #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_COBS) || (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_TCOBS)
-
- #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) || (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1)
-
- static void TriceWriteDeviceRtt0(const uint8_t *enc, size_t encLen)
- {
- #if TRICE_CGO == 1 // automated tests
- TriceWriteDeviceCgo(enc, encLen);
- #else // #if TRICE_CGO == 1
-
- #if TRICE_PROTECT == 1
- unsigned space = SEGGER_RTT_GetAvailWriteSpace(0);
- if (encLen <= space)
- {
- SEGGER_RTT_WriteNoLock(0, enc, encLen);
- }
- else
- {
- TriceDirectOverflowCount++;
- }
- #else // #if TRICE_PROTECT == 1
- SEGGER_RTT_WriteNoLock(0, enc, encLen);
- #endif // #else // #if TRICE_PROTECT == 1
-
- #endif // #else // #if TRICE_CGO == 1
-
- #if TRICE_DIAGNOSTICS == 1
- triceSeggerRTTDiagnostics(); // todo: maybe not needed
- #endif
- }
-
- #endif // #if (TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1) || (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1)
-
- static void TriceDirectWrite8(const uint8_t *enc, size_t encLen)
- {
- #if TRICE_DIRECT_SEGGER_RTT_8BIT_WRITE == 1
- TriceWriteDeviceRtt0(enc, encLen);
- #endif
-
- #if TRICE_DIRECT_AUXILIARY8
- TriceNonBlockingDirectWrite8Auxiliary(enc, encLen);
- #endif
- }
-
- #endif // #if TRICE_DIRECT8
-
- #if TRICE_DIRECT_OUTPUT == 1
-
- //! TriceNonBlockingDirectWrite copies a single trice from triceStart to output.
- //! This is the time critical part, executed inside TRICE_LEAVE.
- //! The trice data start at triceStart and include wordCount values with 1-3 padding bytes at the end.
- //! In front of triceStart are TRICE_DATA_OFFSET bytes space usable for optional in-buffer encoding. ??????? todo
- //! This is NOT the case, when using direct and deferred modes parallel, because for efficient RAM usage
- //! there is no gap between the Trices in double or ring buffer. Therefore, when enabling
- //! TRICE_DIRECT_SEGGER_RTT_32BIT_WRITE together with a deferred mode, for efficiency the RTT output can only be unframed.
- //! The space behind the trice (at triceStart + wordCount) is usable because in direct mode this is writable.
- //! Also in combined modes (direct plus deferred) this is allowed, under certain circumstances:
- //! - 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.
- //! - TRICE_RING_BUFFER: The max depth is not allowed and at the end is 4 bytes space needed.
- void TriceNonBlockingDirectWrite(uint32_t *triceStart, unsigned wordCount)
- {
- // The 16-bit stamped trices start with 2-times 16-bit ID for align and speed reasons.
- // The trice tool knows and expects that, when switch -packageFraming = NONE was applied.
- // 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.
- // That the TRICE_FRAMING_NONE does not remove the 2 additional bytes for 16-bit stamped trices has the
- // 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.
-
- // What happens here, is similar to TriceEncode but this is time critical code and we can do in-place encoding too.
-
- #if TRICE_DIRECT32_ONLY // Space at triceStart + wordCount is usable and we can destroy the data.
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
- triceStart[wordCount++] = 0; // clear padding space
- wordCount &= ~1; // only multiple of 8 can be encrypted
- XTEAEncrypt(triceStart, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
- #endif
-
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
- uint32_t *enc = triceStart;
- unsigned count = wordCount;
- #else
- static uint32_t enc[TRICE_BUFFER_SIZE >> 2]; // static buffer!
- unsigned count = directXEncode32(enc, triceStart, wordCount);
- #endif
-
- TriceDirectWrite32(enc, count);
- return;
-
- #elif TRICE_DIRECT8_ONLY // Space at triceStart + wordCount is usable and we can destroy the data.
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
- triceStart[wordCount++] = 0; // clear padding space
- wordCount &= ~1; // only multiple of 8 can be encrypted
- XTEAEncrypt(triceStart, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
- #endif
-
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
- uint8_t *enc = (uint8_t *)triceStart;
- unsigned len = wordCount << 2;
- #else
- static uint8_t enc[TRICE_BUFFER_SIZE]; // stack buffer!
- unsigned len = directXEncode8(enc, triceStart, wordCount << 2); // Up to 3 trailing zeroes are packed as well here.
- #endif
-
- TriceDirectWrite8(enc, len);
- return;
-
- #elif TRICE_DIRECT32_ALSO // Space at triceStart + wordCount is NOT usable and we can NOT destroy the data.
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1) || (TRICE_DIRECT_OUT_FRAMING != TRICE_FRAMING_NONE)
- static uint32_t enc[TRICE_BUFFER_SIZE >> 2]; // stack buffer!
- #endif
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
- uint32_t *dat = enc + (TRICE_DATA_OFFSET >> 2);
- memcpy(dat, triceStart, wordCount << 2); // Trice data are 32-bit aligned.
- dat[wordCount++] = 0; // clear padding space
- wordCount &= ~1; // only multiple of 8 can be encrypted
- XTEAEncrypt(dat, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
- #else
- uint32_t *dat = triceStart;
- #endif
-
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
- TriceDirectWrite32(dat, wordCount);
- #else
- unsigned count = directXEncode32(enc, dat, wordCount); // Up to 3 trailing zeroes are packed as well here.
- TriceDirectWrite32(enc, count);
- #endif
-
- return;
-
- #elif TRICE_DIRECT8_ALSO // Space at triceStart + wordCount is NOT usable and we can NOT destroy the data.
-
- #if TRICE_DIRECT_OUT_FRAMING != TRICE_FRAMING_NONE
- static uint32_t enc[TRICE_BUFFER_SIZE >> 2]; // stack buffer!
- #endif
-
- #if (TRICE_DIRECT_XTEA_ENCRYPT == 1)
- uint32_t *dat = enc + (TRICE_DATA_OFFSET >> 2);
- memcpy(dat, triceStart, wordCount << 2); // Trice data are 32-bit aligned.
- dat[wordCount++] = 0; // clear padding space
- wordCount &= ~1; // only multiple of 8 can be encrypted
- XTEAEncrypt(dat, wordCount); // in-buffer encryption (in direct-only mode is usable space bedind the Trice message.)
- #else
- uint32_t *dat = triceStart;
- #endif
-
- #if (TRICE_DIRECT_OUT_FRAMING == TRICE_FRAMING_NONE)
- TriceDirectWrite8((uint8_t *)dat, wordCount << 2);
- #else
- unsigned len = directXEncode8(enc, dat, wordCount << 2); // Up to 3 trailing zeroes are packed as well here.
- TriceDirectWrite8((uint8_t *)enc, len);
- #endif
-
- return;
-
- #else //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- #error configuration
- #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- }
-
- #endif // #if TRICE_DIRECT_OUTPUT == 1
-
- #if TRICE_DEFERRED_OUTPUT == 1
-
- // TriceNonBlockingDeferredWrite8 routes trice data to output channels.
- void TriceNonBlockingDeferredWrite8(int triceID, const uint8_t *enc, size_t encLen)
- {
- #if TRICE_DEFERRED_UARTA == 1
- #if (TRICE_UARTA_MIN_ID != 0) || (TRICE_UARTA_MAX_ID != 0)
- #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
- #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
- #endif
- if ((TRICE_UARTA_MIN_ID < triceID) && (triceID < TRICE_UARTA_MAX_ID))
- #else
- TRICE_UNUSED(triceID)
- #endif
- {
- TriceNonBlockingWriteUartA(enc, encLen);
- }
- #endif
-
- #if TRICE_DEFERRED_UARTB == 1
- #if (TRICE_UARTB_MIN_ID != 0) && (TRICE_UARTB_MAX_ID != 0)
- #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
- #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
- #endif
- if ((TRICE_UARTB_MIN_ID < triceID) && (triceID < TRICE_UARTB_MAX_ID))
- #else
- TRICE_UNUSED(triceID)
- #endif
- {
- TriceNonBlockingWriteUartB(enc, encLen);
- }
- #endif
-
- #if (TRICE_DEFERRED_AUXILIARY8 == 1)
- #if defined(TRICE_DEFERRED_AUXILIARY8_MIN_ID) && defined(TRICE_DEFERRED_AUXILIARY8_MAX_ID)
- #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
- #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
- #endif
- if ((TRICE_DEFERRED_AUXILIARY8_MIN_ID < triceID) && (triceID < TRICE_DEFERRED_AUXILIARY8_MAX_ID))
- #else
- TRICE_UNUSED(triceID)
- #endif
- {
- TriceNonBlockingDeferredWrite8Auxiliary(enc, encLen);
- }
- #endif
-
- #if (TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE == 1)
- #if defined(TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MIN_ID) && defined(TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MAX_ID)
- if ((TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MIN_ID < triceID) && (triceID < TRICE_DEFERRED_SEGGER_RTT_8BIT_WRITE_MAX_ID))
- #if TRICE_DEFERRED_TRANSFER_MODE == TRICE_MULTI_PACK_MODE
- #error configuration: TRICE_MULTI_PACK_MODE cannot support ID routing, consider TRICE_SINGLE_PACK_MODE
- #endif
- #else
- TRICE_UNUSED(triceID)
- #endif
- {
- TriceWriteDeviceRtt0(enc, encLen);
- }
- #endif
-
- // #if TRICE_LOG_OVER_MODBUS_FUNC24_ALSO == 1
- // #if defined(TRICE_MODBUS_MIN_ID) && defined(TRICE_MODBUS_MAX_ID)
- // if( (TRICE_MODBUS_MIN_ID < triceID) && (triceID < TRICE_MODBUS_MAX_ID) )
- // #else
- // TRICE_UNUSED(triceID)
- // #endif
- // TriceWriteDeviceModbus( enc, encLen );
- // #endif
- } // lint !e715 Info 715: Symbol 'triceID' not referenced
-
- #endif // #if TRICE_DEFERRED_OUTPUT == 1
-
- //! TriceOutDepth returns the amount of bytes not written yet from the slowest device.
- unsigned TriceOutDepth(void)
- {
- unsigned depth = 0;
- #if defined(SEGGER_RTT) || TRICE_DEFERRED_UARTA == 1 || TRICE_DEFERRED_UARTB == 1 || TRICE_CGO == 1
- unsigned d = 0;
- #endif
- TRICE_ENTER_CRITICAL_SECTION
-
- #ifdef SEGGER_RTT
- // When no RTT host is connected, the RTT buffer runs full.
- // If a RTT host is connected, it is assumed to be the fastest device.
- depth = d > depth ? d : depth;
- #endif
-
- #if TRICE_DEFERRED_UARTA == 1
- d = TriceOutDepthUartA(); // lint !e838
- depth = d > depth ? d : depth;
- #endif
-
- #if TRICE_DEFERRED_UARTB == 1
- d = TriceOutDepthUartB();
- depth = d > depth ? d : depth;
- #endif
-
- #if TRICE_CGO == 1 // automated tests
- d = TriceOutDepthCGO();
- depth = d > depth ? d : depth;
- #endif
-
- TRICE_LEAVE_CRITICAL_SECTION
- return depth;
- }
-
- #ifdef __GNUC__
- // https://stackoverflow.com/questions/5080848/disable-gcc-may-be-used-uninitialized-on-a-particular-variable
- #pragma GCC diagnostic push // save the actual diag context
- #ifndef __clang__
- #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // disable maybe warnings
- #endif
- #endif // #ifdef __GNUC__
- // now impacted section of code
-
- //! TRICE_ASSERT writes trice data as fast as possible in a buffer.
- //! \param tid is a 16 bit Trice id in upper 2 bytes of a 32 bit value
- //! This is a helper macro and should not be used in user code.
- #define TRICE_ASSERT(tid) \
- TRICE_ENTER tid; \
- TRICE_CNTC(0); \
- TRICE_LEAVE
-
- void triceAssertTrue(int idN, char *msg, int flag)
- {
- TRICE_UNUSED(msg)
- if (!flag)
- {
- TRICE_ASSERT(id(idN));
- }
- }
-
- void TriceAssertTrue(int idN, char *msg, int flag)
- {
- TRICE_UNUSED(msg)
- if (!flag)
- {
- TRICE_ASSERT(Id(idN));
- }
- }
-
- void TRiceAssertTrue(int idN, char *msg, int flag)
- {
- TRICE_UNUSED(msg)
- if (!flag)
- {
- TRICE_ASSERT(ID(idN));
- }
- }
-
- void triceAssertFalse(int idN, char *msg, int flag)
- {
- TRICE_UNUSED(msg)
- if (flag)
- {
- TRICE_ASSERT(id(idN));
- }
- }
-
- void TriceAssertFalse(int idN, char *msg, int flag)
- {
- TRICE_UNUSED(msg)
- if (flag)
- {
- TRICE_ASSERT(Id(idN));
- }
- }
-
- void TRiceAssertFalse(int idN, char *msg, int flag)
- {
- TRICE_UNUSED(msg)
- if (flag)
- {
- TRICE_ASSERT(ID(idN));
- }
- }
-
- #ifdef __GNUC__
- #pragma GCC diagnostic pop // restore previous diag context
- #endif // #ifdef __GNUC__
-
- #ifdef TRICE_N
-
- void triceN(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE_N(id(tid), fmt, buf, n);
- }
-
- void TriceN(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE_N(Id(tid), fmt, buf, n);
- }
-
- void TRiceN(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE_N(ID(tid), fmt, buf, n);
- }
-
- void trice8B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE8_B(id(tid), fmt, buf, n);
- }
-
- void Trice8B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE8_B(Id(tid), fmt, buf, n);
- }
-
- void TRice8B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE8_B(ID(tid), fmt, buf, n);
- }
-
- void trice16B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE16_B(id(tid), fmt, buf, n);
- }
-
- void Trice16B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE16_B(Id(tid), fmt, buf, n);
- }
-
- void TRice16B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE16_B(ID(tid), fmt, buf, n);
- }
-
- void trice32B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE32_B(id(tid), fmt, buf, n);
- }
-
- void Trice32B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE32_B(Id(tid), fmt, buf, n);
- }
-
- void TRice32B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE32_B(ID(tid), fmt, buf, n);
- }
-
- void trice64B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE64_B(id(tid), fmt, buf, n);
- }
-
- void Trice64B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE64_B(Id(tid), fmt, buf, n);
- }
-
- void TRice64B(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE64_B(ID(tid), fmt, buf, n);
- }
-
- void trice8F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE8_F(id(tid), fmt, buf, n);
- }
-
- void Trice8F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE8_F(Id(tid), fmt, buf, n);
- }
-
- void TRice8F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE8_F(ID(tid), fmt, buf, n);
- }
-
- void trice16F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE16_F(id(tid), fmt, buf, n);
- }
-
- void Trice16F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE16_F(Id(tid), fmt, buf, n);
- }
-
- void TRice16F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE16_F(ID(tid), fmt, buf, n);
- }
-
- void trice32F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE32_F(id(tid), fmt, buf, n);
- }
-
- void Trice32F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE32_F(Id(tid), fmt, buf, n);
- }
-
- void TRice32F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE32_F(ID(tid), fmt, buf, n);
- }
-
- void trice64F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE64_F(id(tid), fmt, buf, n);
- }
-
- void Trice64F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE64_F(Id(tid), fmt, buf, n);
- }
-
- void TRice64F(int tid, char *fmt, void *buf, uint32_t n)
- {
- TRICE64_F(ID(tid), fmt, buf, n);
- }
-
- #endif // #ifdef TRICE_N
-
- #ifdef TRICE_S
-
- void triceS(int tid, char *fmt, char *runtimeGeneratedString)
- {
- TRICE_S(id(tid), fmt, runtimeGeneratedString);
- }
-
- void TriceS(int tid, char *fmt, char *runtimeGeneratedString)
- {
- TRICE_S(Id(tid), fmt, runtimeGeneratedString);
- }
-
- void TRiceS(int tid, char *fmt, char *runtimeGeneratedString)
- {
- TRICE_S(ID(tid), fmt, runtimeGeneratedString);
- }
-
- #endif // #ifdef TRICE_N
-
- #endif // #if !TRICE_OFF
|