1 /*********************************************************************
2 *                    SEGGER Microcontroller GmbH                     *
3 *                        The Embedded Experts                        *
4 **********************************************************************
5 *                                                                    *
6 *            (c) 1995 - 2024 SEGGER Microcontroller GmbH             *
7 *                                                                    *
8 *       www.segger.com     Support: support@segger.com               *
9 *                                                                    *
10 **********************************************************************
11 *                                                                    *
12 *       SEGGER SystemView * Real-time application analysis           *
13 *                                                                    *
14 **********************************************************************
15 *                                                                    *
16 * All rights reserved.                                               *
17 *                                                                    *
18 * SEGGER strongly recommends to not make any changes                 *
19 * to or modify the source code of this software in order to stay     *
20 * compatible with the SystemView and RTT protocol, and J-Link.       *
21 *                                                                    *
22 * Redistribution and use in source and binary forms, with or         *
23 * without modification, are permitted provided that the following    *
24 * condition is met:                                                  *
25 *                                                                    *
26 * o Redistributions of source code must retain the above copyright   *
27 *   notice, this condition and the following disclaimer.             *
28 *                                                                    *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
33 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
34 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
36 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
37 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
38 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
40 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
41 * DAMAGE.                                                            *
42 *                                                                    *
43 **********************************************************************
44 *                                                                    *
45 *       SystemView version: 3.58                                    *
46 *                                                                    *
47 **********************************************************************
48 -------------------------- END-OF-HEADER -----------------------------
49 
50 File    : SEGGER_SYSVIEW.c
51 Purpose : System visualization API implementation.
52 Revision: $Rev: 29105 $
53 
54 Additional information:
55   Packet format:
56     Packets with IDs 0..23 are standard packets with known structure.
57     For efficiency, they do *NOT* contain a length field.
58     <ID><Data><TimeStampDelta>
59 
60     Packets with IDs 24..31 are standard packets with extendible
61     structure and contain a length field.
62     <ID><Lenght><Data><TimeStampDelta>
63 
64     Packet ID 31 is used for SystemView extended events.
65     <ID><Lenght><ID_EX><Data><TimeStampDelta>
66 
67     Packets with IDs >= 32 always contain a length field.
68     <ID><Length><Data><TimeStampDelta>
69 
70   Packet IDs:
71        0..  31 : Standard packets, known by SystemView.
72       32..1023 : OS-definable packets, described in a SystemView description file.
73     1024..2047 : User-definable packets, described in a SystemView description file.
74     2048..32767: Undefined.
75 
76   Data encoding:
77     Basic types (int, short, char, ...):
78       Basic types are encoded little endian with most-significant bit variant
79       encoding.
80       Each encoded byte contains 7 data bits [6:0] and the MSB continuation bit.
81       The continuation bit indicates whether the next byte belongs to the data
82       (bit set) or this is the last byte (bit clear).
83       The most significant bits of data are encoded first, proceeding to the
84       least significant bits in the final byte (little endian).
85 
86       Example encoding:
87         Data: 0x1F4 (500)
88         Encoded: 0xF4 (First 7 data bits 74 | Continuation bit)
89                  0x03 (Second 7 data bits 03, no continuation)
90 
91         Data: 0xFFFFFFFF
92         Encoded: 0xFF 0xFF 0xFF 0xFF 0x0F
93 
94         Data: 0xA2 (162),   0x03 (3), 0x7000
95         Encoded: 0xA2 0x01  0x03      0x80 0xE0 0x01
96 
97     Byte arrays and strings:
98       Byte arrays and strings are encoded as <NumBytes> followed by the raw data.
99       NumBytes is encoded as a basic type with a theoretical maximum of 4G.
100 
101       Example encoding:
102         Data: "Hello World\0" (0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64 0x00)
103         Encoded: 0x0B 0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64
104 
105   Examples packets:
106   01 F4 03 80 80 10 // Overflow packet. Data is a single U32.
107                        This packet means: 500 packets lost, Timestamp is 0x40000
108 
109   02 0F 50          // ISR(15) Enter. Timestamp 80 (0x50)
110 
111   03 20             // ISR Exit. Timestamp 32 (0x20) (Shortest possible packet.)
112 
113   Sample code for user defined Packets:
114     #define MY_ID   0x400                // Any value between 0x400 and 0x7FF
115     void SendMyPacket(unsigned Para0, unsigned Para1, const char* s) {
116       U8  aPacket[SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + MAX_STR_LEN + 1];
117       U8* pPayload;
118       //
119       pPayload = SEGGER_SYSVIEW_PPREPARE_PACKET(aPacket);               // Prepare the packet for SystemView
120       pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0);             // Add the first parameter to the packet
121       pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1);             // Add the second parameter to the packet
122       pPayload = SEGGER_SYSVIEW_EncodeString(pPayload, s, MAX_STR_LEN); // Add the string to the packet
123       //
124       SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, MY_ID);          // Send the packet with EventId = MY_ID
125     }
126 
127     #define MY_ID_1 0x401
128     void SendOnePara(unsigned Para0) {
129       SEGGER_SYSVIEW_RecordU32(MY_ID_1, Para0);
130     }
131 
132 */
133 
134 /*********************************************************************
135 *
136 *       #include section
137 *
138 **********************************************************************
139 */
140 
141 #define SEGGER_SYSVIEW_C  // For EXTERN statements in SEGGER_SYSVIEW.h
142 
143 #include <string.h>
144 #include <stdlib.h>
145 #include <stdarg.h>
146 #include "SEGGER_SYSVIEW_Int.h"
147 #include "SEGGER_RTT.h"
148 
149 /*********************************************************************
150 *
151 *       Defines, fixed
152 *
153 **********************************************************************
154 */
155 #if SEGGER_SYSVIEW_ID_SHIFT
156   #define SHRINK_ID(Id)   (((Id) - _SYSVIEW_Globals.RAMBaseAddress) >> SEGGER_SYSVIEW_ID_SHIFT)
157 #else
158   #define SHRINK_ID(Id)   ((Id) - _SYSVIEW_Globals.RAMBaseAddress)
159 #endif
160 
161 #if SEGGER_SYSVIEW_RTT_CHANNEL > 0
162   #define CHANNEL_ID_UP   SEGGER_SYSVIEW_RTT_CHANNEL
163   #define CHANNEL_ID_DOWN SEGGER_SYSVIEW_RTT_CHANNEL
164 #else
165   #define CHANNEL_ID_UP   _SYSVIEW_Globals.UpChannel
166   #define CHANNEL_ID_DOWN _SYSVIEW_Globals.DownChannel
167 #endif
168 
169 #if SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE
170   #if (SEGGER_SYSVIEW_RTT_BUFFER_SIZE % SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE)
171     #error "SEGGER_SYSVIEW_RTT_BUFFER_SIZE must be a multiple of SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE"
172   #endif
173 #endif
174 
175 /*********************************************************************
176 *
177 *       Defines, configurable
178 *
179 **********************************************************************
180 */
181 // Timestamps may be less than full 32-bits, in which case we need to zero
182 // the unused bits to properly handle overflows.
183 // Note that this is a quite common scenario, as a 32-bit time such as
184 // SysTick might be scaled down to reduce bandwith
185 // or a 16-bit hardware time might be used.
186 #if SEGGER_SYSVIEW_TIMESTAMP_BITS < 32  // Eliminate unused bits in case hardware timestamps are less than 32 bits
187   #define MAKE_DELTA_32BIT(Delta) Delta <<= 32 - SEGGER_SYSVIEW_TIMESTAMP_BITS; \
188                                   Delta >>= 32 - SEGGER_SYSVIEW_TIMESTAMP_BITS;
189 #else
190   #define MAKE_DELTA_32BIT(Delta)
191 #endif
192 
193 #if SEGGER_SYSVIEW_SUPPORT_LONG_ID
194   #define _MAX_ID_BYTES       5u
195 #else
196   #define _MAX_ID_BYTES       2u
197 #endif
198 
199 #if SEGGER_SYSVIEW_SUPPORT_LONG_DATA
200   #define _MAX_DATA_BYTES     5u
201 #else
202   #define _MAX_DATA_BYTES     2u
203 #endif
204 
205 /*********************************************************************
206 *
207 *       Defines, fixed
208 *
209 **********************************************************************
210 */
211 #define ENABLE_STATE_OFF        0
212 #define ENABLE_STATE_ON         1
213 #define ENABLE_STATE_DROPPING   2
214 
215 #define FORMAT_FLAG_LEFT_JUSTIFY   (1u << 0)
216 #define FORMAT_FLAG_PAD_ZERO       (1u << 1)
217 #define FORMAT_FLAG_PRINT_SIGN     (1u << 2)
218 #define FORMAT_FLAG_ALTERNATE      (1u << 3)
219 
220 #define MODULE_EVENT_OFFSET        (512)
221 
222 /*********************************************************************
223 *
224 *       Types, local
225 *
226 **********************************************************************
227 */
228 typedef struct {
229   U8*       pBuffer;
230   U8*       pPayload;
231   U8*       pPayloadStart;
232   U32       Options;
233   unsigned  Cnt;
234 } SEGGER_SYSVIEW_PRINTF_DESC;
235 
236 typedef struct {
237         U8                      EnableState;   // 0: Disabled, 1: Enabled, (2: Dropping)
238         U8                      UpChannel;
239         U8                      RecursionCnt;
240         U32                     SysFreq;
241         U32                     CPUFreq;
242         U32                     LastTxTimeStamp;
243         U32                     RAMBaseAddress;
244 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
245         U32                     PacketCount;
246 #else
247         U32                     DropCount;
248         U8                      DownChannel;
249 #endif
250         U32                     DisabledEvents;
251   const SEGGER_SYSVIEW_OS_API*  pOSAPI;
252         SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC*   pfSendSysDesc;
253 } SEGGER_SYSVIEW_GLOBALS;
254 
255 /*********************************************************************
256 *
257 *       Function prototypes, required
258 *
259 **********************************************************************
260 */
261 static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId);
262 
263 /*********************************************************************
264 *
265 *       Static data
266 *
267 **********************************************************************
268 */
269 static const U8 _abSync[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
270 
271 #if SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE
272   #ifdef SEGGER_SYSVIEW_SECTION
273     //
274     // Alignment + special section required
275     //
276     #if (defined __GNUC__)
277       __attribute__ ((section (SEGGER_SYSVIEW_SECTION), aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE))) static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
278       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
279         __attribute__ ((section (SEGGER_SYSVIEW_SECTION), aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE))) static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
280       #endif
281     #elif (defined __ICCARM__) || (defined __ICCRX__)
282       #pragma location=SEGGER_SYSVIEW_SECTION
283       #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
284       static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
285       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
286         #pragma location=SEGGER_SYSVIEW_SECTION
287         #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
288         static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
289       #endif
290     #elif (defined __CC_ARM)
291       __attribute__ ((section (SEGGER_SYSVIEW_SECTION), aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE), zero_init)) static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
292       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
293         __attribute__ ((section (SEGGER_SYSVIEW_SECTION), aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE), zero_init)) static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
294       #endif
295     #else
296       #error "Do not know how to place SystemView buffers in specific section"
297     #endif
298   #else
299     //
300     // Only alignment required
301     //
302     #if (defined __GNUC__)
303       __attribute__ ((aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE))) static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
304       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
305         __attribute__ ((aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE))) static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
306       #endif
307     #elif (defined __ICCARM__) || (defined __ICCRX__)
308       #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
309       static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
310       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
311         #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
312         static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
313       #endif
314     #elif (defined __CC_ARM)
315       __attribute__ ((aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE), zero_init)) static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
316       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
317         __attribute__ ((aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE), zero_init)) static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
318       #endif
319     #else
320       #error "Do not know how to align SystemView buffers to cache line size"
321     #endif
322   #endif
323 #else
324   #ifdef SEGGER_SYSVIEW_SECTION
325     //
326     // Only special section required
327     //
328     #if (defined __GNUC__)
329       __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
330       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
331         __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
332       #endif
333     #elif (defined __ICCARM__) || (defined __ICCRX__)
334       #pragma location=SEGGER_SYSVIEW_SECTION
335       static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
336       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
337         #pragma location=SEGGER_SYSVIEW_SECTION
338         static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
339       #endif
340     #elif (defined __CC_ARM)
341       __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
342       #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
343         __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
344       #endif
345     #else
346       #error "Do not know how to place SystemView buffers in specific section"
347     #endif
348   #else
349     //
350     // Neither special section nor alignment required
351     //
352     static char _UpBuffer  [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
353     #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
354       static char _DownBuffer[8];  // Small, fixed-size buffer, for back-channel comms
355     #endif
356   #endif
357 #endif
358 
359 static SEGGER_SYSVIEW_GLOBALS _SYSVIEW_Globals;
360 
361 static SEGGER_SYSVIEW_MODULE* _pFirstModule;
362 static U8                     _NumModules;
363 
364 /*********************************************************************
365 *
366 *       Static code
367 *
368 **********************************************************************
369 */
370 
371 #define ENCODE_U32(pDest, Value) {                                                  \
372                                    U8* pSysviewPointer;                             \
373                                    U32 SysViewData;                                 \
374                                    pSysviewPointer = pDest;                         \
375                                    SysViewData = (U32)Value;                        \
376                                    while(SysViewData > 0x7F) {                      \
377                                      *pSysviewPointer++ = (U8)(SysViewData | 0x80); \
378                                      SysViewData >>= 7;                             \
379                                    };                                               \
380                                    *pSysviewPointer++ = (U8)SysViewData;            \
381                                    pDest = pSysviewPointer;                         \
382                                  };
383 
384 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
385 static U8 _aPacket[SEGGER_SYSVIEW_MAX_PACKET_SIZE];
386 
387 #define RECORD_START(PacketSize)  SEGGER_SYSVIEW_LOCK();                            \
388                                   pPayloadStart = _PreparePacket(_aPacket);
389 
390 #define RECORD_END()              SEGGER_SYSVIEW_UNLOCK()
391 
392 #else
393 
394 #define RECORD_START(PacketSize)  U8 aPacket[(PacketSize)];                         \
395                                   pPayloadStart = _PreparePacket(aPacket);          \
396 
397 #define RECORD_END()
398 
399 #endif
400 
401 /*********************************************************************
402 *
403 *       _EncodeData()
404 *
405 *  Function description
406 *    Encode a byte buffer in variable-length format.
407 *
408 *  Parameters
409 *    pPayload - Pointer to where string will be encoded.
410 *    pSrc     - Pointer to data buffer to be encoded.
411 *    NumBytes - Number of bytes in the buffer to be encoded.
412 *
413 *  Return value
414 *    Pointer to the byte following the value, i.e. the first free
415 *    byte in the payload and the next position to store payload
416 *    content.
417 *
418 *  Additional information
419 *    The data is encoded as a count byte followed by the contents
420 *    of the data buffer.
421 *    Make sure NumBytes + 1 bytes are free for the payload.
422 */
_EncodeData(U8 * pPayload,const char * pSrc,unsigned int NumBytes)423 static U8* _EncodeData(U8* pPayload, const char* pSrc, unsigned int NumBytes) {
424   unsigned int  n;
425   const U8*     p;
426   //
427   n = 0;
428   p = (const U8*)pSrc;
429   //
430   // Write Len
431   //
432   if (NumBytes < 255)  {
433     *pPayload++ = (U8)NumBytes;
434   } else {
435     *pPayload++ = 255;
436     *pPayload++ = ((NumBytes >> 8) & 255);
437     *pPayload++ = (NumBytes & 255);
438   }
439   while (n < NumBytes) {
440     *pPayload++ = *p++;
441     n++;
442   }
443   return pPayload;
444 }
445 
446 /*********************************************************************
447 *
448 *       _EncodeFloat()
449 *
450 *  Function description
451 *    Encode a float value in variable-length format.
452 *
453 *  Parameters
454 *    pPayload - Pointer to where value will be encoded.
455 *    Value    - Value to be encoded.
456 *
457 *  Return value
458 *    Pointer to the byte following the value, i.e. the first free
459 *    byte in the payload and the next position to store payload
460 *    content.
461 */
_EncodeFloat(U8 * pPayload,float Value)462 static U8* _EncodeFloat(U8* pPayload, float Value) {
463   float  Val;
464   U8*    pSysviewPointer;
465   U32*   SysViewData;
466 
467   Val = Value;
468   pSysviewPointer = pPayload;
469   SysViewData = (U32*)&Val;
470   while((*SysViewData) > 0x7F) {
471     *pSysviewPointer++ = (U8)((*SysViewData) | 0x80);
472     (*SysViewData) >>= 7;
473   }
474   *pSysviewPointer++ = (U8)(*SysViewData);
475   pPayload = pSysviewPointer;
476 
477   return pPayload;
478 }
479 
480 /*********************************************************************
481 *
482 *       _EncodeStr()
483 *
484 *  Function description
485 *    Encode a string in variable-length format.
486 *
487 *  Parameters
488 *    pPayload - Pointer to where string will be encoded.
489 *    pText    - String to encode.
490 *    Limit    - Maximum number of characters to encode from string.
491 *
492 *  Return value
493 *    Pointer to the byte following the value, i.e. the first free
494 *    byte in the payload and the next position to store payload
495 *    content.
496 *
497 *  Additional information
498 *    The string is encoded as a count byte followed by the contents
499 *    of the string.
500 *    No more than 1 + Limit bytes will be encoded to the payload.
501 */
_EncodeStr(U8 * pPayload,const char * pText,unsigned int Limit)502 static U8 *_EncodeStr(U8 *pPayload, const char *pText, unsigned int Limit) {
503   U8* pLen;
504   const char* sStart;
505 
506   if (pText == NULL) {
507     *pPayload++ = (U8)0;
508   } else {
509     sStart = pText; // Remember start of string.
510     //
511     // Save space to store count byte(s).
512     //
513     pLen = pPayload++;
514 #if (SEGGER_SYSVIEW_MAX_STRING_LEN >= 255)  // Length always encodes in 3 bytes
515     pPayload += 2;
516 #endif
517     //
518     // Limit string to maximum length and copy into payload buffer.
519     //
520     if (Limit > SEGGER_SYSVIEW_MAX_STRING_LEN) {
521       Limit = SEGGER_SYSVIEW_MAX_STRING_LEN;
522     }
523     while ((Limit-- > 0) && (*pText != '\0')) {
524       *pPayload++ = *pText++;
525     }
526     //
527     // Save string length to buffer.
528     //
529 #if (SEGGER_SYSVIEW_MAX_STRING_LEN >= 255)  // Length always encodes in 3 bytes
530     Limit = (unsigned int)(pText - sStart);
531     *pLen++ = (U8)255;
532     *pLen++ = (U8)((Limit >> 8) & 255);
533     *pLen++ = (U8)(Limit & 255);
534 #else   // Length always encodes in 1 byte
535     *pLen = (U8)(pText - sStart);
536 #endif
537   }
538   //
539   return pPayload;
540 }
541 
542 /*********************************************************************
543 *
544 *       _PreparePacket()
545 *
546 *  Function description
547 *    Prepare a SystemView event packet header.
548 *
549 *  Parameters
550 *    pPacket - Pointer to start of packet to initialize.
551 *
552 *  Return value
553 *    Pointer to first byte of packet payload.
554 *
555 *  Additional information
556 *    The payload length and evnetId are not initialized.
557 *    PreparePacket only reserves space for them and they are
558 *    computed and filled in by the sending function.
559 */
_PreparePacket(U8 * pPacket)560 static U8* _PreparePacket(U8* pPacket) {
561   return pPacket + _MAX_ID_BYTES + _MAX_DATA_BYTES;
562 }
563 
564 /*********************************************************************
565 *
566 *       _HandleIncomingPacket()
567 *
568 *  Function description
569 *    Read an incoming command from the down channel and process it.
570 *
571 *  Additional information
572 *    This function is called each time after sending a packet.
573 *    Processing incoming packets is done asynchronous. SystemView might
574 *    already have sent event packets after the host has sent a command.
575 */
576 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
_HandleIncomingPacket(void)577 static void _HandleIncomingPacket(void) {
578   U8  Cmd;
579   unsigned int Status;
580   //
581   Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
582   if (Status > 0) {
583     switch (Cmd) {
584     case SEGGER_SYSVIEW_COMMAND_ID_START:
585       SEGGER_SYSVIEW_Start();
586       break;
587     case SEGGER_SYSVIEW_COMMAND_ID_STOP:
588       SEGGER_SYSVIEW_Stop();
589       break;
590     case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME:
591       SEGGER_SYSVIEW_RecordSystime();
592       break;
593     case SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST:
594       SEGGER_SYSVIEW_SendTaskList();
595       break;
596     case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC:
597       SEGGER_SYSVIEW_GetSysDesc();
598       break;
599     case SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES:
600       SEGGER_SYSVIEW_SendNumModules();
601       break;
602     case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC:
603       SEGGER_SYSVIEW_SendModuleDescription();
604       break;
605     case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE:
606       Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
607       if (Status > 0) {
608         SEGGER_SYSVIEW_SendModule(Cmd);
609       }
610       break;
611     case SEGGER_SYSVIEW_COMMAND_ID_HEARTBEAT:
612       break;
613     default:
614       if (Cmd >= 128) { // Unknown extended command. Dummy read its parameter.
615         SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
616       }
617       break;
618     }
619   }
620 }
621 #endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
622 
623 /*********************************************************************
624 *
625 *       _TrySendOverflowPacket()
626 *
627 *  Function description
628 *    Try to transmit an SystemView Overflow packet containing the
629 *    number of dropped packets.
630 *
631 *  Additional information
632 *    Format as follows:
633 *      01 <DropCnt><TimeStamp>  Max. packet len is 1 + 5 + 5 = 11
634 *
635 *    Example packets sent
636 *      01 20 40
637 *
638 *  Return value
639 *    !=0:  Success, Message sent (stored in RTT-Buffer)
640 *    ==0:  Buffer full, Message *NOT* stored
641 *
642 */
643 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
_TrySendOverflowPacket(void)644 static int _TrySendOverflowPacket(void) {
645   U32 TimeStamp;
646   I32 Delta;
647   int Status;
648   U8  aPacket[11];
649   U8* pPayload;
650 
651   aPacket[0] = SYSVIEW_EVTID_OVERFLOW;      // 1
652   pPayload   = &aPacket[1];
653   ENCODE_U32(pPayload, _SYSVIEW_Globals.DropCount);
654   //
655   // Compute time stamp delta and append it to packet.
656   //
657   TimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
658   Delta = (I32)(TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp);
659   MAKE_DELTA_32BIT(Delta);
660   ENCODE_U32(pPayload, Delta);
661   //
662   // Try to store packet in RTT buffer and update time stamp when this was successful
663   //
664   Status = (int)SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, aPacket, (unsigned int)(pPayload - aPacket));
665   SEGGER_SYSVIEW_ON_EVENT_RECORDED(pPayload - aPacket);
666   if (Status) {
667     _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
668     _SYSVIEW_Globals.EnableState--; // EnableState has been 2, will be 1. Always.
669   } else {
670     _SYSVIEW_Globals.DropCount++;
671   }
672   //
673   return Status;
674 }
675 #endif  // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
676 
677 /*********************************************************************
678 *
679 *       _SendSyncInfo()
680 *
681 *  Function description
682 *    Send SystemView sync packet and system information in
683 *    post mortem mode.
684 *
685 *  Additional information
686 *    Sync is 10 * 0x00 without timestamp
687 */
688 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
_SendSyncInfo(void)689 static void _SendSyncInfo(void) {
690   //
691   // Add sync packet ( 10 * 0x00)
692   // Send system description
693   // Send system time
694   // Send task list
695   // Send module description
696   // Send module information
697   //
698   SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, _abSync, 10);
699   SEGGER_SYSVIEW_ON_EVENT_RECORDED(10);
700   SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
701   {
702     U8* pPayload;
703     U8* pPayloadStart;
704     RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
705     //
706     pPayload = pPayloadStart;
707     ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
708     ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
709     ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
710     ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
711     _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
712     RECORD_END();
713   }
714   if (_SYSVIEW_Globals.pfSendSysDesc) {
715     _SYSVIEW_Globals.pfSendSysDesc();
716   }
717   SEGGER_SYSVIEW_RecordSystime();
718   SEGGER_SYSVIEW_SendTaskList();
719   if (_NumModules > 0) {
720     int n;
721     SEGGER_SYSVIEW_SendNumModules();
722     for (n = 0; n < _NumModules; n++) {
723       SEGGER_SYSVIEW_SendModule(n);
724     }
725   }
726 }
727 #endif  // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
728 
729 /*********************************************************************
730 *
731 *       _SendPacket()
732 *
733 *  Function description
734 *    Send a SystemView packet over RTT. RTT channel and mode are
735 *    configured by macros when the SystemView component is initialized.
736 *    This function takes care of maintaining the packet drop count
737 *    and sending overflow packets when necessary.
738 *    The packet must be passed without Id and Length because this
739 *    function prepends it to the packet before transmission.
740 *
741 *  Parameters
742 *    pStartPacket - Pointer to start of packet payload.
743 *                   There must be at least 4 bytes free to prepend Id and Length.
744 *    pEndPacket   - Pointer to end of packet payload.
745 *    EventId      - Id of the event to send.
746 *
747 */
_SendPacket(U8 * pStartPacket,U8 * pEndPacket,unsigned int EventId)748 static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId) {
749   unsigned int  NumBytes;
750   U32           TimeStamp;
751   U32           Delta;
752 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
753   unsigned int  Status;
754 #endif
755 
756 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
757   SEGGER_SYSVIEW_LOCK();
758 #endif
759 
760 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
761   if (_SYSVIEW_Globals.EnableState == 0) {
762     goto SendDone;
763   }
764 #else
765   if (_SYSVIEW_Globals.EnableState == 1) {  // Enabled, no dropped packets remaining
766     goto Send;
767   }
768   if (_SYSVIEW_Globals.EnableState == 0) {
769     goto SendDone;
770   }
771   //
772   // Handle buffer full situations:
773   // Have packets been dropped before because buffer was full?
774   // In this case try to send and overflow packet.
775   //
776   if (_SYSVIEW_Globals.EnableState == 2) {
777     _TrySendOverflowPacket();
778     if (_SYSVIEW_Globals.EnableState != 1) {
779       goto SendDone;
780     }
781   }
782 Send:
783 #endif
784   //
785   // Check if event is disabled from being recorded.
786   //
787   if (EventId < 32) {
788     if (_SYSVIEW_Globals.DisabledEvents & ((U32)1u << EventId)) {
789       goto SendDone;
790     }
791   }
792   //
793   // Prepare actual packet.
794   // If it is a known packet, prepend eventId only,
795   // otherwise prepend packet length and eventId.
796   //
797   if (EventId < 24) {
798     *--pStartPacket = (U8)EventId;
799   } else {
800     //
801     // Get data length and prepend it.
802     //
803     NumBytes = (unsigned int)(pEndPacket - pStartPacket);
804 #if SEGGER_SYSVIEW_SUPPORT_LONG_DATA
805     if (NumBytes < 127) {
806       *--pStartPacket = EventId;
807     } else {
808       //
809       // Backwards U32 encode EventId.
810       //
811       if (NumBytes < (1ul << 14)) { // Encodes in 2 bytes
812         *--pStartPacket = (U8)(NumBytes >>  7);
813         *--pStartPacket = (U8)(NumBytes | 0x80);
814       } else if (NumBytes < (1ul << 21)) {    // Encodes in 3 bytes
815         *--pStartPacket = (U8)(NumBytes >> 14);
816         *--pStartPacket = (U8)((NumBytes >>  7) | 0x80);
817         *--pStartPacket = (U8)(NumBytes | 0x80);
818       } else if (NumBytes < (1ul << 28)) {    // Encodes in 4 bytes
819         *--pStartPacket = (U8)(NumBytes >> 21);
820         *--pStartPacket = (U8)((NumBytes >> 14) | 0x80);
821         *--pStartPacket = (U8)((NumBytes >>  7) | 0x80);
822         *--pStartPacket = (U8)(NumBytes | 0x80);
823       } else {                              // Encodes in 5 bytes
824         *--pStartPacket = (U8)(NumBytes >> 28);
825         *--pStartPacket = (U8)((NumBytes >> 21) | 0x80);
826         *--pStartPacket = (U8)((NumBytes >> 14) | 0x80);
827         *--pStartPacket = (U8)((NumBytes >>  7) | 0x80);
828         *--pStartPacket = (U8)(NumBytes | 0x80);
829       }
830     }
831 #else
832     if (NumBytes > 127) {
833       *--pStartPacket = (U8)(NumBytes >> 7);
834       *--pStartPacket = (U8)(NumBytes | 0x80);
835     } else {
836       *--pStartPacket = (U8)NumBytes;
837     }
838 #endif
839     //
840     // Prepend EventId.
841     //
842 #if SEGGER_SYSVIEW_SUPPORT_LONG_ID
843     if (EventId < 127) {
844       *--pStartPacket = (U8)EventId;
845     } else {
846       //
847       // Backwards U32 encode EventId.
848       //
849       if (EventId < (1u << 14)) { // Encodes in 2 bytes
850         *--pStartPacket = (U8)(EventId >>  7);
851         *--pStartPacket = (U8)(EventId | 0x80);
852       } else if (EventId < (1ul << 21)) {    // Encodes in 3 bytes
853         *--pStartPacket = (U8)(EventId >> 14);
854         *--pStartPacket = (U8)((EventId >>  7) | 0x80);
855         *--pStartPacket = (U8)(EventId | 0x80);
856       } else if (EventId < (1ul << 28)) {    // Encodes in 4 bytes
857         *--pStartPacket = (U8)(EventId >> 21);
858         *--pStartPacket = (U8)((EventId >> 14) | 0x80);
859         *--pStartPacket = (U8)((EventId >>  7) | 0x80);
860         *--pStartPacket = (U8)(EventId | 0x80);
861       } else {                              // Encodes in 5 bytes
862         *--pStartPacket = (U8)(EventId >> 28);
863         *--pStartPacket = (U8)((EventId >> 21) | 0x80);
864         *--pStartPacket = (U8)((EventId >> 14) | 0x80);
865         *--pStartPacket = (U8)((EventId >>  7) | 0x80);
866         *--pStartPacket = (U8)(EventId | 0x80);
867       }
868     }
869 #else
870     if (EventId > 127) {
871       *--pStartPacket = (U8)(EventId >> 7);
872       *--pStartPacket = (U8)(EventId | 0x80);
873     } else {
874       *--pStartPacket = (U8)EventId;
875     }
876 #endif
877   }
878   //
879   // Compute time stamp delta and append it to packet.
880   //
881   TimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
882   Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp;
883   MAKE_DELTA_32BIT(Delta);
884   ENCODE_U32(pEndPacket, Delta);
885 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
886   //
887   // Store packet in RTT buffer by overwriting old data and update time stamp
888   //
889   SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, pStartPacket, pEndPacket - pStartPacket);
890   SEGGER_SYSVIEW_ON_EVENT_RECORDED(pEndPacket - pStartPacket);
891   _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
892 #else
893   //
894   // Try to store packet in RTT buffer and update time stamp when this was successful
895   //
896   Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, pStartPacket, (unsigned int)(pEndPacket - pStartPacket));
897   SEGGER_SYSVIEW_ON_EVENT_RECORDED(pEndPacket - pStartPacket);
898   if (Status) {
899     _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
900   } else {
901     _SYSVIEW_Globals.EnableState++; // EnableState has been 1, will be 2. Always.
902   }
903 #endif
904 
905 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
906   //
907   // Add sync and system information periodically if we are in post mortem mode
908   //
909   if (_SYSVIEW_Globals.RecursionCnt == 0) {   // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
910     _SYSVIEW_Globals.RecursionCnt = 1;
911     if (_SYSVIEW_Globals.PacketCount++ & (1 << SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT)) {
912       _SendSyncInfo();
913       _SYSVIEW_Globals.PacketCount = 0;
914     }
915     _SYSVIEW_Globals.RecursionCnt = 0;
916   }
917 SendDone:
918   ; // Avoid "label at end of compound statement" error when using static buffer
919 #else
920 SendDone:
921   //
922   // Check if host is sending data which needs to be processed.
923   // Note that since this code is called for every packet, it is very time critical, so we do
924   // only what is really needed here, which is checking if there is any data
925   //
926   if (SEGGER_RTT_HASDATA(CHANNEL_ID_DOWN)) {
927     if (_SYSVIEW_Globals.RecursionCnt == 0) {   // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
928       _SYSVIEW_Globals.RecursionCnt = 1;
929       _HandleIncomingPacket();
930       _SYSVIEW_Globals.RecursionCnt = 0;
931     }
932   }
933 #endif
934   //
935 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
936   SEGGER_SYSVIEW_UNLOCK();  // We are done. Unlock and return
937 #endif
938 }
939 
940 #ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
941 /*********************************************************************
942 *
943 *       _VPrintHost()
944 *
945 *  Function description
946 *    Send a format string and its parameters to the host.
947 *
948 *  Parameters
949 *    s            Pointer to format string.
950 *    Options      Options to be sent to the host.
951 *    pParamList   Pointer to the list of arguments for the format string.
952 */
_VPrintHost(const char * s,U32 Options,va_list * pParamList)953 static int _VPrintHost(const char* s, U32 Options, va_list* pParamList) {
954   U32         aParas[SEGGER_SYSVIEW_MAX_ARGUMENTS];
955   U32*        pParas;
956   U32         NumArguments;
957   const char* p;
958   char        c;
959   U8*         pPayload;
960   U8*         pPayloadStart;
961 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
962   U8 HasNonScalar;
963 
964   HasNonScalar = 0;
965 #endif
966   //
967   // Count number of arguments by counting '%' characters in string.
968   // If enabled, check for non-scalar modifier flags to format string on the target.
969   //
970   p = s;
971   NumArguments = 0;
972   for (;;) {
973     c = *p++;
974     if (c == 0) {
975       break;
976     }
977     if (c == '%') {
978       c = *p;
979 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT == 0
980       aParas[NumArguments++] = (U32)(va_arg(*pParamList, int));
981       if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) {
982         break;
983       }
984 #else
985       if (c == 's') {
986         HasNonScalar = 1;
987         break;
988       } else {
989         aParas[NumArguments++] = (U32)(va_arg(*pParamList, int));
990         if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) {
991           break;
992         }
993       }
994 #endif
995     }
996   }
997 
998 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
999   if (HasNonScalar) {
1000     return -1;
1001   }
1002 #endif
1003   //
1004   // Send string and parameters to host
1005   //
1006   {
1007     RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32);
1008     pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
1009     ENCODE_U32(pPayload, Options);
1010     ENCODE_U32(pPayload, NumArguments);
1011     pParas = aParas;
1012     while (NumArguments--) {
1013       ENCODE_U32(pPayload, (*pParas));
1014       pParas++;
1015     }
1016     _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
1017     RECORD_END();
1018   }
1019   return 0;
1020 }
1021 
1022 /*********************************************************************
1023 *
1024 *       _StoreChar()
1025 *
1026 *  Function description
1027 *    Stores a character in the printf-buffer and sends the buffer when
1028 *     it is filled.
1029 *
1030 *  Parameters
1031 *    p            Pointer to the buffer description.
1032 *    c            Character to be printed.
1033 */
_StoreChar(SEGGER_SYSVIEW_PRINTF_DESC * p,char c)1034 static void _StoreChar(SEGGER_SYSVIEW_PRINTF_DESC * p, char c) {
1035   unsigned int  Cnt;
1036   U8*           pPayload;
1037   U32           Options;
1038 
1039   Cnt = p->Cnt;
1040   if ((Cnt + 1u) <= SEGGER_SYSVIEW_MAX_STRING_LEN) {
1041     *(p->pPayload++) = (U8)c;
1042     p->Cnt = Cnt + 1u;
1043   }
1044   //
1045   // Write part of string, when the buffer is full
1046   //
1047   if (p->Cnt == SEGGER_SYSVIEW_MAX_STRING_LEN) {
1048     *(p->pPayloadStart) = (U8)p->Cnt;
1049     pPayload = p->pPayload;
1050     Options = p->Options;
1051     ENCODE_U32(pPayload, Options);
1052     ENCODE_U32(pPayload, 0);
1053     _SendPacket(p->pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
1054     p->pPayloadStart = _PreparePacket(p->pBuffer);
1055     p->pPayload = p->pPayloadStart + 1u;
1056     p->Cnt = 0u;
1057   }
1058 }
1059 
1060 /*********************************************************************
1061 *
1062 *       _PrintUnsigned()
1063 *
1064 *  Function description
1065 *    Print an unsigned integer with the given formatting into the
1066 *     formatted string.
1067 *
1068 *  Parameters
1069 *    pBufferDesc  Pointer to the buffer description.
1070 *    v            Value to be printed.
1071 *    Base         Base of the value.
1072 *    NumDigits    Number of digits to be printed.
1073 *    FieldWidth   Width of the printed field.
1074 *    FormatFlags  Flags for formatting the value.
1075 */
_PrintUnsigned(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc,unsigned int v,unsigned int Base,unsigned int NumDigits,unsigned int FieldWidth,unsigned int FormatFlags)1076 static void _PrintUnsigned(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, unsigned int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
1077   static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1078   unsigned int      Div;
1079   unsigned int      Digit;
1080   unsigned int      Number;
1081   unsigned int      Width;
1082   char              c;
1083 
1084   Number = v;
1085   Digit = 1u;
1086   //
1087   // Get actual field width
1088   //
1089   Width = 1u;
1090   while (Number >= Base) {
1091     Number = (Number / Base);
1092     Width++;
1093   }
1094   if (NumDigits > Width) {
1095     Width = NumDigits;
1096   }
1097   //
1098   // Print leading chars if necessary
1099   //
1100   if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
1101     if (FieldWidth != 0u) {
1102       if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
1103         c = '0';
1104       } else {
1105         c = ' ';
1106       }
1107       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1108         FieldWidth--;
1109         _StoreChar(pBufferDesc, c);
1110       }
1111     }
1112   }
1113   //
1114   // Compute Digit.
1115   // Loop until Digit has the value of the highest digit required.
1116   // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
1117   //
1118   while (1) {
1119     if (NumDigits > 1u) {       // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
1120       NumDigits--;
1121     } else {
1122       Div = v / Digit;
1123       if (Div < Base) {        // Is our divider big enough to extract the highest digit from value? => Done
1124         break;
1125       }
1126     }
1127     Digit *= Base;
1128   }
1129   //
1130   // Output digits
1131   //
1132   do {
1133     Div = v / Digit;
1134     v -= Div * Digit;
1135     _StoreChar(pBufferDesc, _aV2C[Div]);
1136     Digit /= Base;
1137   } while (Digit);
1138   //
1139   // Print trailing spaces if necessary
1140   //
1141   if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
1142     if (FieldWidth != 0u) {
1143       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1144         FieldWidth--;
1145         _StoreChar(pBufferDesc, ' ');
1146       }
1147     }
1148   }
1149 }
1150 
1151 /*********************************************************************
1152 *
1153 *       _PrintInt()
1154 *
1155 *  Function description
1156 *    Print a signed integer with the given formatting into the
1157 *     formatted string.
1158 *
1159 *  Parameters
1160 *    pBufferDesc  Pointer to the buffer description.
1161 *    v            Value to be printed.
1162 *    Base         Base of the value.
1163 *    NumDigits    Number of digits to be printed.
1164 *    FieldWidth   Width of the printed field.
1165 *    FormatFlags  Flags for formatting the value.
1166 */
_PrintInt(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc,int v,unsigned int Base,unsigned int NumDigits,unsigned int FieldWidth,unsigned int FormatFlags)1167 static void _PrintInt(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
1168   unsigned int  Width;
1169   int           Number;
1170 
1171   Number = (v < 0) ? -v : v;
1172 
1173   //
1174   // Get actual field width
1175   //
1176   Width = 1u;
1177   while (Number >= (int)Base) {
1178     Number = (Number / (int)Base);
1179     Width++;
1180   }
1181   if (NumDigits > Width) {
1182     Width = NumDigits;
1183   }
1184   if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
1185     FieldWidth--;
1186   }
1187 
1188   //
1189   // Print leading spaces if necessary
1190   //
1191   if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
1192     if (FieldWidth != 0u) {
1193       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1194         FieldWidth--;
1195         _StoreChar(pBufferDesc, ' ');
1196       }
1197     }
1198   }
1199   //
1200   // Print sign if necessary
1201   //
1202   if (v < 0) {
1203     v = -v;
1204     _StoreChar(pBufferDesc, '-');
1205   } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
1206     _StoreChar(pBufferDesc, '+');
1207   } else {
1208 
1209   }
1210   //
1211   // Print leading zeros if necessary
1212   //
1213   if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
1214     if (FieldWidth != 0u) {
1215       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1216         FieldWidth--;
1217         _StoreChar(pBufferDesc, '0');
1218       }
1219     }
1220   }
1221   //
1222   // Print number without sign
1223   //
1224   _PrintUnsigned(pBufferDesc, (unsigned int)v, Base, NumDigits, FieldWidth, FormatFlags);
1225 }
1226 
1227 /*********************************************************************
1228 *
1229 *       _VPrintTarget()
1230 *
1231 *  Function description
1232 *    Stores a formatted string.
1233 *    This data is read by the host.
1234 *
1235 *  Parameters
1236 *    sFormat      Pointer to format string.
1237 *    Options      Options to be sent to the host.
1238 *    pParamList   Pointer to the list of arguments for the format string.
1239 */
_VPrintTarget(const char * sFormat,U32 Options,va_list * pParamList)1240 static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) {
1241   SEGGER_SYSVIEW_PRINTF_DESC BufferDesc;
1242   char          c;
1243   int           v;
1244   unsigned int  NumDigits;
1245   unsigned int  FormatFlags;
1246   unsigned int  FieldWidth;
1247   U8*           pPayloadStart;
1248   const char*   s;
1249 #if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
1250   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
1251   SEGGER_SYSVIEW_LOCK();
1252 #else
1253   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
1254 #endif
1255 
1256 #if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
1257   BufferDesc.pBuffer        = aPacket;
1258 #else
1259   BufferDesc.pBuffer        = _aPacket;
1260 #endif
1261   BufferDesc.Cnt            = 0u;
1262   BufferDesc.pPayloadStart  = pPayloadStart;
1263   BufferDesc.pPayload       = BufferDesc.pPayloadStart + 1u;
1264   BufferDesc.Options        =  Options;
1265 
1266   do {
1267     c = *sFormat;
1268     sFormat++;
1269     if (c == 0u) {
1270       break;
1271     }
1272     if (c == '%') {
1273       //
1274       // Filter out flags
1275       //
1276       FormatFlags = 0u;
1277       v = 1;
1278       do {
1279         c = *sFormat;
1280         switch (c) {
1281         case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
1282         case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO;     sFormat++; break;
1283         case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN;   sFormat++; break;
1284         case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE;    sFormat++; break;
1285         default:  v = 0; break;
1286         }
1287       } while (v);
1288       //
1289       // filter out field with
1290       //
1291       FieldWidth = 0u;
1292       do {
1293         c = *sFormat;
1294         if ((c < '0') || (c > '9')) {
1295           break;
1296         }
1297         sFormat++;
1298         FieldWidth = (FieldWidth * 10u) + ((unsigned int)c - '0');
1299       } while (1);
1300 
1301       //
1302       // Filter out precision (number of digits to display)
1303       //
1304       NumDigits = 0u;
1305       c = *sFormat;
1306       if (c == '.') {
1307         sFormat++;
1308         do {
1309           c = *sFormat;
1310           if ((c < '0') || (c > '9')) {
1311             break;
1312           }
1313           sFormat++;
1314           NumDigits = NumDigits * 10u + ((unsigned int)c - '0');
1315         } while (1);
1316       }
1317       //
1318       // Filter out length modifier
1319       //
1320       c = *sFormat;
1321       do {
1322         if ((c == 'l') || (c == 'h')) {
1323           c = *sFormat;
1324           sFormat++;
1325         } else {
1326           break;
1327         }
1328       } while (1);
1329       //
1330       // Handle specifiers
1331       //
1332       switch (c) {
1333       case 'c': {
1334         char c0;
1335         v = va_arg(*pParamList, int);
1336         c0 = (char)v;
1337         _StoreChar(&BufferDesc, c0);
1338         break;
1339       }
1340       case 'd':
1341         v = va_arg(*pParamList, int);
1342         _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
1343         break;
1344       case 'u':
1345         v = va_arg(*pParamList, int);
1346         _PrintUnsigned(&BufferDesc, (unsigned int)v, 10u, NumDigits, FieldWidth, FormatFlags);
1347         break;
1348       case 'x':
1349       case 'X':
1350         v = va_arg(*pParamList, int);
1351         _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, NumDigits, FieldWidth, FormatFlags);
1352         break;
1353       case 's':
1354         s = va_arg(*pParamList, const char*);
1355         if (s == NULL) {
1356           s = "(null)";
1357         }
1358         do {
1359           c = *s;
1360           s++;
1361           if (c == '\0') {
1362             break;
1363           }
1364          _StoreChar(&BufferDesc, c);
1365         } while (BufferDesc.Cnt < SEGGER_SYSVIEW_MAX_STRING_LEN);
1366         break;
1367       case 'p':
1368         v = va_arg(*pParamList, int);
1369         _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, 8u, 8u, 0u);
1370         break;
1371       case '%':
1372         _StoreChar(&BufferDesc, '%');
1373         break;
1374       default:
1375         break;
1376       }
1377       sFormat++;
1378     } else {
1379       _StoreChar(&BufferDesc, c);
1380     }
1381   } while (*sFormat);
1382 
1383   //
1384   // Write remaining data, if any
1385   //
1386   if (BufferDesc.Cnt != 0u) {
1387     *(BufferDesc.pPayloadStart) = (U8)BufferDesc.Cnt;
1388     ENCODE_U32(BufferDesc.pPayload, BufferDesc.Options);
1389     ENCODE_U32(BufferDesc.pPayload, 0);
1390     _SendPacket(BufferDesc.pPayloadStart, BufferDesc.pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
1391   }
1392 #if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
1393   SEGGER_SYSVIEW_UNLOCK();
1394   RECORD_END();
1395 #else
1396   RECORD_END();
1397 #endif
1398 }
1399 #endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
1400 
1401 /*********************************************************************
1402 *
1403 *       Public code
1404 *
1405 **********************************************************************
1406 */
1407 
1408 /*********************************************************************
1409 *
1410 *       SEGGER_SYSVIEW_Init()
1411 *
1412 *  Function description
1413 *    Initializes the SYSVIEW module.
1414 *    Must be called before the SystemView Application connects to
1415 *    the system.
1416 *
1417 *  Parameters
1418 *    SysFreq        - Frequency of timestamp, usually CPU core clock frequency.
1419 *    CPUFreq        - CPU core clock frequency.
1420 *    pOSAPI         - Pointer to the API structure for OS-specific functions.
1421 *    pfSendSysDesc  - Pointer to record system description callback function.
1422 *
1423 *  Additional information
1424 *    This function initializes the RTT channel used to transport
1425 *    SEGGER SystemView packets.
1426 *    The channel is assigned the label "SysView" for client software
1427 *    to identify the SystemView channel.
1428 *
1429 *    The channel is configured with the macro SEGGER_SYSVIEW_RTT_CHANNEL.
1430 */
SEGGER_SYSVIEW_Init(U32 SysFreq,U32 CPUFreq,const SEGGER_SYSVIEW_OS_API * pOSAPI,SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc)1431 void SEGGER_SYSVIEW_Init(U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc) {
1432 #ifdef SEGGER_RTT_SECTION
1433   //
1434   // Explicitly initialize the RTT Control Block if it is in its dedicated section.
1435   //
1436   SEGGER_RTT_Init();
1437 #endif
1438 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1439 #if SEGGER_SYSVIEW_RTT_CHANNEL > 0
1440   SEGGER_RTT_ConfigUpBuffer(SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1441 #else
1442   _SYSVIEW_Globals.UpChannel = (U8)SEGGER_RTT_AllocUpBuffer  ("SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1443 #endif
1444   _SYSVIEW_Globals.RAMBaseAddress   = SEGGER_SYSVIEW_ID_BASE;
1445   _SYSVIEW_Globals.LastTxTimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
1446   _SYSVIEW_Globals.pOSAPI           = pOSAPI;
1447   _SYSVIEW_Globals.SysFreq          = SysFreq;
1448   _SYSVIEW_Globals.CPUFreq          = CPUFreq;
1449   _SYSVIEW_Globals.pfSendSysDesc    = pfSendSysDesc;
1450   _SYSVIEW_Globals.EnableState      = 0;
1451   _SYSVIEW_Globals.PacketCount      = 0;
1452 #else // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1453 #if SEGGER_SYSVIEW_RTT_CHANNEL > 0
1454   SEGGER_RTT_ConfigUpBuffer   (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1455   SEGGER_RTT_ConfigDownBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1456 #else
1457   _SYSVIEW_Globals.UpChannel = (U8)SEGGER_RTT_AllocUpBuffer  ("SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1458   _SYSVIEW_Globals.DownChannel = _SYSVIEW_Globals.UpChannel;
1459   SEGGER_RTT_ConfigDownBuffer (_SYSVIEW_Globals.DownChannel, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1460 #endif
1461   _SYSVIEW_Globals.RAMBaseAddress   = SEGGER_SYSVIEW_ID_BASE;
1462   _SYSVIEW_Globals.LastTxTimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
1463   _SYSVIEW_Globals.pOSAPI           = pOSAPI;
1464   _SYSVIEW_Globals.SysFreq          = SysFreq;
1465   _SYSVIEW_Globals.CPUFreq          = CPUFreq;
1466   _SYSVIEW_Globals.pfSendSysDesc    = pfSendSysDesc;
1467   _SYSVIEW_Globals.EnableState      = 0;
1468 #endif  // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1469 }
1470 
1471 /*********************************************************************
1472 *
1473 *       SEGGER_SYSVIEW_SetRAMBase()
1474 *
1475 *  Function description
1476 *    Sets the RAM base address, which is subtracted from IDs in order
1477 *     to save bandwidth.
1478 *
1479 *  Parameters
1480 *    RAMBaseAddress - Lowest RAM Address. (i.e. 0x20000000 on most Cortex-M)
1481 */
SEGGER_SYSVIEW_SetRAMBase(U32 RAMBaseAddress)1482 void SEGGER_SYSVIEW_SetRAMBase(U32 RAMBaseAddress) {
1483   _SYSVIEW_Globals.RAMBaseAddress = RAMBaseAddress;
1484 }
1485 
1486 /*********************************************************************
1487 *
1488 *       SEGGER_SYSVIEW_RecordVoid()
1489 *
1490 *  Function description
1491 *    Formats and sends a SystemView packet with an empty payload.
1492 *
1493 *  Parameters
1494 *    EventID - SystemView event ID.
1495 */
SEGGER_SYSVIEW_RecordVoid(unsigned int EventID)1496 void SEGGER_SYSVIEW_RecordVoid(unsigned int EventID) {
1497   U8* pPayloadStart;
1498   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
1499   //
1500   _SendPacket(pPayloadStart, pPayloadStart, EventID);
1501   RECORD_END();
1502 }
1503 
1504 /*********************************************************************
1505 *
1506 *       SEGGER_SYSVIEW_RecordU32()
1507 *
1508 *  Function description
1509 *    Formats and sends a SystemView packet containing a single U32
1510 *    parameter payload.
1511 *
1512 *  Parameters
1513 *    EventID - SystemView event ID.
1514 *    Value   - The 32-bit parameter encoded to SystemView packet payload.
1515 */
SEGGER_SYSVIEW_RecordU32(unsigned int EventID,U32 Value)1516 void SEGGER_SYSVIEW_RecordU32(unsigned int EventID, U32 Value) {
1517   U8* pPayload;
1518   U8* pPayloadStart;
1519   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
1520   //
1521   pPayload = pPayloadStart;
1522   ENCODE_U32(pPayload, Value);
1523   _SendPacket(pPayloadStart, pPayload, EventID);
1524   RECORD_END();
1525 }
1526 
1527 /*********************************************************************
1528 *
1529 *       SEGGER_SYSVIEW_RecordU32x2()
1530 *
1531 *  Function description
1532 *    Formats and sends a SystemView packet containing 2 U32 parameter payload.
1533 *
1534 *  Parameters
1535 *    EventID - SystemView event ID.
1536 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1537 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1538 */
SEGGER_SYSVIEW_RecordU32x2(unsigned int EventID,U32 Para0,U32 Para1)1539 void SEGGER_SYSVIEW_RecordU32x2(unsigned int EventID, U32 Para0, U32 Para1) {
1540   U8* pPayload;
1541   U8* pPayloadStart;
1542   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
1543   //
1544   pPayload = pPayloadStart;
1545   ENCODE_U32(pPayload, Para0);
1546   ENCODE_U32(pPayload, Para1);
1547   _SendPacket(pPayloadStart, pPayload, EventID);
1548   RECORD_END();
1549 }
1550 
1551 /*********************************************************************
1552 *
1553 *       SEGGER_SYSVIEW_RecordU32x3()
1554 *
1555 *  Function description
1556 *    Formats and sends a SystemView packet containing 3 U32 parameter payload.
1557 *
1558 *  Parameters
1559 *    EventID - SystemView event ID.
1560 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1561 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1562 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1563 */
SEGGER_SYSVIEW_RecordU32x3(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2)1564 void SEGGER_SYSVIEW_RecordU32x3(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2) {
1565   U8* pPayload;
1566   U8* pPayloadStart;
1567   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 3 * SEGGER_SYSVIEW_QUANTA_U32);
1568   //
1569   pPayload = pPayloadStart;
1570   ENCODE_U32(pPayload, Para0);
1571   ENCODE_U32(pPayload, Para1);
1572   ENCODE_U32(pPayload, Para2);
1573   _SendPacket(pPayloadStart, pPayload, EventID);
1574   RECORD_END();
1575 }
1576 
1577 /*********************************************************************
1578 *
1579 *       SEGGER_SYSVIEW_RecordU32x4()
1580 *
1581 *  Function description
1582 *    Formats and sends a SystemView packet containing 4 U32 parameter payload.
1583 *
1584 *  Parameters
1585 *    EventID - SystemView event ID.
1586 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1587 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1588 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1589 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1590 */
SEGGER_SYSVIEW_RecordU32x4(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3)1591 void SEGGER_SYSVIEW_RecordU32x4(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
1592   U8* pPayload;
1593   U8* pPayloadStart;
1594   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
1595   //
1596   pPayload = pPayloadStart;
1597   ENCODE_U32(pPayload, Para0);
1598   ENCODE_U32(pPayload, Para1);
1599   ENCODE_U32(pPayload, Para2);
1600   ENCODE_U32(pPayload, Para3);
1601   _SendPacket(pPayloadStart, pPayload, EventID);
1602   RECORD_END();
1603 }
1604 
1605 /*********************************************************************
1606 *
1607 *       SEGGER_SYSVIEW_RecordU32x5()
1608 *
1609 *  Function description
1610 *    Formats and sends a SystemView packet containing 5 U32 parameter payload.
1611 *
1612 *  Parameters
1613 *    EventID - SystemView event ID.
1614 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1615 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1616 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1617 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1618 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1619 */
SEGGER_SYSVIEW_RecordU32x5(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4)1620 void SEGGER_SYSVIEW_RecordU32x5(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
1621   U8* pPayload;
1622   U8* pPayloadStart;
1623   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32);
1624   //
1625   pPayload = pPayloadStart;
1626   ENCODE_U32(pPayload, Para0);
1627   ENCODE_U32(pPayload, Para1);
1628   ENCODE_U32(pPayload, Para2);
1629   ENCODE_U32(pPayload, Para3);
1630   ENCODE_U32(pPayload, Para4);
1631   _SendPacket(pPayloadStart, pPayload, EventID);
1632   RECORD_END();
1633 }
1634 
1635 /*********************************************************************
1636 *
1637 *       SEGGER_SYSVIEW_RecordU32x6()
1638 *
1639 *  Function description
1640 *    Formats and sends a SystemView packet containing 6 U32 parameter payload.
1641 *
1642 *  Parameters
1643 *    EventID - SystemView event ID.
1644 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1645 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1646 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1647 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1648 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1649 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1650 */
SEGGER_SYSVIEW_RecordU32x6(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5)1651 void SEGGER_SYSVIEW_RecordU32x6(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5) {
1652   U8* pPayload;
1653   U8* pPayloadStart;
1654   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 6 * SEGGER_SYSVIEW_QUANTA_U32);
1655   //
1656   pPayload = pPayloadStart;
1657   ENCODE_U32(pPayload, Para0);
1658   ENCODE_U32(pPayload, Para1);
1659   ENCODE_U32(pPayload, Para2);
1660   ENCODE_U32(pPayload, Para3);
1661   ENCODE_U32(pPayload, Para4);
1662   ENCODE_U32(pPayload, Para5);
1663   _SendPacket(pPayloadStart, pPayload, EventID);
1664   RECORD_END();
1665 }
1666 
1667 /*********************************************************************
1668 *
1669 *       SEGGER_SYSVIEW_RecordU32x7()
1670 *
1671 *  Function description
1672 *    Formats and sends a SystemView packet containing 7 U32 parameter payload.
1673 *
1674 *  Parameters
1675 *    EventID - SystemView event ID.
1676 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1677 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1678 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1679 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1680 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1681 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1682 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1683 */
SEGGER_SYSVIEW_RecordU32x7(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5,U32 Para6)1684 void SEGGER_SYSVIEW_RecordU32x7(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6) {
1685   U8* pPayload;
1686   U8* pPayloadStart;
1687   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 7 * SEGGER_SYSVIEW_QUANTA_U32);
1688   //
1689   pPayload = pPayloadStart;
1690   ENCODE_U32(pPayload, Para0);
1691   ENCODE_U32(pPayload, Para1);
1692   ENCODE_U32(pPayload, Para2);
1693   ENCODE_U32(pPayload, Para3);
1694   ENCODE_U32(pPayload, Para4);
1695   ENCODE_U32(pPayload, Para5);
1696   ENCODE_U32(pPayload, Para6);
1697   _SendPacket(pPayloadStart, pPayload, EventID);
1698   RECORD_END();
1699 }
1700 
1701 /*********************************************************************
1702 *
1703 *       SEGGER_SYSVIEW_RecordU32x8()
1704 *
1705 *  Function description
1706 *    Formats and sends a SystemView packet containing 8 U32 parameter payload.
1707 *
1708 *  Parameters
1709 *    EventID - SystemView event ID.
1710 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1711 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1712 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1713 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1714 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1715 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1716 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1717 *    Para7   - The 32-bit parameter encoded to SystemView packet payload.
1718 */
SEGGER_SYSVIEW_RecordU32x8(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5,U32 Para6,U32 Para7)1719 void SEGGER_SYSVIEW_RecordU32x8(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7) {
1720   U8* pPayload;
1721   U8* pPayloadStart;
1722   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 8 * SEGGER_SYSVIEW_QUANTA_U32);
1723   //
1724   pPayload = pPayloadStart;
1725   ENCODE_U32(pPayload, Para0);
1726   ENCODE_U32(pPayload, Para1);
1727   ENCODE_U32(pPayload, Para2);
1728   ENCODE_U32(pPayload, Para3);
1729   ENCODE_U32(pPayload, Para4);
1730   ENCODE_U32(pPayload, Para5);
1731   ENCODE_U32(pPayload, Para6);
1732   ENCODE_U32(pPayload, Para7);
1733   _SendPacket(pPayloadStart, pPayload, EventID);
1734   RECORD_END();
1735 }
1736 
1737 /*********************************************************************
1738 *
1739 *       SEGGER_SYSVIEW_RecordU32x9()
1740 *
1741 *  Function description
1742 *    Formats and sends a SystemView packet containing 9 U32 parameter payload.
1743 *
1744 *  Parameters
1745 *    EventID - SystemView event ID.
1746 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1747 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1748 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1749 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1750 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1751 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1752 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1753 *    Para7   - The 32-bit parameter encoded to SystemView packet payload.
1754 *    Para8   - The 32-bit parameter encoded to SystemView packet payload.
1755 */
SEGGER_SYSVIEW_RecordU32x9(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5,U32 Para6,U32 Para7,U32 Para8)1756 void SEGGER_SYSVIEW_RecordU32x9(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8) {
1757   U8* pPayload;
1758   U8* pPayloadStart;
1759   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 9 * SEGGER_SYSVIEW_QUANTA_U32);
1760   //
1761   pPayload = pPayloadStart;
1762   ENCODE_U32(pPayload, Para0);
1763   ENCODE_U32(pPayload, Para1);
1764   ENCODE_U32(pPayload, Para2);
1765   ENCODE_U32(pPayload, Para3);
1766   ENCODE_U32(pPayload, Para4);
1767   ENCODE_U32(pPayload, Para5);
1768   ENCODE_U32(pPayload, Para6);
1769   ENCODE_U32(pPayload, Para7);
1770   ENCODE_U32(pPayload, Para8);
1771   _SendPacket(pPayloadStart, pPayload, EventID);
1772   RECORD_END();
1773 }
1774 
1775 /*********************************************************************
1776 *
1777 *       SEGGER_SYSVIEW_RecordU32x10()
1778 *
1779 *  Function description
1780 *    Formats and sends a SystemView packet containing 10 U32 parameter payload.
1781 *
1782 *  Parameters
1783 *    EventID - SystemView event ID.
1784 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1785 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1786 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1787 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1788 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1789 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1790 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1791 *    Para7   - The 32-bit parameter encoded to SystemView packet payload.
1792 *    Para8   - The 32-bit parameter encoded to SystemView packet payload.
1793 *    Para9   - The 32-bit parameter encoded to SystemView packet payload.
1794 */
SEGGER_SYSVIEW_RecordU32x10(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5,U32 Para6,U32 Para7,U32 Para8,U32 Para9)1795 void SEGGER_SYSVIEW_RecordU32x10(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9) {
1796   U8* pPayload;
1797   U8* pPayloadStart;
1798   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 10 * SEGGER_SYSVIEW_QUANTA_U32);
1799   //
1800   pPayload = pPayloadStart;
1801   ENCODE_U32(pPayload, Para0);
1802   ENCODE_U32(pPayload, Para1);
1803   ENCODE_U32(pPayload, Para2);
1804   ENCODE_U32(pPayload, Para3);
1805   ENCODE_U32(pPayload, Para4);
1806   ENCODE_U32(pPayload, Para5);
1807   ENCODE_U32(pPayload, Para6);
1808   ENCODE_U32(pPayload, Para7);
1809   ENCODE_U32(pPayload, Para8);
1810   ENCODE_U32(pPayload, Para9);
1811   _SendPacket(pPayloadStart, pPayload, EventID);
1812   RECORD_END();
1813 }
1814 /*********************************************************************
1815 *
1816 *       SEGGER_SYSVIEW_RecordString()
1817 *
1818 *  Function description
1819 *    Formats and sends a SystemView packet containing a string.
1820 *
1821 *  Parameters
1822 *    EventID - SystemView event ID.
1823 *    pString - The string to be sent in the SystemView packet payload.
1824 *
1825 *  Additional information
1826 *    The string is encoded as a count byte followed by the contents
1827 *    of the string.
1828 *    No more than SEGGER_SYSVIEW_MAX_STRING_LEN bytes will be encoded to the payload.
1829 */
SEGGER_SYSVIEW_RecordString(unsigned int EventID,const char * pString)1830 void SEGGER_SYSVIEW_RecordString(unsigned int EventID, const char* pString) {
1831   U8* pPayload;
1832   U8* pPayloadStart;
1833   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
1834   //
1835   pPayload = _EncodeStr(pPayloadStart, pString, SEGGER_SYSVIEW_MAX_STRING_LEN);
1836   _SendPacket(pPayloadStart, pPayload, EventID);
1837   RECORD_END();
1838 }
1839 
1840 /*********************************************************************
1841 *
1842 *       SEGGER_SYSVIEW_Start()
1843 *
1844 *  Function description
1845 *    Start recording SystemView events.
1846 *
1847 *    This function is triggered by the SystemView Application on connect.
1848 *    For single-shot or post-mortem mode recording, it needs to be called
1849 *    by the application.
1850 *
1851 *  Additional information
1852 *    This function enables transmission of SystemView packets recorded
1853 *    by subsequent trace calls and records a SystemView Start event.
1854 *
1855 *    As part of start, a SystemView Init packet is sent, containing the system
1856 *    frequency. The list of current tasks, the current system time and the
1857 *    system description string is sent, too.
1858 *
1859 *  Notes
1860 *    SEGGER_SYSVIEW_Start and SEGGER_SYSVIEW_Stop do not nest.
1861 *    When SEGGER_SYSVIEW_CAN_RESTART is 1, each received start command
1862 *    records the system information. This is required to enable restart
1863 *    of recordings when SystemView unexpectedly disconnects without sending
1864 *    a stop command before.
1865 */
SEGGER_SYSVIEW_Start(void)1866 void SEGGER_SYSVIEW_Start(void) {
1867 #if (SEGGER_SYSVIEW_CAN_RESTART == 0)
1868   if (_SYSVIEW_Globals.EnableState == 0) {
1869 #endif
1870     _SYSVIEW_Globals.EnableState = 1;
1871 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1872     _SendSyncInfo();
1873 #else
1874     SEGGER_SYSVIEW_LOCK();
1875     SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, _abSync, 10);
1876     SEGGER_SYSVIEW_UNLOCK();
1877     SEGGER_SYSVIEW_ON_EVENT_RECORDED(10);
1878     SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
1879     {
1880       U8* pPayload;
1881       U8* pPayloadStart;
1882       RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
1883       //
1884       pPayload = pPayloadStart;
1885       ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
1886       ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
1887       ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
1888       ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
1889       _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
1890       RECORD_END();
1891     }
1892     if (_SYSVIEW_Globals.pfSendSysDesc) {
1893       _SYSVIEW_Globals.pfSendSysDesc();
1894     }
1895     SEGGER_SYSVIEW_RecordSystime();
1896     SEGGER_SYSVIEW_SendTaskList();
1897     SEGGER_SYSVIEW_SendNumModules();
1898 #endif
1899 #if (SEGGER_SYSVIEW_CAN_RESTART == 0)
1900   }
1901 #endif
1902 }
1903 
1904 /*********************************************************************
1905 *
1906 *       SEGGER_SYSVIEW_Stop()
1907 *
1908 *  Function description
1909 *    Stop recording SystemView events.
1910 *
1911 *    This function is triggered by the SystemView Application on disconnect.
1912 *    For single-shot or postmortem mode recording, it can be called
1913 *    by the application.
1914 *
1915 *  Additional information
1916 *    This function disables transmission of SystemView packets recorded
1917 *    by subsequent trace calls.  If transmission is enabled when
1918 *    this function is called, a single SystemView Stop event is recorded
1919 *    to the trace, send, and then trace transmission is halted.
1920 */
SEGGER_SYSVIEW_Stop(void)1921 void SEGGER_SYSVIEW_Stop(void) {
1922   U8* pPayloadStart;
1923   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
1924   //
1925   if (_SYSVIEW_Globals.EnableState) {
1926     _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TRACE_STOP);
1927     _SYSVIEW_Globals.EnableState = 0;
1928   }
1929   RECORD_END();
1930 }
1931 
1932 /*********************************************************************
1933 *
1934 *       SEGGER_SYSVIEW_GetChannelID()
1935 *
1936 *  Function description
1937 *    Returns the RTT <Up> / <Down> channel ID used by SystemView.
1938 */
SEGGER_SYSVIEW_GetChannelID(void)1939 int SEGGER_SYSVIEW_GetChannelID(void) {
1940   return CHANNEL_ID_UP;
1941 }
1942 
1943 /*********************************************************************
1944 *
1945 *       SEGGER_SYSVIEW_GetSysDesc()
1946 *
1947 *  Function description
1948 *    Triggers a send of the system information and description.
1949 *
1950 */
SEGGER_SYSVIEW_GetSysDesc(void)1951 void SEGGER_SYSVIEW_GetSysDesc(void) {
1952   U8* pPayload;
1953   U8* pPayloadStart;
1954   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
1955   //
1956   pPayload = pPayloadStart;
1957   ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
1958   ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
1959   ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
1960   ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
1961   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
1962   RECORD_END();
1963   if (_SYSVIEW_Globals.pfSendSysDesc) {
1964     _SYSVIEW_Globals.pfSendSysDesc();
1965   }
1966 }
1967 
1968 /*********************************************************************
1969 *
1970 *       SEGGER_SYSVIEW_SendTaskInfo()
1971 *
1972 *  Function description
1973 *    Send a Task Info Packet, containing TaskId for identification,
1974 *    task priority and task name.
1975 *
1976 *  Parameters
1977 *    pInfo - Pointer to task information to send.
1978 */
SEGGER_SYSVIEW_SendTaskInfo(const SEGGER_SYSVIEW_TASKINFO * pInfo)1979 void SEGGER_SYSVIEW_SendTaskInfo(const SEGGER_SYSVIEW_TASKINFO *pInfo) {
1980   U8* pPayload;
1981   U8* pPayloadStart;
1982   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + 32);
1983   //
1984   pPayload = pPayloadStart;
1985   ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
1986   ENCODE_U32(pPayload, pInfo->Prio);
1987   pPayload = _EncodeStr(pPayload, pInfo->sName, 32);
1988   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_INFO);
1989   //
1990   pPayload = pPayloadStart;
1991   ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
1992   ENCODE_U32(pPayload, pInfo->StackBase);
1993   ENCODE_U32(pPayload, pInfo->StackSize);
1994   ENCODE_U32(pPayload, pInfo->StackUsage);
1995   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_STACK_INFO);
1996   RECORD_END();
1997 }
1998 
1999 /*********************************************************************
2000 *
2001 *       SEGGER_SYSVIEW_SendStackInfo()
2002 *
2003 *  Function description
2004 *    Send a Stack Info Packet, containing TaskId for identification,
2005 *    stack base, stack size and stack usage.
2006 *
2007 *
2008 *  Parameters
2009 *    pInfo - Pointer to stack information to send.
2010 */
SEGGER_SYSVIEW_SendStackInfo(const SEGGER_SYSVIEW_STACKINFO * pInfo)2011 void SEGGER_SYSVIEW_SendStackInfo(const SEGGER_SYSVIEW_STACKINFO *pInfo) {
2012   U8* pPayload;
2013   U8* pPayloadStart;
2014   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
2015   //
2016   pPayload = pPayloadStart;
2017   ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
2018   ENCODE_U32(pPayload, pInfo->StackBase);
2019   ENCODE_U32(pPayload, pInfo->StackSize);
2020   ENCODE_U32(pPayload, pInfo->StackUsage);
2021 
2022   RECORD_END();
2023 }
2024 
2025 /*********************************************************************
2026 *
2027 *        SEGGER_SYSVIEW_SampleData()
2028 *
2029 *  Function description
2030 *    Send a Data Sample Packet, containing the data Id and the value.
2031 *
2032 *
2033 *  Parameters
2034 *    pInfo - Pointer to data sample struct to send.
2035 */
SEGGER_SYSVIEW_SampleData(const SEGGER_SYSVIEW_DATA_SAMPLE * pInfo)2036 void SEGGER_SYSVIEW_SampleData(const SEGGER_SYSVIEW_DATA_SAMPLE *pInfo) {
2037   U8* pPayload;
2038   U8* pPayloadStart;
2039   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2040   //
2041   pPayload = pPayloadStart;
2042   ENCODE_U32(pPayload, pInfo->ID);
2043   pPayload = _EncodeFloat(pPayload, *(pInfo->pValue.pFloat));
2044   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_DATA_SAMPLE);
2045 
2046   RECORD_END();
2047 }
2048 
2049 /*********************************************************************
2050 *
2051 *       SEGGER_SYSVIEW_SendTaskList()
2052 *
2053 *  Function description
2054 *    Send all tasks descriptors to the host.
2055 */
SEGGER_SYSVIEW_SendTaskList(void)2056 void SEGGER_SYSVIEW_SendTaskList(void) {
2057   if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfSendTaskList) {
2058     _SYSVIEW_Globals.pOSAPI->pfSendTaskList();
2059   }
2060 }
2061 
2062 /*********************************************************************
2063 *
2064 *       SEGGER_SYSVIEW_SendSysDesc()
2065 *
2066 *  Function description
2067 *    Send the system description string to the host.
2068 *    The system description is used by the SystemView Application
2069 *    to identify the current application and handle events accordingly.
2070 *
2071 *    The system description is usually called by the system description
2072 *    callback, to ensure it is only sent when the SystemView Application
2073 *    is connected.
2074 *
2075 *  Parameters
2076 *    sSysDesc - Pointer to the 0-terminated system description string.
2077 *
2078 *  Additional information
2079 *    One system description string may not exceed SEGGER_SYSVIEW_MAX_STRING_LEN characters.
2080 *    Multiple description strings can be recorded.
2081 *
2082 *    The Following items can be described in a system description string.
2083 *    Each item is identified by its identifier, followed by '=' and the value.
2084 *    Items are separated by ','.
2085 */
SEGGER_SYSVIEW_SendSysDesc(const char * sSysDesc)2086 void SEGGER_SYSVIEW_SendSysDesc(const char *sSysDesc) {
2087   U8* pPayload;
2088   U8* pPayloadStart;
2089   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2090   //
2091   pPayload = _EncodeStr(pPayloadStart, sSysDesc, SEGGER_SYSVIEW_MAX_STRING_LEN);
2092   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_SYSDESC);
2093   RECORD_END();
2094 }
2095 
2096 /*********************************************************************
2097 *
2098 *       SEGGER_SYSVIEW_RecordSystime()
2099 *
2100 *  Function description
2101 *    Formats and sends a SystemView Systime containing a single U64 or U32
2102 *    parameter payload.
2103 */
SEGGER_SYSVIEW_RecordSystime(void)2104 void SEGGER_SYSVIEW_RecordSystime(void) {
2105   U64 Systime;
2106 
2107   if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfGetTime) {
2108     Systime = _SYSVIEW_Globals.pOSAPI->pfGetTime();
2109     SEGGER_SYSVIEW_RecordU32x2(SYSVIEW_EVTID_SYSTIME_US,
2110                                (U32)(Systime),
2111                                (U32)(Systime >> 32));
2112   } else {
2113     SEGGER_SYSVIEW_RecordU32(SYSVIEW_EVTID_SYSTIME_CYCLES, SEGGER_SYSVIEW_GET_TIMESTAMP());
2114   }
2115 }
2116 
2117 /*********************************************************************
2118 *
2119 *       SEGGER_SYSVIEW_RecordEnterISR()
2120 *
2121 *  Function description
2122 *    Format and send an ISR entry event.
2123 *
2124 *  Additional information
2125 *    Example packets sent
2126 *      02 0F 50              // ISR(15) Enter. Timestamp is 80 (0x50)
2127 */
SEGGER_SYSVIEW_RecordEnterISR(void)2128 void SEGGER_SYSVIEW_RecordEnterISR(void) {
2129   unsigned v;
2130   U8* pPayload;
2131   U8* pPayloadStart;
2132   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2133   //
2134   pPayload = pPayloadStart;
2135   v = SEGGER_SYSVIEW_GET_INTERRUPT_ID();
2136   ENCODE_U32(pPayload, v);
2137   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_ISR_ENTER);
2138   RECORD_END();
2139 }
2140 
2141 /*********************************************************************
2142 *
2143 *       SEGGER_SYSVIEW_RecordExitISR()
2144 *
2145 *  Function description
2146 *    Format and send an ISR exit event.
2147 *
2148 *  Additional information
2149 *    Format as follows:
2150 *      03 <TimeStamp>        // Max. packet len is 6
2151 *
2152 *    Example packets sent
2153 *      03 20                // ISR Exit. Timestamp is 32 (0x20)
2154 */
SEGGER_SYSVIEW_RecordExitISR(void)2155 void SEGGER_SYSVIEW_RecordExitISR(void) {
2156   U8* pPayloadStart;
2157   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2158   //
2159   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_EXIT);
2160   RECORD_END();
2161 }
2162 
2163 /*********************************************************************
2164 *
2165 *       SEGGER_SYSVIEW_RecordExitISRToScheduler()
2166 *
2167 *  Function description
2168 *    Format and send an ISR exit into scheduler event.
2169 *
2170 *  Additional information
2171 *    Format as follows:
2172 *      18 <TimeStamp>        // Max. packet len is 6
2173 *
2174 *    Example packets sent
2175 *      18 20                // ISR Exit to Scheduler. Timestamp is 32 (0x20)
2176 */
SEGGER_SYSVIEW_RecordExitISRToScheduler(void)2177 void SEGGER_SYSVIEW_RecordExitISRToScheduler(void) {
2178   U8* pPayloadStart;
2179   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2180   //
2181   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_TO_SCHEDULER);
2182   RECORD_END();
2183 }
2184 
2185 /*********************************************************************
2186 *
2187 *       SEGGER_SYSVIEW_RecordEnterTimer()
2188 *
2189 *  Function description
2190 *    Format and send a Timer entry event.
2191 *
2192 *  Parameters
2193 *    TimerId - Id of the timer which starts.
2194 */
SEGGER_SYSVIEW_RecordEnterTimer(U32 TimerId)2195 void SEGGER_SYSVIEW_RecordEnterTimer(U32 TimerId) {
2196   U8* pPayload;
2197   U8* pPayloadStart;
2198   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2199   //
2200   pPayload = pPayloadStart;
2201   ENCODE_U32(pPayload, SHRINK_ID(TimerId));
2202   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TIMER_ENTER);
2203   RECORD_END();
2204 }
2205 
2206 /*********************************************************************
2207 *
2208 *       SEGGER_SYSVIEW_RecordExitTimer()
2209 *
2210 *  Function description
2211 *    Format and send a Timer exit event.
2212 */
SEGGER_SYSVIEW_RecordExitTimer(void)2213 void SEGGER_SYSVIEW_RecordExitTimer(void) {
2214   U8* pPayloadStart;
2215   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2216   //
2217   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TIMER_EXIT);
2218   RECORD_END();
2219 }
2220 
2221 /*********************************************************************
2222 *
2223 *       SEGGER_SYSVIEW_RecordEndCall()
2224 *
2225 *  Function description
2226 *    Format and send an End API Call event without return value.
2227 *
2228 *  Parameters
2229 *    EventID - Id of API function which ends.
2230 */
SEGGER_SYSVIEW_RecordEndCall(unsigned int EventID)2231 void SEGGER_SYSVIEW_RecordEndCall(unsigned int EventID) {
2232   U8* pPayload;
2233   U8* pPayloadStart;
2234   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2235   //
2236   pPayload = pPayloadStart;
2237   ENCODE_U32(pPayload, EventID);
2238   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
2239   RECORD_END();
2240 }
2241 
2242 /*********************************************************************
2243 *
2244 *       SEGGER_SYSVIEW_RecordEndCallU32()
2245 *
2246 *  Function description
2247 *    Format and send an End API Call event with return value.
2248 *
2249 *  Parameters
2250 *    EventID      - Id of API function which ends.
2251 *    Para0        - Return value which will be returned by the API function.
2252 */
SEGGER_SYSVIEW_RecordEndCallU32(unsigned int EventID,U32 Para0)2253 void SEGGER_SYSVIEW_RecordEndCallU32(unsigned int EventID, U32 Para0) {
2254   U8* pPayload;
2255   U8* pPayloadStart;
2256   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2257   //
2258   pPayload = pPayloadStart;
2259   ENCODE_U32(pPayload, EventID);
2260   ENCODE_U32(pPayload, Para0);
2261   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
2262   RECORD_END();
2263 }
2264 
2265 /*********************************************************************
2266 *
2267 *       SEGGER_SYSVIEW_OnIdle()
2268 *
2269 *  Function description
2270 *    Record an Idle event.
2271 */
SEGGER_SYSVIEW_OnIdle(void)2272 void SEGGER_SYSVIEW_OnIdle(void) {
2273   U8* pPayloadStart;
2274   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2275   //
2276   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_IDLE);
2277   RECORD_END();
2278 }
2279 
2280 /*********************************************************************
2281 *
2282 *       SEGGER_SYSVIEW_OnTaskCreate()
2283 *
2284 *  Function description
2285 *    Record a Task Create event.  The Task Create event corresponds
2286 *    to creating a task in the OS.
2287 *
2288 *  Parameters
2289 *    TaskId        - Task ID of created task.
2290 */
SEGGER_SYSVIEW_OnTaskCreate(U32 TaskId)2291 void SEGGER_SYSVIEW_OnTaskCreate(U32 TaskId) {
2292   U8* pPayload;
2293   U8* pPayloadStart;
2294   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2295   //
2296   pPayload = pPayloadStart;
2297   TaskId = SHRINK_ID(TaskId);
2298   ENCODE_U32(pPayload, TaskId);
2299   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_CREATE);
2300   RECORD_END();
2301 }
2302 
2303 /*********************************************************************
2304 *
2305 *       SEGGER_SYSVIEW_OnTaskTerminate()
2306 *
2307 *  Function description
2308 *    Record a Task termination event.
2309 *    The Task termination event corresponds to terminating a task in
2310 *    the OS. If the TaskId is the currently active task,
2311 *    SEGGER_SYSVIEW_OnTaskStopExec may be used, either.
2312 *
2313 *  Parameters
2314 *    TaskId        - Task ID of terminated task.
2315 */
SEGGER_SYSVIEW_OnTaskTerminate(U32 TaskId)2316 void SEGGER_SYSVIEW_OnTaskTerminate(U32 TaskId) {
2317   U8* pPayload;
2318   U8* pPayloadStart;
2319   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2320   //
2321   pPayload = pPayloadStart;
2322   TaskId = SHRINK_ID(TaskId);
2323   ENCODE_U32(pPayload, TaskId);
2324   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_TERMINATE);
2325   RECORD_END();
2326 }
2327 
2328 /*********************************************************************
2329 *
2330 *       SEGGER_SYSVIEW_OnTaskStartExec()
2331 *
2332 *  Function description
2333 *    Record a Task Start Execution event.  The Task Start event
2334 *    corresponds to when a task has started to execute rather than
2335 *    when it is ready to execute.
2336 *
2337 *  Parameters
2338 *    TaskId - Task ID of task that started to execute.
2339 */
SEGGER_SYSVIEW_OnTaskStartExec(U32 TaskId)2340 void SEGGER_SYSVIEW_OnTaskStartExec(U32 TaskId) {
2341   U8* pPayload;
2342   U8* pPayloadStart;
2343   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2344   //
2345   pPayload = pPayloadStart;
2346   TaskId = SHRINK_ID(TaskId);
2347   ENCODE_U32(pPayload, TaskId);
2348   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_EXEC);
2349   RECORD_END();
2350 }
2351 
2352 /*********************************************************************
2353 *
2354 *       SEGGER_SYSVIEW_OnTaskStopExec()
2355 *
2356 *  Function description
2357 *    Record a Task Stop Execution event.  The Task Stop event
2358 *    corresponds to when a task stops executing and terminates.
2359 */
SEGGER_SYSVIEW_OnTaskStopExec(void)2360 void SEGGER_SYSVIEW_OnTaskStopExec(void) {
2361   U8* pPayloadStart;
2362   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2363   //
2364   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TASK_STOP_EXEC);
2365   RECORD_END();
2366 }
2367 
2368 /*********************************************************************
2369 *
2370 *       SEGGER_SYSVIEW_OnTaskStartReady()
2371 *
2372 *  Function description
2373 *    Record a Task Start Ready event.
2374 *
2375 *  Parameters
2376 *    TaskId - Task ID of task that started to execute.
2377 */
SEGGER_SYSVIEW_OnTaskStartReady(U32 TaskId)2378 void SEGGER_SYSVIEW_OnTaskStartReady(U32 TaskId) {
2379   U8* pPayload;
2380   U8* pPayloadStart;
2381   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2382   //
2383   pPayload = pPayloadStart;
2384   TaskId = SHRINK_ID(TaskId);
2385   ENCODE_U32(pPayload, TaskId);
2386   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_READY);
2387   RECORD_END();
2388 }
2389 
2390 /*********************************************************************
2391 *
2392 *       SEGGER_SYSVIEW_OnTaskStopReady()
2393 *
2394 *  Function description
2395 *    Record a Task Stop Ready event.
2396 *
2397 *  Parameters
2398 *    TaskId - Task ID of task that completed execution.
2399 *    Cause  - Reason for task to stop (i.e. Idle/Sleep)
2400 */
SEGGER_SYSVIEW_OnTaskStopReady(U32 TaskId,unsigned int Cause)2401 void SEGGER_SYSVIEW_OnTaskStopReady(U32 TaskId, unsigned int Cause) {
2402   U8* pPayload;
2403   U8* pPayloadStart;
2404   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2405   //
2406   pPayload = pPayloadStart;
2407   TaskId = SHRINK_ID(TaskId);
2408   ENCODE_U32(pPayload, TaskId);
2409   ENCODE_U32(pPayload, Cause);
2410   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_STOP_READY);
2411   RECORD_END();
2412 }
2413 
2414 /*********************************************************************
2415 *
2416 *       SEGGER_SYSVIEW_MarkStart()
2417 *
2418 *  Function description
2419 *    Record a Performance Marker Start event to start measuring runtime.
2420 *
2421 *  Parameters
2422 *    MarkerId  - User defined ID for the marker.
2423 */
SEGGER_SYSVIEW_MarkStart(unsigned MarkerId)2424 void SEGGER_SYSVIEW_MarkStart(unsigned MarkerId) {
2425   U8* pPayload;
2426   U8* pPayloadStart;
2427   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2428   //
2429   pPayload = pPayloadStart;
2430   ENCODE_U32(pPayload, MarkerId);
2431   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MARK_START);
2432   RECORD_END();
2433 }
2434 
2435 /*********************************************************************
2436 *
2437 *       SEGGER_SYSVIEW_MarkStop()
2438 *
2439 *  Function description
2440 *    Record a Performance Marker Stop event to stop measuring runtime.
2441 *
2442 *  Parameters
2443 *    MarkerId  - User defined ID for the marker.
2444 */
SEGGER_SYSVIEW_MarkStop(unsigned MarkerId)2445 void SEGGER_SYSVIEW_MarkStop(unsigned MarkerId) {
2446   U8 * pPayload;
2447   U8 * pPayloadStart;
2448   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2449   //
2450   pPayload = pPayloadStart;
2451   ENCODE_U32(pPayload, MarkerId);
2452   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MARK_STOP);
2453   RECORD_END();
2454 }
2455 
2456 /*********************************************************************
2457 *
2458 *       SEGGER_SYSVIEW_Mark()
2459 *
2460 *  Function description
2461 *    Record a Performance Marker intermediate event.
2462 *
2463 *  Parameters
2464 *    MarkerId  - User defined ID for the marker.
2465 */
SEGGER_SYSVIEW_Mark(unsigned int MarkerId)2466 void SEGGER_SYSVIEW_Mark(unsigned int MarkerId) {
2467   U8* pPayload;
2468   U8* pPayloadStart;
2469   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2470   //
2471   pPayload = pPayloadStart;
2472   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_MARK);
2473   ENCODE_U32(pPayload, MarkerId);
2474   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2475   RECORD_END();
2476 }
2477 
2478 /*********************************************************************
2479 *
2480 *       SEGGER_SYSVIEW_NameMarker()
2481 *
2482 *  Function description
2483 *    Send the name of a Performance Marker to be displayed in SystemView.
2484 *
2485 *    Marker names are usually set in the system description
2486 *    callback, to ensure it is only sent when the SystemView Application
2487 *    is connected.
2488 *
2489 *  Parameters
2490 *    MarkerId   - User defined ID for the marker.
2491 *    sName      - Pointer to the marker name. (Max. SEGGER_SYSVIEW_MAX_STRING_LEN Bytes)
2492 */
SEGGER_SYSVIEW_NameMarker(unsigned int MarkerId,const char * sName)2493 void SEGGER_SYSVIEW_NameMarker(unsigned int MarkerId, const char* sName) {
2494   U8* pPayload;
2495   U8* pPayloadStart;
2496   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2497   //
2498   pPayload = pPayloadStart;
2499   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_NAME_MARKER);
2500   ENCODE_U32(pPayload, MarkerId);
2501   pPayload = _EncodeStr(pPayload, sName, SEGGER_SYSVIEW_MAX_STRING_LEN);
2502   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2503   RECORD_END();
2504 }
2505 
2506 /*********************************************************************
2507 *
2508 *       SEGGER_SYSVIEW_NameResource()
2509 *
2510 *  Function description
2511 *    Send the name of a resource to be displayed in SystemView.
2512 *
2513 *    Marker names are usually set in the system description
2514 *    callback, to ensure it is only sent when the SystemView Application
2515 *    is connected.
2516 *
2517 *  Parameters
2518 *    ResourceId - Id of the resource to be named. i.e. its address.
2519 *    sName      - Pointer to the resource name. (Max. SEGGER_SYSVIEW_MAX_STRING_LEN Bytes)
2520 */
SEGGER_SYSVIEW_NameResource(U32 ResourceId,const char * sName)2521 void SEGGER_SYSVIEW_NameResource(U32 ResourceId, const char* sName) {
2522   U8* pPayload;
2523   U8* pPayloadStart;
2524   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2525   //
2526   pPayload = pPayloadStart;
2527   ENCODE_U32(pPayload, SHRINK_ID(ResourceId));
2528   pPayload = _EncodeStr(pPayload, sName, SEGGER_SYSVIEW_MAX_STRING_LEN);
2529   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NAME_RESOURCE);
2530   RECORD_END();
2531 }
2532 
2533 /*********************************************************************
2534 *
2535 *       SEGGER_SYSVIEW_RegisterData()
2536 *
2537 *  Function description
2538 *    Register data to sample the values via SystemView.
2539 *
2540 *    Register functions are usually set in the system description
2541 *    callback, to ensure it is only sent when the SystemView Application
2542 *    is connected.
2543 *
2544 *  Parameters
2545 *    pInfo - Struct containing all possible properties that can be sent via this registration event.
2546 */
SEGGER_SYSVIEW_RegisterData(SEGGER_SYSVIEW_DATA_REGISTER * pInfo)2547 void SEGGER_SYSVIEW_RegisterData(SEGGER_SYSVIEW_DATA_REGISTER* pInfo) {
2548   U8* pPayload;
2549   U8* pPayloadStart;
2550   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 8 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2551   //
2552   pPayload = pPayloadStart;
2553   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_REGISTER_DATA);
2554   ENCODE_U32(pPayload, pInfo->ID);
2555   pPayload = _EncodeStr(pPayload, pInfo->sName, SEGGER_SYSVIEW_MAX_STRING_LEN);
2556 
2557   if (pInfo->sUnit != 0) {
2558     ENCODE_U32(pPayload, pInfo->DataType);
2559     ENCODE_U32(pPayload, pInfo->Offset);
2560     ENCODE_U32(pPayload, pInfo->RangeMin);
2561     ENCODE_U32(pPayload, pInfo->RangeMax);
2562     pPayload = _EncodeFloat(pPayload, pInfo->ScalingFactor);
2563     pPayload = _EncodeStr(pPayload, pInfo->sUnit, SEGGER_SYSVIEW_MAX_STRING_LEN);
2564   } else if (pInfo->ScalingFactor != 0) {
2565     ENCODE_U32(pPayload, pInfo->DataType);
2566     ENCODE_U32(pPayload, pInfo->Offset);
2567     ENCODE_U32(pPayload, pInfo->RangeMin);
2568     ENCODE_U32(pPayload, pInfo->RangeMax);
2569     pPayload = _EncodeFloat(pPayload, pInfo->ScalingFactor);
2570   } else if (pInfo->RangeMax != 0) {
2571     ENCODE_U32(pPayload, pInfo->DataType);
2572     ENCODE_U32(pPayload, pInfo->Offset);
2573     ENCODE_U32(pPayload, pInfo->RangeMin);
2574     ENCODE_U32(pPayload, pInfo->RangeMax);
2575   } else if (pInfo->RangeMin != 0) {
2576     ENCODE_U32(pPayload, pInfo->DataType);
2577     ENCODE_U32(pPayload, pInfo->Offset);
2578     ENCODE_U32(pPayload, pInfo->RangeMin);
2579   } else if (pInfo->Offset != 0) {
2580     ENCODE_U32(pPayload, pInfo->DataType);
2581     ENCODE_U32(pPayload, pInfo->Offset);
2582   } else if (pInfo->DataType != 0) {
2583     ENCODE_U32(pPayload, pInfo->DataType);
2584   }
2585 
2586   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2587   RECORD_END();
2588 }
2589 
2590 /*********************************************************************
2591 *
2592 *       SEGGER_SYSVIEW_HeapDefine()
2593 *
2594 *  Function description
2595 *    Define heap.
2596 *
2597 *  Parameters
2598 *    pHeap        - Pointer to heap control structure.
2599 *    pBase        - Pointer to managed heap memory.
2600 *    HeapSize     - Size of managed heap memory in bytes.
2601 *    MetadataSize - Size of metadata associated with each heap allocation.
2602 *
2603 *  Additional information
2604 *    SystemView can track allocations across multiple heaps.
2605 *
2606 *    HeapSize must be a multiple of the natural alignment unit of the
2607 *    target.  This size is subject to compression, controlled by the
2608 *    specific setting of SEGGER_SYSVIEW_ID_SHIFT.
2609 *
2610 *    MetadataSize defines the size of the per-allocation metadata.
2611 *    For many heap implementations, the metadata size is a multiple of
2612 *    the word size of the machine and typically contains the size
2613 *    of the allocated block (used upon deallocation), optional
2614 *    pointers to the preceding and/or following blocks, and optionally
2615 *    a tag identifying the owner of the block.  Note that MetadataSize
2616 *    is not compressed within the SystemView packet and is not
2617 *    required to be a multiple of 1<<SEGGER_SYSVIEW_ID_SHIFT.
2618 */
SEGGER_SYSVIEW_HeapDefine(void * pHeap,void * pBase,unsigned int HeapSize,unsigned int MetadataSize)2619 void SEGGER_SYSVIEW_HeapDefine(void* pHeap, void *pBase, unsigned int HeapSize, unsigned int MetadataSize) {
2620   U8* pPayload;
2621   U8* pPayloadStart;
2622   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
2623   //
2624   pPayload = pPayloadStart;
2625   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_DEFINE);
2626   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2627   ENCODE_U32(pPayload, SHRINK_ID((U32)pBase));
2628   ENCODE_U32(pPayload, HeapSize >> SEGGER_SYSVIEW_ID_SHIFT);
2629   ENCODE_U32(pPayload, MetadataSize);
2630   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2631   RECORD_END();
2632 }
2633 
2634 /*********************************************************************
2635 *
2636 *       SEGGER_SYSVIEW_HeapAlloc()
2637 *
2638 *  Function description
2639 *    Record a system-heap allocation event.
2640 *
2641 *  Parameters
2642 *    pHeap       - Pointer to heap where allocation was made.
2643 *    pUserData   - Pointer to allocated user data.
2644 *    UserDataLen - Size of block allocated to hold user data, excluding any metadata.
2645 *
2646 *  Additional information
2647 *    The user data must be correctly aligned for the architecture, which
2648 *    typically requires that the alignment is at least the alignment
2649 *    of a double or a long long.  pUserData is, therefore, compressed by
2650 *    shrinking as IDs are compressed, controlled by the specific setting
2651 *    of SEGGER_SYSVIEW_ID_SHIFT.
2652 *
2653 *    In the same way, UserDataLen must reflect the size of the allocated
2654 *    block, not the allocation size requested by the application.  This
2655 *    size is also subject to compression, controlled by the specific setting
2656 *    of SEGGER_SYSVIEW_ID_SHIFT.
2657 *
2658 *    As an example, assume the allocator is running on a Cortex-M device
2659 *    with SEGGER_SYSVIEW_ID_SHIFT set to 2 (the word alignment of the device).
2660 *    If a user requests an allocation of 5 bytes, a hypothetical heap
2661 *    allocator could allocate a block with size 32 bytes for this.  The value
2662 *    of UserDataLen sent to SystemView for recording should be 32, not 5,
2663 *    and the 32 is compressed by shifting by two bits, the configured value
2664 *    of SEGGER_SYSVIEW_ID_SHIFT, and describes the number of bytes that are
2665 *    consumed from managed memory from which SystemView can calculate
2666 *    accurate heap metrics.
2667 */
SEGGER_SYSVIEW_HeapAlloc(void * pHeap,void * pUserData,unsigned int UserDataLen)2668 void SEGGER_SYSVIEW_HeapAlloc(void *pHeap, void* pUserData, unsigned int UserDataLen) {
2669   U8* pPayload;
2670   U8* pPayloadStart;
2671   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 3 * SEGGER_SYSVIEW_QUANTA_U32);
2672   //
2673   pPayload = pPayloadStart;
2674   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_ALLOC);
2675   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2676   ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData));
2677   ENCODE_U32(pPayload, UserDataLen >> SEGGER_SYSVIEW_ID_SHIFT);
2678   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2679   RECORD_END();
2680 }
2681 
2682 /*********************************************************************
2683 *
2684 *       SEGGER_SYSVIEW_HeapAllocEx()
2685 *
2686 *  Function description
2687 *    Record a per-heap allocation event.
2688 *
2689 *  Parameters
2690 *    pHeap       - Pointer to heap where allocation was made.
2691 *    pUserData   - Pointer to allocated user data.
2692 *    UserDataLen - Size of block allocated to hold user data, excluding any metadata.
2693 *    Tag         - Block tag, typically used to identify the owner of the block.
2694 *
2695 *  Additional information
2696 *    The user data must be correctly aligned for the architecture, which
2697 *    typically requires that the alignment is at least the alignment
2698 *    of a double or a long long.  pUserData is, therefore, compressed by
2699 *    shrinking as IDs are compressed, controlled by the specific setting
2700 *    of SEGGER_SYSVIEW_ID_SHIFT.
2701 *
2702 *    In the same way, UserDataLen must reflect the size of the allocated
2703 *    block, not the allocation size requested by the application.  This
2704 *    size is also subject to compression, controlled by the specific setting
2705 *    of SEGGER_SYSVIEW_ID_SHIFT.
2706 *
2707 *    As an example, assume the allocator is running on a Cortex-M device
2708 *    with SEGGER_SYSVIEW_ID_SHIFT set to 2 (the word alignment of the device).
2709 *    If a user requests an allocation of 5 bytes, a hypothetical heap
2710 *    allocator could allocate a block with size 32 bytes for this.  The value
2711 *    of UserDataLen sent to SystemView for recording should be 32, not 5,
2712 *    and the 32 is compressed by shifting by two bits, the configured value
2713 *    of SEGGER_SYSVIEW_ID_SHIFT, and describes the number of bytes that are
2714 *    consumed from managed memory from which SystemView can calculate
2715 *    accurate heap metrics.
2716 *
2717 *  See also
2718 *    SEGGER_SYSVIEW_HeapAlloc().
2719 */
SEGGER_SYSVIEW_HeapAllocEx(void * pHeap,void * pUserData,unsigned int UserDataLen,unsigned int Tag)2720 void SEGGER_SYSVIEW_HeapAllocEx(void *pHeap, void* pUserData, unsigned int UserDataLen, unsigned int Tag) {
2721   U8* pPayload;
2722   U8* pPayloadStart;
2723   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32);
2724   //
2725   pPayload = pPayloadStart;
2726   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_ALLOC_EX);
2727   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2728   ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData));
2729   ENCODE_U32(pPayload, UserDataLen >> SEGGER_SYSVIEW_ID_SHIFT);
2730   ENCODE_U32(pPayload, Tag);
2731   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2732   RECORD_END();
2733 }
2734 
2735 /*********************************************************************
2736 *
2737 *       SEGGER_SYSVIEW_HeapFree()
2738 *
2739 *  Function description
2740 *    Record a heap deallocation event.
2741 *
2742 *  Parameters
2743 *    pHeap     - Pointer to heap where allocation was made.
2744 *    pUserData - Pointer to allocated user data.
2745 *
2746 *  Additional information
2747 *    SystemViews track allocations and knows the size of the
2748 *    allocated data.
2749 */
SEGGER_SYSVIEW_HeapFree(void * pHeap,void * pUserData)2750 void SEGGER_SYSVIEW_HeapFree(void* pHeap, void* pUserData) {
2751   U8* pPayload;
2752   U8* pPayloadStart;
2753   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2754   //
2755   pPayload = pPayloadStart;
2756   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_FREE);
2757   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2758   ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData));
2759   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2760   RECORD_END();
2761 }
2762 
2763 /*********************************************************************
2764 *
2765 *       SEGGER_SYSVIEW_SendPacket()
2766 *
2767 *  Function description
2768 *    Send an event packet.
2769 *
2770 *  Parameters
2771 *    pPacket      - Pointer to the start of the packet.
2772 *    pPayloadEnd  - Pointer to the end of the payload.
2773 *                   Make sure there are at least 5 bytes free after the payload.
2774 *    EventId      - Id of the event packet.
2775 *
2776 *  Return value
2777 *    !=0:  Success, Message sent.
2778 *    ==0:  Buffer full, Message *NOT* sent.
2779 */
SEGGER_SYSVIEW_SendPacket(U8 * pPacket,U8 * pPayloadEnd,unsigned int EventId)2780 int SEGGER_SYSVIEW_SendPacket(U8* pPacket, U8* pPayloadEnd, unsigned int EventId) {
2781 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
2782   SEGGER_SYSVIEW_LOCK();
2783 #endif
2784   _SendPacket(pPacket + 4, pPayloadEnd, EventId);
2785 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
2786   SEGGER_SYSVIEW_UNLOCK();
2787 #endif
2788   return 0;
2789 }
2790 
2791 /*********************************************************************
2792 *
2793 *       SEGGER_SYSVIEW_EncodeU32()
2794 *
2795 *  Function description
2796 *    Encode a U32 in variable-length format.
2797 *
2798 *  Parameters
2799 *    pPayload - Pointer to where U32 will be encoded.
2800 *    Value    - The 32-bit value to be encoded.
2801 *
2802 *  Return value
2803 *    Pointer to the byte following the value, i.e. the first free
2804 *    byte in the payload and the next position to store payload
2805 *    content.
2806 */
SEGGER_SYSVIEW_EncodeU32(U8 * pPayload,U32 Value)2807 U8* SEGGER_SYSVIEW_EncodeU32(U8* pPayload, U32 Value) {
2808   ENCODE_U32(pPayload, Value);
2809   return pPayload;
2810 }
2811 
2812 /*********************************************************************
2813 *
2814 *       SEGGER_SYSVIEW_EncodeString()
2815 *
2816 *  Function description
2817 *    Encode a string in variable-length format.
2818 *
2819 *  Parameters
2820 *    pPayload - Pointer to where string will be encoded.
2821 *    s        - String to encode.
2822 *    MaxLen   - Maximum number of characters to encode from string.
2823 *
2824 *  Return value
2825 *    Pointer to the byte following the value, i.e. the first free
2826 *    byte in the payload and the next position to store payload
2827 *    content.
2828 *
2829 *  Additional information
2830 *    The string is encoded as a count byte followed by the contents
2831 *    of the string.
2832 *    No more than 1 + MaxLen bytes will be encoded to the payload.
2833 */
SEGGER_SYSVIEW_EncodeString(U8 * pPayload,const char * s,unsigned int MaxLen)2834 U8* SEGGER_SYSVIEW_EncodeString(U8* pPayload, const char* s, unsigned int MaxLen) {
2835   return _EncodeStr(pPayload, s, MaxLen);
2836 }
2837 
2838 /*********************************************************************
2839 *
2840 *       SEGGER_SYSVIEW_EncodeData()
2841 *
2842 *  Function description
2843 *    Encode a byte buffer in variable-length format.
2844 *
2845 *  Parameters
2846 *    pPayload - Pointer to where string will be encoded.
2847 *    pSrc     - Pointer to data buffer to be encoded.
2848 *    NumBytes - Number of bytes in the buffer to be encoded.
2849 *
2850 *  Return value
2851 *    Pointer to the byte following the value, i.e. the first free
2852 *    byte in the payload and the next position to store payload
2853 *    content.
2854 *
2855 *  Additional information
2856 *    The data is encoded as a count byte followed by the contents
2857 *    of the data buffer.
2858 *    Make sure NumBytes + 1 bytes are free for the payload.
2859 */
SEGGER_SYSVIEW_EncodeData(U8 * pPayload,const char * pSrc,unsigned int NumBytes)2860 U8* SEGGER_SYSVIEW_EncodeData(U8 *pPayload, const char* pSrc, unsigned int NumBytes) {
2861   return _EncodeData(pPayload, pSrc, NumBytes);
2862 }
2863 
2864 /*********************************************************************
2865 *
2866 *       SEGGER_SYSVIEW_EncodeId()
2867 *
2868 *  Function description
2869 *    Encode a 32-bit Id in shrunken variable-length format.
2870 *
2871 *  Parameters
2872 *    pPayload - Pointer to where the Id will be encoded.
2873 *    Id       - The 32-bit value to be encoded.
2874 *
2875 *  Return value
2876 *    Pointer to the byte following the value, i.e. the first free
2877 *    byte in the payload and the next position to store payload
2878 *    content.
2879 *
2880 *  Additional information
2881 *    The parameters to shrink an Id can be configured in
2882 *    SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
2883 *     SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
2884 *       (i.e. 0x20000000 when all Ids are an address in this RAM)
2885 *     SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
2886 *       save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
2887 */
SEGGER_SYSVIEW_EncodeId(U8 * pPayload,U32 Id)2888 U8* SEGGER_SYSVIEW_EncodeId(U8* pPayload, U32 Id) {
2889   Id = SHRINK_ID(Id);
2890   ENCODE_U32(pPayload, Id);
2891   return pPayload;
2892 }
2893 
2894 /*********************************************************************
2895 *
2896 *       SEGGER_SYSVIEW_ShrinkId()
2897 *
2898 *  Function description
2899 *    Get the shrunken value of an Id for further processing like in
2900 *    SEGGER_SYSVIEW_NameResource().
2901 *
2902 *  Parameters
2903 *    Id       - The 32-bit value to be shrunken.
2904 *
2905 *  Return value
2906 *    Shrunken Id.
2907 *
2908 *  Additional information
2909 *    The parameters to shrink an Id can be configured in
2910 *    SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
2911 *     SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
2912 *       (i.e. 0x20000000 when all Ids are an address in this RAM)
2913 *     SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
2914 *       save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
2915 */
SEGGER_SYSVIEW_ShrinkId(U32 Id)2916 U32 SEGGER_SYSVIEW_ShrinkId(U32 Id) {
2917   return SHRINK_ID(Id);
2918 }
2919 
2920 /*********************************************************************
2921 *
2922 *       SEGGER_SYSVIEW_RegisterModule()
2923 *
2924 *  Function description
2925 *    Register a middleware module for recording its events.
2926 *
2927 *  Parameters
2928 *    pModule  - The middleware module information.
2929 *
2930 *  Additional information
2931 *    SEGGER_SYSVIEW_MODULE elements:
2932 *      sDescription      - Pointer to a string containing the module name and optionally the module event description.
2933 *      NumEvents         - Number of events the module wants to register.
2934 *      EventOffset       - Offset to be added to the event Ids. Out parameter, set by this function. Do not modify after calling this function.
2935 *      pfSendModuleDesc  - Callback function pointer to send more detailed module description to SystemView Application.
2936 *      pNext             - Pointer to next registered module. Out parameter, set by this function. Do not modify after calling this function.
2937 */
SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE * pModule)2938 void SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE* pModule) {
2939   SEGGER_SYSVIEW_LOCK();
2940   if (_pFirstModule == 0) {
2941     //
2942     // No module registered, yet.
2943     // Start list with new module.
2944     // EventOffset is the base offset for modules
2945     //
2946     pModule->EventOffset = MODULE_EVENT_OFFSET;
2947     pModule->pNext = 0;
2948     _pFirstModule = pModule;
2949     _NumModules = 1;
2950   } else {
2951     //
2952     // Registreded module(s) present.
2953     // Prepend new module in list.
2954     // EventOffset set from number of events and offset of previous module.
2955     //
2956     pModule->EventOffset = _pFirstModule->EventOffset + _pFirstModule->NumEvents;
2957     pModule->pNext = _pFirstModule;
2958     _pFirstModule = pModule;
2959     _NumModules++;
2960   }
2961   SEGGER_SYSVIEW_SendModule(0);
2962   SEGGER_SYSVIEW_UNLOCK();
2963 }
2964 
2965 /*********************************************************************
2966 *
2967 *       SEGGER_SYSVIEW_RecordModuleDescription()
2968 *
2969 *  Function description
2970 *    Sends detailed information of a registered module to the host.
2971 *
2972 *  Parameters
2973 *    pModule      - Pointer to the described module.
2974 *    sDescription - Pointer to a description string.
2975 */
SEGGER_SYSVIEW_RecordModuleDescription(const SEGGER_SYSVIEW_MODULE * pModule,const char * sDescription)2976 void SEGGER_SYSVIEW_RecordModuleDescription(const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription) {
2977   U8  ModuleId;
2978   SEGGER_SYSVIEW_MODULE* p;
2979 
2980   p = _pFirstModule;
2981   ModuleId = 0;
2982   do {
2983     if (p == pModule) {
2984       break;
2985     }
2986     ModuleId++;
2987     p = p->pNext;
2988   } while (p);
2989   {
2990     U8* pPayload;
2991     U8* pPayloadStart;
2992     RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2993     //
2994     pPayload = pPayloadStart;
2995     //
2996     // Send module description
2997     // Send event offset and number of events
2998     //
2999     ENCODE_U32(pPayload, ModuleId);
3000     ENCODE_U32(pPayload, (pModule->EventOffset));
3001     pPayload = _EncodeStr(pPayload, sDescription, SEGGER_SYSVIEW_MAX_STRING_LEN);
3002     _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
3003     RECORD_END();
3004   }
3005 }
3006 
3007 /*********************************************************************
3008 *
3009 *       SEGGER_SYSVIEW_SendModule()
3010 *
3011 *  Function description
3012 *    Sends the information of a registered module to the host.
3013 *
3014 *  Parameters
3015 *    ModuleId   - Id of the requested module.
3016 */
SEGGER_SYSVIEW_SendModule(U8 ModuleId)3017 void SEGGER_SYSVIEW_SendModule(U8 ModuleId) {
3018   SEGGER_SYSVIEW_MODULE* pModule;
3019   U32 n;
3020 
3021   if (_pFirstModule != 0) {
3022     pModule = _pFirstModule;
3023     for (n = 0; n < ModuleId; n++) {
3024       pModule = pModule->pNext;
3025       if (pModule == 0) {
3026         break;
3027       }
3028     }
3029     if (pModule != 0) {
3030       U8* pPayload;
3031       U8* pPayloadStart;
3032       RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
3033       //
3034       pPayload = pPayloadStart;
3035       //
3036       // Send module description
3037       // Send event offset and number of events
3038       //
3039       ENCODE_U32(pPayload, ModuleId);
3040       ENCODE_U32(pPayload, (pModule->EventOffset));
3041       pPayload = _EncodeStr(pPayload, pModule->sModule, SEGGER_SYSVIEW_MAX_STRING_LEN);
3042       _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
3043       RECORD_END();
3044     }
3045     if (pModule && pModule->pfSendModuleDesc) {
3046       pModule->pfSendModuleDesc();
3047     }
3048   }
3049 }
3050 
3051 /*********************************************************************
3052 *
3053 *       SEGGER_SYSVIEW_SendModuleDescription()
3054 *
3055 *  Function description
3056 *    Triggers a send of the registered module descriptions.
3057 *
3058 */
SEGGER_SYSVIEW_SendModuleDescription(void)3059 void SEGGER_SYSVIEW_SendModuleDescription(void) {
3060   SEGGER_SYSVIEW_MODULE* pModule;
3061 
3062   if (_pFirstModule != 0) {
3063     pModule = _pFirstModule;
3064     do {
3065       if (pModule->pfSendModuleDesc) {
3066         pModule->pfSendModuleDesc();
3067       }
3068       pModule = pModule->pNext;
3069     } while (pModule);
3070   }
3071 }
3072 
3073 /*********************************************************************
3074 *
3075 *       SEGGER_SYSVIEW_SendNumModules()
3076 *
3077 *  Function description
3078 *    Send the number of registered modules to the host.
3079 */
SEGGER_SYSVIEW_SendNumModules(void)3080 void SEGGER_SYSVIEW_SendNumModules(void) {
3081   U8* pPayload;
3082   U8* pPayloadStart;
3083   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2*SEGGER_SYSVIEW_QUANTA_U32);
3084   pPayload = pPayloadStart;
3085   ENCODE_U32(pPayload, _NumModules);
3086   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NUMMODULES);
3087   RECORD_END();
3088 }
3089 
3090 #ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
3091 
3092 /*********************************************************************
3093 *
3094 *       SEGGER_SYSVIEW_PrintfHostEx()
3095 *
3096 *  Function description
3097 *    Print a string which is formatted on the host by the SystemView Application
3098 *    with Additional information.
3099 *
3100 *  Parameters
3101 *    s        - String to be formatted.
3102 *    Options  - Options for the string. i.e. Log level.
3103 *
3104 *  Additional information
3105 *    All format arguments are treated as 32-bit scalar values.
3106 */
SEGGER_SYSVIEW_PrintfHostEx(const char * s,U32 Options,...)3107 void SEGGER_SYSVIEW_PrintfHostEx(const char* s, U32 Options, ...) {
3108   va_list ParamList;
3109 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3110   int r;
3111 
3112   va_start(ParamList, Options);
3113   r = _VPrintHost(s, Options, &ParamList);
3114   va_end(ParamList);
3115 
3116   if (r == -1) {
3117     va_start(ParamList, Options);
3118     _VPrintTarget(s, Options, &ParamList);
3119     va_end(ParamList);
3120   }
3121 #else
3122   va_start(ParamList, Options);
3123   _VPrintHost(s, Options, &ParamList);
3124   va_end(ParamList);
3125 #endif
3126 }
3127 
3128 /*********************************************************************
3129 *
3130 *       SEGGER_SYSVIEW_VPrintfHostEx()
3131 *
3132 *  Function description
3133 *    Print a string which is formatted on the host by the SystemView Application
3134 *    with Additional information.
3135 *
3136 *  Parameters
3137 *    s          - String to be formatted.
3138 *    Options    - Options for the string. i.e. Log level.
3139 *    pParamList - Pointer to the list of arguments for the format string
3140 *
3141 *  Additional information
3142 *    All format arguments are treated as 32-bit scalar values.
3143 */
SEGGER_SYSVIEW_VPrintfHostEx(const char * s,U32 Options,va_list * pParamList)3144 void SEGGER_SYSVIEW_VPrintfHostEx(const char* s, U32 Options, va_list *pParamList) {
3145 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3146   int r;
3147   va_list ParamListCopy;
3148   va_copy(ParamListCopy, *pParamList);
3149 
3150   r = _VPrintHost(s, Options, pParamList);
3151 
3152   if (r == -1) {
3153     _VPrintTarget(s, Options, &ParamListCopy);
3154   }
3155   va_end(ParamListCopy);
3156 #else
3157   _VPrintHost(s, Options, pParamList);
3158 #endif
3159 }
3160 
3161 /*********************************************************************
3162 *
3163 *       SEGGER_SYSVIEW_PrintfHost()
3164 *
3165 *  Function description
3166 *    Print a string which is formatted on the host by the SystemView Application.
3167 *
3168 *  Parameters
3169 *    s        - String to be formatted.
3170 *
3171 *  Additional information
3172 *    All format arguments are treated as 32-bit scalar values.
3173 */
SEGGER_SYSVIEW_PrintfHost(const char * s,...)3174 void SEGGER_SYSVIEW_PrintfHost(const char* s, ...) {
3175   va_list ParamList;
3176 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3177   int r;
3178 
3179   va_start(ParamList, s);
3180   r = _VPrintHost(s, SEGGER_SYSVIEW_LOG, &ParamList);
3181   va_end(ParamList);
3182 
3183   if (r == -1) {
3184     va_start(ParamList, s);
3185     _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamList);
3186     va_end(ParamList);
3187   }
3188 #else
3189   va_start(ParamList, s);
3190   _VPrintHost(s, SEGGER_SYSVIEW_LOG, &ParamList);
3191   va_end(ParamList);
3192 #endif
3193 }
3194 
3195 /*********************************************************************
3196 *
3197 *       SEGGER_SYSVIEW_VPrintfHost()
3198 *
3199 *  Function description
3200 *    Print a string which is formatted on the host by the SystemView Application.
3201 *
3202 *  Parameters
3203 *    s          - String to be formatted.
3204 *    pParamList - Pointer to the list of arguments for the format string
3205 *
3206 *  Additional information
3207 *    All format arguments are treated as 32-bit scalar values.
3208 */
SEGGER_SYSVIEW_VPrintfHost(const char * s,va_list * pParamList)3209 void SEGGER_SYSVIEW_VPrintfHost(const char* s, va_list *pParamList) {
3210 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3211   int r;
3212   va_list ParamListCopy;
3213   va_copy(ParamListCopy, *pParamList);
3214 
3215   r = _VPrintHost(s, SEGGER_SYSVIEW_LOG, pParamList);
3216 
3217   if (r == -1) {
3218     _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamListCopy);
3219   }
3220   va_end(ParamListCopy);
3221 #else
3222   _VPrintHost(s, SEGGER_SYSVIEW_LOG, pParamList);
3223 #endif
3224 }
3225 
3226 /*********************************************************************
3227 *
3228 *       SEGGER_SYSVIEW_WarnfHost()
3229 *
3230 *  Function description
3231 *    Print a warning string which is formatted on the host by
3232 *    the SystemView Application.
3233 *
3234 *  Parameters
3235 *    s        - String to be formatted.
3236 *
3237 *  Additional information
3238 *    All format arguments are treated as 32-bit scalar values.
3239 */
SEGGER_SYSVIEW_WarnfHost(const char * s,...)3240 void SEGGER_SYSVIEW_WarnfHost(const char* s, ...) {
3241   va_list ParamList;
3242 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3243   int r;
3244 
3245   va_start(ParamList, s);
3246   r = _VPrintHost(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3247   va_end(ParamList);
3248 
3249   if (r == -1) {
3250     va_start(ParamList, s);
3251     _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3252     va_end(ParamList);
3253   }
3254 #else
3255   va_start(ParamList, s);
3256   _VPrintHost(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3257   va_end(ParamList);
3258 #endif
3259 }
3260 
3261 /*********************************************************************
3262 *
3263 *       SEGGER_SYSVIEW_VWarnfHost()
3264 *
3265 *  Function description
3266 *    Print a warning string which is formatted on the host by
3267 *    the SystemView Application.
3268 *
3269 *  Parameters
3270 *    s          - String to be formatted.
3271 *    pParamList - Pointer to the list of arguments for the format string
3272 *
3273 *  Additional information
3274 *    All format arguments are treated as 32-bit scalar values.
3275 */
SEGGER_SYSVIEW_VWarnfHost(const char * s,va_list * pParamList)3276 void SEGGER_SYSVIEW_VWarnfHost(const char* s, va_list *pParamList) {
3277 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3278   int r;
3279   va_list ParamListCopy;
3280   va_copy(ParamListCopy, *pParamList);
3281 
3282   r = _VPrintHost(s, SEGGER_SYSVIEW_WARNING, pParamList);
3283 
3284   if (r == -1) {
3285     _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamListCopy);
3286   }
3287   va_end(ParamListCopy);
3288 #else
3289   _VPrintHost(s, SEGGER_SYSVIEW_WARNING, pParamList);
3290 #endif
3291 }
3292 
3293 /*********************************************************************
3294 *
3295 *       SEGGER_SYSVIEW_ErrorfHost()
3296 *
3297 *  Function description
3298 *    Print an error string which is formatted on the host by
3299 *    the SystemView Application.
3300 *
3301 *  Parameters
3302 *    s        - String to be formatted.
3303 *
3304 *  Additional information
3305 *    All format arguments are treated as 32-bit scalar values.
3306 */
SEGGER_SYSVIEW_ErrorfHost(const char * s,...)3307 void SEGGER_SYSVIEW_ErrorfHost(const char* s, ...) {
3308   va_list ParamList;
3309 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3310   int r;
3311 
3312   va_start(ParamList, s);
3313   r = _VPrintHost(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3314   va_end(ParamList);
3315 
3316   if (r == -1) {
3317     va_start(ParamList, s);
3318     _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3319     va_end(ParamList);
3320   }
3321 #else
3322   va_start(ParamList, s);
3323   _VPrintHost(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3324   va_end(ParamList);
3325 #endif
3326 }
3327 
3328 /*********************************************************************
3329 *
3330 *       SEGGER_SYSVIEW_VErrorfHost()
3331 *
3332 *  Function description
3333 *    Print a warning string which is formatted on the host by
3334 *    the SystemView Application.
3335 *
3336 *  Parameters
3337 *    s          - String to be formatted.
3338 *    pParamList - Pointer to the list of arguments for the format string
3339 *
3340 *  Additional information
3341 *    All format arguments are treated as 32-bit scalar values.
3342 */
SEGGER_SYSVIEW_VErrorfHost(const char * s,va_list * pParamList)3343 void SEGGER_SYSVIEW_VErrorfHost(const char* s, va_list *pParamList) {
3344 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3345   int r;
3346   va_list ParamListCopy;
3347   va_copy(ParamListCopy, *pParamList);
3348 
3349   r = _VPrintHost(s, SEGGER_SYSVIEW_ERROR, pParamList);
3350 
3351   if (r == -1) {
3352     _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamListCopy);
3353   }
3354   va_end(ParamListCopy);
3355 #else
3356   _VPrintHost(s, SEGGER_SYSVIEW_ERROR, pParamList);
3357 #endif
3358 }
3359 
3360 /*********************************************************************
3361 *
3362 *       SEGGER_SYSVIEW_PrintfTargetEx()
3363 *
3364 *  Function description
3365 *    Print a string which is formatted on the target before sent to
3366 *    the host with Additional information.
3367 *
3368 *  Parameters
3369 *    s        - String to be formatted.
3370 *    Options  - Options for the string. i.e. Log level.
3371 */
SEGGER_SYSVIEW_PrintfTargetEx(const char * s,U32 Options,...)3372 void SEGGER_SYSVIEW_PrintfTargetEx(const char* s, U32 Options, ...) {
3373   va_list ParamList;
3374 
3375   va_start(ParamList, Options);
3376   _VPrintTarget(s, Options, &ParamList);
3377   va_end(ParamList);
3378 }
3379 
3380 /*********************************************************************
3381 *
3382 *       SEGGER_SYSVIEW_VPrintfTargetEx()
3383 *
3384 *  Function description
3385 *    Print a string which is formatted on the target before sent to
3386 *    the host with Additional information.
3387 *
3388 *  Parameters
3389 *    s          - String to be formatted.
3390 *    Options    - Options for the string. i.e. Log level.
3391 *    pParamList - Pointer to the list of arguments for the format string
3392 */
SEGGER_SYSVIEW_VPrintfTargetEx(const char * s,U32 Options,va_list * pParamList)3393 void SEGGER_SYSVIEW_VPrintfTargetEx(const char* s, U32 Options, va_list *pParamList) {
3394   _VPrintTarget(s, Options, pParamList);
3395 }
3396 
3397 /*********************************************************************
3398 *
3399 *       SEGGER_SYSVIEW_PrintfTarget()
3400 *
3401 *  Function description
3402 *    Print a string which is formatted on the target before sent to
3403 *    the host.
3404 *
3405 *  Parameters
3406 *    s        - String to be formatted.
3407 */
SEGGER_SYSVIEW_PrintfTarget(const char * s,...)3408 void SEGGER_SYSVIEW_PrintfTarget(const char* s, ...) {
3409   va_list ParamList;
3410 
3411   va_start(ParamList, s);
3412   _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamList);
3413   va_end(ParamList);
3414 }
3415 
3416 /*********************************************************************
3417 *
3418 *       SEGGER_SYSVIEW_VPrintfTarget()
3419 *
3420 *  Function description
3421 *    Print a string which is formatted on the target before sent to
3422 *    the host.
3423 *
3424 *  Parameters
3425 *    s          - String to be formatted.
3426 *    pParamList - Pointer to the list of arguments for the format string
3427 */
SEGGER_SYSVIEW_VPrintfTarget(const char * s,va_list * pParamList)3428 void SEGGER_SYSVIEW_VPrintfTarget(const char* s, va_list* pParamList) {
3429   _VPrintTarget(s, SEGGER_SYSVIEW_LOG, pParamList);
3430 }
3431 
3432 /*********************************************************************
3433 *
3434 *       SEGGER_SYSVIEW_WarnfTarget()
3435 *
3436 *  Function description
3437 *    Print a warning string which is formatted on the target before
3438 *    sent to the host.
3439 *
3440 *  Parameters
3441 *    s        - String to be formatted.
3442 */
SEGGER_SYSVIEW_WarnfTarget(const char * s,...)3443 void SEGGER_SYSVIEW_WarnfTarget(const char* s, ...) {
3444   va_list ParamList;
3445 
3446   va_start(ParamList, s);
3447   _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3448   va_end(ParamList);
3449 }
3450 
3451 /*********************************************************************
3452 *
3453 *       SEGGER_SYSVIEW_VWarnfTarget()
3454 *
3455 *  Function description
3456 *    Print a warning string which is formatted on the target before
3457 *    sent to the host.
3458 *
3459 *  Parameters
3460 *    s          - String to be formatted.
3461 *    pParamList - Pointer to the list of arguments for the format string
3462 */
SEGGER_SYSVIEW_VWarnfTarget(const char * s,va_list * pParamList)3463 void SEGGER_SYSVIEW_VWarnfTarget(const char* s, va_list* pParamList) {
3464   _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, pParamList);
3465 }
3466 
3467 /*********************************************************************
3468 *
3469 *       SEGGER_SYSVIEW_ErrorfTarget()
3470 *
3471 *  Function description
3472 *    Print an error string which is formatted on the target before
3473 *    sent to the host.
3474 *
3475 *  Parameters
3476 *    s        - String to be formatted.
3477 */
SEGGER_SYSVIEW_ErrorfTarget(const char * s,...)3478 void SEGGER_SYSVIEW_ErrorfTarget(const char* s, ...) {
3479   va_list ParamList;
3480 
3481   va_start(ParamList, s);
3482   _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3483   va_end(ParamList);
3484 }
3485 
3486 /*********************************************************************
3487 *
3488 *       SEGGER_SYSVIEW_VErrorfTarget()
3489 *
3490 *  Function description
3491 *    Print an error string which is formatted on the target before
3492 *    sent to the host.
3493 *
3494 *  Parameters
3495 *    s          - String to be formatted.
3496 *    pParamList - Pointer to the list of arguments for the format string
3497 */
SEGGER_SYSVIEW_VErrorfTarget(const char * s,va_list * pParamList)3498 void SEGGER_SYSVIEW_VErrorfTarget(const char* s, va_list* pParamList) {
3499   _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, pParamList);
3500 }
3501 #endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
3502 
3503 /*********************************************************************
3504 *
3505 *       SEGGER_SYSVIEW_Print()
3506 *
3507 *  Function description
3508 *    Print a string to the host.
3509 *
3510 *  Parameters
3511 *    s        - String to sent.
3512 */
SEGGER_SYSVIEW_Print(const char * s)3513 void SEGGER_SYSVIEW_Print(const char* s) {
3514   U8* pPayload;
3515   U8* pPayloadStart;
3516   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
3517   //
3518   pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
3519   ENCODE_U32(pPayload, SEGGER_SYSVIEW_LOG);
3520   ENCODE_U32(pPayload, 0);
3521   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
3522   RECORD_END();
3523 }
3524 
3525 /*********************************************************************
3526 *
3527 *       SEGGER_SYSVIEW_Warn()
3528 *
3529 *  Function description
3530 *    Print a warning string to the host.
3531 *
3532 *  Parameters
3533 *    s        - String to sent.
3534 */
SEGGER_SYSVIEW_Warn(const char * s)3535 void SEGGER_SYSVIEW_Warn(const char* s) {
3536   U8* pPayload;
3537   U8* pPayloadStart;
3538   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
3539   //
3540   pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
3541   ENCODE_U32(pPayload, SEGGER_SYSVIEW_WARNING);
3542   ENCODE_U32(pPayload, 0);
3543   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
3544   RECORD_END();
3545 }
3546 
3547 /*********************************************************************
3548 *
3549 *       SEGGER_SYSVIEW_Error()
3550 *
3551 *  Function description
3552 *    Print an error string to the host.
3553 *
3554 *  Parameters
3555 *    s        - String to sent.
3556 */
SEGGER_SYSVIEW_Error(const char * s)3557 void SEGGER_SYSVIEW_Error(const char* s) {
3558   U8* pPayload;
3559   U8* pPayloadStart;
3560   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
3561   //
3562   pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
3563   ENCODE_U32(pPayload, SEGGER_SYSVIEW_ERROR);
3564   ENCODE_U32(pPayload, 0);
3565   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
3566   RECORD_END();
3567 }
3568 
3569 /*********************************************************************
3570 *
3571 *       SEGGER_SYSVIEW_EnableEvents()
3572 *
3573 *  Function description
3574 *    Enable standard SystemView events to be generated.
3575 *
3576 *  Parameters
3577 *    EnableMask   - Events to be enabled.
3578 */
SEGGER_SYSVIEW_EnableEvents(U32 EnableMask)3579 void SEGGER_SYSVIEW_EnableEvents(U32 EnableMask) {
3580   _SYSVIEW_Globals.DisabledEvents &= ~EnableMask;
3581 }
3582 
3583 /*********************************************************************
3584 *
3585 *       SEGGER_SYSVIEW_DisableEvents()
3586 *
3587 *  Function description
3588 *    Disable standard SystemView events to not be generated.
3589 *
3590 *  Parameters
3591 *    DisableMask  - Events to be disabled.
3592 */
SEGGER_SYSVIEW_DisableEvents(U32 DisableMask)3593 void SEGGER_SYSVIEW_DisableEvents(U32 DisableMask) {
3594   _SYSVIEW_Globals.DisabledEvents |= DisableMask;
3595 }
3596 
3597 /*********************************************************************
3598 *
3599 *       SEGGER_SYSVIEW_IsStarted()
3600 *
3601 *  Function description
3602 *    Handle incoming packets if any and check if recording is started.
3603 *
3604 *  Return value
3605 *      0: Recording not started.
3606 *    > 0: Recording started.
3607 */
SEGGER_SYSVIEW_IsStarted(void)3608 int SEGGER_SYSVIEW_IsStarted(void) {
3609 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
3610   //
3611   // Check if host is sending data which needs to be processed.
3612   //
3613   if (SEGGER_RTT_HASDATA(CHANNEL_ID_DOWN)) {
3614     if (_SYSVIEW_Globals.RecursionCnt == 0) {   // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
3615       _SYSVIEW_Globals.RecursionCnt = 1;
3616       _HandleIncomingPacket();
3617       _SYSVIEW_Globals.RecursionCnt = 0;
3618     }
3619   }
3620 #endif
3621   return _SYSVIEW_Globals.EnableState;
3622 }
3623 
3624 
3625 /*************************** End of file ****************************/
3626