1 /*********************************************************************
2 *                    SEGGER Microcontroller GmbH                     *
3 *                        The Embedded Experts                        *
4 **********************************************************************
5 *                                                                    *
6 *            (c) 1995 - 2021 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.40                                    *
46 *                                                                    *
47 **********************************************************************
48 -------------------------- END-OF-HEADER -----------------------------
49 
50 File    : SEGGER_SYSVIEW.c
51 Purpose : System visualization API implementation.
52 Revision: $Rev: 28341 $
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 = Value;                             \
376                                    while(SysViewData > 0x7F) {                      \
377                                      *pSysviewPointer++ = (U8)(SysViewData | 0x80); \
378                                      SysViewData >>= 7;                             \
379                                    };                                               \
380                                    *pSysviewPointer++ = (U8)SysViewData;            \
381                                    pDest = pSysviewPointer;                         \
382                                  };
383 
384 
385 
386 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
387 static U8 _aPacket[SEGGER_SYSVIEW_MAX_PACKET_SIZE];
388 
389 #define RECORD_START(PacketSize)  SEGGER_SYSVIEW_LOCK();                            \
390                                   pPayloadStart = _PreparePacket(_aPacket);
391 
392 #define RECORD_END()              SEGGER_SYSVIEW_UNLOCK()
393 
394 #else
395 
396 #define RECORD_START(PacketSize)  U8 aPacket[(PacketSize)];                         \
397                                   pPayloadStart = _PreparePacket(aPacket);          \
398 
399 #define RECORD_END()
400 
401 #endif
402 
403 /*********************************************************************
404 *
405 *       _EncodeData()
406 *
407 *  Function description
408 *    Encode a byte buffer in variable-length format.
409 *
410 *  Parameters
411 *    pPayload - Pointer to where string will be encoded.
412 *    pSrc     - Pointer to data buffer to be encoded.
413 *    NumBytes - Number of bytes in the buffer to be encoded.
414 *
415 *  Return value
416 *    Pointer to the byte following the value, i.e. the first free
417 *    byte in the payload and the next position to store payload
418 *    content.
419 *
420 *  Additional information
421 *    The data is encoded as a count byte followed by the contents
422 *    of the data buffer.
423 *    Make sure NumBytes + 1 bytes are free for the payload.
424 */
_EncodeData(U8 * pPayload,const char * pSrc,unsigned int NumBytes)425 static U8* _EncodeData(U8* pPayload, const char* pSrc, unsigned int NumBytes) {
426   unsigned int  n;
427   const U8*     p;
428   //
429   n = 0;
430   p = (const U8*)pSrc;
431   //
432   // Write Len
433   //
434   if (NumBytes < 255)  {
435     *pPayload++ = (U8)NumBytes;
436   } else {
437     *pPayload++ = 255;
438     *pPayload++ = (NumBytes & 255);
439     *pPayload++ = ((NumBytes >> 8) & 255);
440   }
441   while (n < NumBytes) {
442     *pPayload++ = *p++;
443     n++;
444   }
445   return pPayload;
446 }
447 
448 /*********************************************************************
449 *
450 *       _EncodeStr()
451 *
452 *  Function description
453 *    Encode a string in variable-length format.
454 *
455 *  Parameters
456 *    pPayload - Pointer to where string will be encoded.
457 *    pText    - String to encode.
458 *    Limit    - Maximum number of characters to encode from string.
459 *
460 *  Return value
461 *    Pointer to the byte following the value, i.e. the first free
462 *    byte in the payload and the next position to store payload
463 *    content.
464 *
465 *  Additional information
466 *    The string is encoded as a count byte followed by the contents
467 *    of the string.
468 *    No more than 1 + Limit bytes will be encoded to the payload.
469 */
_EncodeStr(U8 * pPayload,const char * pText,unsigned int Limit)470 static U8 *_EncodeStr(U8 *pPayload, const char *pText, unsigned int Limit) {
471   unsigned int n;
472   unsigned int Len;
473   //
474   // Compute string len
475   //
476   Len = 0;
477   if (pText != NULL) {
478     while(*(pText + Len) != 0) {
479       Len++;
480     }
481     if (Len > Limit) {
482       Len = Limit;
483     }
484   }
485   //
486   // Write Len
487   //
488   if (Len < 255)  {
489     *pPayload++ = (U8)Len;
490   } else {
491     *pPayload++ = 255;
492     *pPayload++ = (Len & 255);
493     *pPayload++ = ((Len >> 8) & 255);
494   }
495   //
496   // copy string
497   //
498   n = 0;
499   while (n < Len) {
500     *pPayload++ = *pText++;
501     n++;
502   }
503   return pPayload;
504 }
505 
506 /*********************************************************************
507 *
508 *       _PreparePacket()
509 *
510 *  Function description
511 *    Prepare a SystemView event packet header.
512 *
513 *  Parameters
514 *    pPacket - Pointer to start of packet to initialize.
515 *
516 *  Return value
517 *    Pointer to first byte of packet payload.
518 *
519 *  Additional information
520 *    The payload length and evnetId are not initialized.
521 *    PreparePacket only reserves space for them and they are
522 *    computed and filled in by the sending function.
523 */
_PreparePacket(U8 * pPacket)524 static U8* _PreparePacket(U8* pPacket) {
525   return pPacket + _MAX_ID_BYTES + _MAX_DATA_BYTES;
526 }
527 
528 /*********************************************************************
529 *
530 *       _HandleIncomingPacket()
531 *
532 *  Function description
533 *    Read an incoming command from the down channel and process it.
534 *
535 *  Additional information
536 *    This function is called each time after sending a packet.
537 *    Processing incoming packets is done asynchronous. SystemView might
538 *    already have sent event packets after the host has sent a command.
539 */
540 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
_HandleIncomingPacket(void)541 static void _HandleIncomingPacket(void) {
542   U8  Cmd;
543   unsigned int Status;
544   //
545   Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
546   if (Status > 0) {
547     switch (Cmd) {
548     case SEGGER_SYSVIEW_COMMAND_ID_START:
549       SEGGER_SYSVIEW_Start();
550       break;
551     case SEGGER_SYSVIEW_COMMAND_ID_STOP:
552       SEGGER_SYSVIEW_Stop();
553       break;
554     case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME:
555       SEGGER_SYSVIEW_RecordSystime();
556       break;
557     case SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST:
558       SEGGER_SYSVIEW_SendTaskList();
559       break;
560     case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC:
561       SEGGER_SYSVIEW_GetSysDesc();
562       break;
563     case SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES:
564       SEGGER_SYSVIEW_SendNumModules();
565       break;
566     case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC:
567       SEGGER_SYSVIEW_SendModuleDescription();
568       break;
569     case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE:
570       Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
571       if (Status > 0) {
572         SEGGER_SYSVIEW_SendModule(Cmd);
573       }
574       break;
575     case SEGGER_SYSVIEW_COMMAND_ID_HEARTBEAT:
576       break;
577     default:
578       if (Cmd >= 128) { // Unknown extended command. Dummy read its parameter.
579         SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
580       }
581       break;
582     }
583   }
584 }
585 #endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
586 
587 /*********************************************************************
588 *
589 *       _TrySendOverflowPacket()
590 *
591 *  Function description
592 *    Try to transmit an SystemView Overflow packet containing the
593 *    number of dropped packets.
594 *
595 *  Additional information
596 *    Format as follows:
597 *      01 <DropCnt><TimeStamp>  Max. packet len is 1 + 5 + 5 = 11
598 *
599 *    Example packets sent
600 *      01 20 40
601 *
602 *  Return value
603 *    !=0:  Success, Message sent (stored in RTT-Buffer)
604 *    ==0:  Buffer full, Message *NOT* stored
605 *
606 */
607 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
_TrySendOverflowPacket(void)608 static int _TrySendOverflowPacket(void) {
609   U32 TimeStamp;
610   I32 Delta;
611   int Status;
612   U8  aPacket[11];
613   U8* pPayload;
614 
615   aPacket[0] = SYSVIEW_EVTID_OVERFLOW;      // 1
616   pPayload   = &aPacket[1];
617   ENCODE_U32(pPayload, _SYSVIEW_Globals.DropCount);
618   //
619   // Compute time stamp delta and append it to packet.
620   //
621   TimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
622   Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp;
623   MAKE_DELTA_32BIT(Delta);
624   ENCODE_U32(pPayload, Delta);
625   //
626   // Try to store packet in RTT buffer and update time stamp when this was successful
627   //
628   Status = (int)SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, aPacket, (unsigned int)(pPayload - aPacket));
629   SEGGER_SYSVIEW_ON_EVENT_RECORDED(pPayload - aPacket);
630   if (Status) {
631     _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
632     _SYSVIEW_Globals.EnableState--; // EnableState has been 2, will be 1. Always.
633   } else {
634     _SYSVIEW_Globals.DropCount++;
635   }
636   //
637   return Status;
638 }
639 #endif  // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
640 
641 /*********************************************************************
642 *
643 *       _SendSyncInfo()
644 *
645 *  Function description
646 *    Send SystemView sync packet and system information in
647 *    post mortem mode.
648 *
649 *  Additional information
650 *    Sync is 10 * 0x00 without timestamp
651 */
652 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
_SendSyncInfo(void)653 static void _SendSyncInfo(void) {
654   //
655   // Add sync packet ( 10 * 0x00)
656   // Send system description
657   // Send system time
658   // Send task list
659   // Send module description
660   // Send module information
661   //
662   SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, _abSync, 10);
663   SEGGER_SYSVIEW_ON_EVENT_RECORDED(10);
664   SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
665   {
666     U8* pPayload;
667     U8* pPayloadStart;
668     RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
669     //
670     pPayload = pPayloadStart;
671     ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
672     ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
673     ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
674     ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
675     _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
676     RECORD_END();
677   }
678   if (_SYSVIEW_Globals.pfSendSysDesc) {
679     _SYSVIEW_Globals.pfSendSysDesc();
680   }
681   SEGGER_SYSVIEW_RecordSystime();
682   SEGGER_SYSVIEW_SendTaskList();
683   if (_NumModules > 0) {
684     int n;
685     SEGGER_SYSVIEW_SendNumModules();
686     for (n = 0; n < _NumModules; n++) {
687       SEGGER_SYSVIEW_SendModule(n);
688     }
689     SEGGER_SYSVIEW_SendModuleDescription();
690   }
691 }
692 #endif  // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
693 
694 /*********************************************************************
695 *
696 *       _SendPacket()
697 *
698 *  Function description
699 *    Send a SystemView packet over RTT. RTT channel and mode are
700 *    configured by macros when the SystemView component is initialized.
701 *    This function takes care of maintaining the packet drop count
702 *    and sending overflow packets when necessary.
703 *    The packet must be passed without Id and Length because this
704 *    function prepends it to the packet before transmission.
705 *
706 *  Parameters
707 *    pStartPacket - Pointer to start of packet payload.
708 *                   There must be at least 4 bytes free to prepend Id and Length.
709 *    pEndPacket   - Pointer to end of packet payload.
710 *    EventId      - Id of the event to send.
711 *
712 */
_SendPacket(U8 * pStartPacket,U8 * pEndPacket,unsigned int EventId)713 static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId) {
714   unsigned int  NumBytes;
715   U32           TimeStamp;
716   U32           Delta;
717 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
718   unsigned int  Status;
719 #endif
720 
721 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
722   SEGGER_SYSVIEW_LOCK();
723 #endif
724 
725 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
726   if (_SYSVIEW_Globals.EnableState == 0) {
727     goto SendDone;
728   }
729 #else
730   if (_SYSVIEW_Globals.EnableState == 1) {  // Enabled, no dropped packets remaining
731     goto Send;
732   }
733   if (_SYSVIEW_Globals.EnableState == 0) {
734     goto SendDone;
735   }
736   //
737   // Handle buffer full situations:
738   // Have packets been dropped before because buffer was full?
739   // In this case try to send and overflow packet.
740   //
741   if (_SYSVIEW_Globals.EnableState == 2) {
742     _TrySendOverflowPacket();
743     if (_SYSVIEW_Globals.EnableState != 1) {
744       goto SendDone;
745     }
746   }
747 Send:
748 #endif
749   //
750   // Check if event is disabled from being recorded.
751   //
752   if (EventId < 32) {
753     if (_SYSVIEW_Globals.DisabledEvents & ((U32)1u << EventId)) {
754       goto SendDone;
755     }
756   }
757   //
758   // Prepare actual packet.
759   // If it is a known packet, prepend eventId only,
760   // otherwise prepend packet length and eventId.
761   //
762   if (EventId < 24) {
763     *--pStartPacket = (U8)EventId;
764   } else {
765     //
766     // Get data length and prepend it.
767     //
768     NumBytes = (unsigned int)(pEndPacket - pStartPacket);
769 #if SEGGER_SYSVIEW_SUPPORT_LONG_DATA
770     if (NumBytes < 127) {
771       *--pStartPacket = EventId;
772     } else {
773       //
774       // Backwards U32 encode EventId.
775       //
776       if (NumBytes < (1ul << 14)) { // Encodes in 2 bytes
777         *--pStartPacket = (U8)(NumBytes >>  7);
778         *--pStartPacket = (U8)(NumBytes | 0x80);
779       } else if (NumBytes < (1ul << 21)) {    // Encodes in 3 bytes
780         *--pStartPacket = (U8)(NumBytes >> 14);
781         *--pStartPacket = (U8)((NumBytes >>  7) | 0x80);
782         *--pStartPacket = (U8)(NumBytes | 0x80);
783       } else if (NumBytes < (1ul << 28)) {    // Encodes in 4 bytes
784         *--pStartPacket = (U8)(NumBytes >> 21);
785         *--pStartPacket = (U8)((NumBytes >> 14) | 0x80);
786         *--pStartPacket = (U8)((NumBytes >>  7) | 0x80);
787         *--pStartPacket = (U8)(NumBytes | 0x80);
788       } else {                              // Encodes in 5 bytes
789         *--pStartPacket = (U8)(NumBytes >> 28);
790         *--pStartPacket = (U8)((NumBytes >> 21) | 0x80);
791         *--pStartPacket = (U8)((NumBytes >> 14) | 0x80);
792         *--pStartPacket = (U8)((NumBytes >>  7) | 0x80);
793         *--pStartPacket = (U8)(NumBytes | 0x80);
794       }
795     }
796 #else
797     if (NumBytes > 127) {
798       *--pStartPacket = (U8)(NumBytes >> 7);
799       *--pStartPacket = (U8)(NumBytes | 0x80);
800     } else {
801       *--pStartPacket = (U8)NumBytes;
802     }
803 #endif
804     //
805     // Prepend EventId.
806     //
807 #if SEGGER_SYSVIEW_SUPPORT_LONG_ID
808     if (EventId < 127) {
809       *--pStartPacket = (U8)EventId;
810     } else {
811       //
812       // Backwards U32 encode EventId.
813       //
814       if (EventId < (1u << 14)) { // Encodes in 2 bytes
815         *--pStartPacket = (U8)(EventId >>  7);
816         *--pStartPacket = (U8)(EventId | 0x80);
817       } else if (EventId < (1ul << 21)) {    // Encodes in 3 bytes
818         *--pStartPacket = (U8)(EventId >> 14);
819         *--pStartPacket = (U8)((EventId >>  7) | 0x80);
820         *--pStartPacket = (U8)(EventId | 0x80);
821       } else if (EventId < (1ul << 28)) {    // Encodes in 4 bytes
822         *--pStartPacket = (U8)(EventId >> 21);
823         *--pStartPacket = (U8)((EventId >> 14) | 0x80);
824         *--pStartPacket = (U8)((EventId >>  7) | 0x80);
825         *--pStartPacket = (U8)(EventId | 0x80);
826       } else {                              // Encodes in 5 bytes
827         *--pStartPacket = (U8)(EventId >> 28);
828         *--pStartPacket = (U8)((EventId >> 21) | 0x80);
829         *--pStartPacket = (U8)((EventId >> 14) | 0x80);
830         *--pStartPacket = (U8)((EventId >>  7) | 0x80);
831         *--pStartPacket = (U8)(EventId | 0x80);
832       }
833     }
834 #else
835     if (EventId > 127) {
836       *--pStartPacket = (U8)(EventId >> 7);
837       *--pStartPacket = (U8)(EventId | 0x80);
838     } else {
839       *--pStartPacket = (U8)EventId;
840     }
841 #endif
842   }
843   //
844   // Compute time stamp delta and append it to packet.
845   //
846   TimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
847   Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp;
848   MAKE_DELTA_32BIT(Delta);
849   ENCODE_U32(pEndPacket, Delta);
850 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
851   //
852   // Store packet in RTT buffer by overwriting old data and update time stamp
853   //
854   SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, pStartPacket, pEndPacket - pStartPacket);
855   SEGGER_SYSVIEW_ON_EVENT_RECORDED(pEndPacket - pStartPacket);
856   _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
857 #else
858   //
859   // Try to store packet in RTT buffer and update time stamp when this was successful
860   //
861   Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, pStartPacket, (unsigned int)(pEndPacket - pStartPacket));
862   SEGGER_SYSVIEW_ON_EVENT_RECORDED(pEndPacket - pStartPacket);
863   if (Status) {
864     _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
865   } else {
866     _SYSVIEW_Globals.EnableState++; // EnableState has been 1, will be 2. Always.
867   }
868 #endif
869 
870 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
871   //
872   // Add sync and system information periodically if we are in post mortem mode
873   //
874   if (_SYSVIEW_Globals.RecursionCnt == 0) {   // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
875     _SYSVIEW_Globals.RecursionCnt = 1;
876     if (_SYSVIEW_Globals.PacketCount++ & (1 << SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT)) {
877       _SendSyncInfo();
878       _SYSVIEW_Globals.PacketCount = 0;
879     }
880     _SYSVIEW_Globals.RecursionCnt = 0;
881   }
882 SendDone:
883   ; // Avoid "label at end of compound statement" error when using static buffer
884 #else
885 SendDone:
886   //
887   // Check if host is sending data which needs to be processed.
888   // Note that since this code is called for every packet, it is very time critical, so we do
889   // only what is really needed here, which is checking if there is any data
890   //
891   if (SEGGER_RTT_HASDATA(CHANNEL_ID_DOWN)) {
892     if (_SYSVIEW_Globals.RecursionCnt == 0) {   // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
893       _SYSVIEW_Globals.RecursionCnt = 1;
894       _HandleIncomingPacket();
895       _SYSVIEW_Globals.RecursionCnt = 0;
896     }
897   }
898 #endif
899   //
900 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
901   SEGGER_SYSVIEW_UNLOCK();  // We are done. Unlock and return
902 #endif
903 }
904 
905 #ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
906 /*********************************************************************
907 *
908 *       _VPrintHost()
909 *
910 *  Function description
911 *    Send a format string and its parameters to the host.
912 *
913 *  Parameters
914 *    s            Pointer to format string.
915 *    Options      Options to be sent to the host.
916 *    pParamList   Pointer to the list of arguments for the format string.
917 */
_VPrintHost(const char * s,U32 Options,va_list * pParamList)918 static int _VPrintHost(const char* s, U32 Options, va_list* pParamList) {
919   U32         aParas[SEGGER_SYSVIEW_MAX_ARGUMENTS];
920   U32*        pParas;
921   U32         NumArguments;
922   const char* p;
923   char        c;
924   U8*         pPayload;
925   U8*         pPayloadStart;
926 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
927   U8 HasNonScalar;
928 
929   HasNonScalar = 0;
930 #endif
931   //
932   // Count number of arguments by counting '%' characters in string.
933   // If enabled, check for non-scalar modifier flags to format string on the target.
934   //
935   p = s;
936   NumArguments = 0;
937   for (;;) {
938     c = *p++;
939     if (c == 0) {
940       break;
941     }
942     if (c == '%') {
943       c = *p;
944 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT == 0
945       aParas[NumArguments++] = (U32)(va_arg(*pParamList, int));
946       if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) {
947         break;
948       }
949 #else
950       if (c == 's') {
951         HasNonScalar = 1;
952         break;
953       } else {
954         aParas[NumArguments++] = (U32)(va_arg(*pParamList, int));
955         if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) {
956           break;
957         }
958       }
959 #endif
960     }
961   }
962 
963 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
964   if (HasNonScalar) {
965     return -1;
966   }
967 #endif
968   //
969   // Send string and parameters to host
970   //
971   {
972     RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32);
973     pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
974     ENCODE_U32(pPayload, Options);
975     ENCODE_U32(pPayload, NumArguments);
976     pParas = aParas;
977     while (NumArguments--) {
978       ENCODE_U32(pPayload, (*pParas));
979       pParas++;
980     }
981     _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
982     RECORD_END();
983   }
984   return 0;
985 }
986 
987 /*********************************************************************
988 *
989 *       _StoreChar()
990 *
991 *  Function description
992 *    Stores a character in the printf-buffer and sends the buffer when
993 *     it is filled.
994 *
995 *  Parameters
996 *    p            Pointer to the buffer description.
997 *    c            Character to be printed.
998 */
_StoreChar(SEGGER_SYSVIEW_PRINTF_DESC * p,char c)999 static void _StoreChar(SEGGER_SYSVIEW_PRINTF_DESC * p, char c) {
1000   unsigned int  Cnt;
1001   U8*           pPayload;
1002   U32           Options;
1003 
1004   Cnt = p->Cnt;
1005   if ((Cnt + 1u) <= SEGGER_SYSVIEW_MAX_STRING_LEN) {
1006     *(p->pPayload++) = (U8)c;
1007     p->Cnt = Cnt + 1u;
1008   }
1009   //
1010   // Write part of string, when the buffer is full
1011   //
1012   if (p->Cnt == SEGGER_SYSVIEW_MAX_STRING_LEN) {
1013     *(p->pPayloadStart) = (U8)p->Cnt;
1014     pPayload = p->pPayload;
1015     Options = p->Options;
1016     ENCODE_U32(pPayload, Options);
1017     ENCODE_U32(pPayload, 0);
1018     _SendPacket(p->pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
1019     p->pPayloadStart = _PreparePacket(p->pBuffer);
1020     p->pPayload = p->pPayloadStart + 1u;
1021     p->Cnt = 0u;
1022   }
1023 }
1024 
1025 /*********************************************************************
1026 *
1027 *       _PrintUnsigned()
1028 *
1029 *  Function description
1030 *    Print an unsigned integer with the given formatting into the
1031 *     formatted string.
1032 *
1033 *  Parameters
1034 *    pBufferDesc  Pointer to the buffer description.
1035 *    v            Value to be printed.
1036 *    Base         Base of the value.
1037 *    NumDigits    Number of digits to be printed.
1038 *    FieldWidth   Width of the printed field.
1039 *    FormatFlags  Flags for formatting the value.
1040 */
_PrintUnsigned(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc,unsigned int v,unsigned int Base,unsigned int NumDigits,unsigned int FieldWidth,unsigned int FormatFlags)1041 static void _PrintUnsigned(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, unsigned int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
1042   static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1043   unsigned int      Div;
1044   unsigned int      Digit;
1045   unsigned int      Number;
1046   unsigned int      Width;
1047   char              c;
1048 
1049   Number = v;
1050   Digit = 1u;
1051   //
1052   // Get actual field width
1053   //
1054   Width = 1u;
1055   while (Number >= Base) {
1056     Number = (Number / Base);
1057     Width++;
1058   }
1059   if (NumDigits > Width) {
1060     Width = NumDigits;
1061   }
1062   //
1063   // Print leading chars if necessary
1064   //
1065   if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
1066     if (FieldWidth != 0u) {
1067       if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
1068         c = '0';
1069       } else {
1070         c = ' ';
1071       }
1072       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1073         FieldWidth--;
1074         _StoreChar(pBufferDesc, c);
1075       }
1076     }
1077   }
1078   //
1079   // Compute Digit.
1080   // Loop until Digit has the value of the highest digit required.
1081   // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
1082   //
1083   while (1) {
1084     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)
1085       NumDigits--;
1086     } else {
1087       Div = v / Digit;
1088       if (Div < Base) {        // Is our divider big enough to extract the highest digit from value? => Done
1089         break;
1090       }
1091     }
1092     Digit *= Base;
1093   }
1094   //
1095   // Output digits
1096   //
1097   do {
1098     Div = v / Digit;
1099     v -= Div * Digit;
1100     _StoreChar(pBufferDesc, _aV2C[Div]);
1101     Digit /= Base;
1102   } while (Digit);
1103   //
1104   // Print trailing spaces if necessary
1105   //
1106   if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
1107     if (FieldWidth != 0u) {
1108       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1109         FieldWidth--;
1110         _StoreChar(pBufferDesc, ' ');
1111       }
1112     }
1113   }
1114 }
1115 
1116 /*********************************************************************
1117 *
1118 *       _PrintInt()
1119 *
1120 *  Function description
1121 *    Print a signed integer with the given formatting into the
1122 *     formatted string.
1123 *
1124 *  Parameters
1125 *    pBufferDesc  Pointer to the buffer description.
1126 *    v            Value to be printed.
1127 *    Base         Base of the value.
1128 *    NumDigits    Number of digits to be printed.
1129 *    FieldWidth   Width of the printed field.
1130 *    FormatFlags  Flags for formatting the value.
1131 */
_PrintInt(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc,int v,unsigned int Base,unsigned int NumDigits,unsigned int FieldWidth,unsigned int FormatFlags)1132 static void _PrintInt(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
1133   unsigned int  Width;
1134   int           Number;
1135 
1136   Number = (v < 0) ? -v : v;
1137 
1138   //
1139   // Get actual field width
1140   //
1141   Width = 1u;
1142   while (Number >= (int)Base) {
1143     Number = (Number / (int)Base);
1144     Width++;
1145   }
1146   if (NumDigits > Width) {
1147     Width = NumDigits;
1148   }
1149   if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
1150     FieldWidth--;
1151   }
1152 
1153   //
1154   // Print leading spaces if necessary
1155   //
1156   if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
1157     if (FieldWidth != 0u) {
1158       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1159         FieldWidth--;
1160         _StoreChar(pBufferDesc, ' ');
1161       }
1162     }
1163   }
1164   //
1165   // Print sign if necessary
1166   //
1167   if (v < 0) {
1168     v = -v;
1169     _StoreChar(pBufferDesc, '-');
1170   } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
1171     _StoreChar(pBufferDesc, '+');
1172   } else {
1173 
1174   }
1175   //
1176   // Print leading zeros if necessary
1177   //
1178   if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
1179     if (FieldWidth != 0u) {
1180       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
1181         FieldWidth--;
1182         _StoreChar(pBufferDesc, '0');
1183       }
1184     }
1185   }
1186   //
1187   // Print number without sign
1188   //
1189   _PrintUnsigned(pBufferDesc, (unsigned int)v, Base, NumDigits, FieldWidth, FormatFlags);
1190 }
1191 
1192 /*********************************************************************
1193 *
1194 *       _VPrintTarget()
1195 *
1196 *  Function description
1197 *    Stores a formatted string.
1198 *    This data is read by the host.
1199 *
1200 *  Parameters
1201 *    sFormat      Pointer to format string.
1202 *    Options      Options to be sent to the host.
1203 *    pParamList   Pointer to the list of arguments for the format string.
1204 */
_VPrintTarget(const char * sFormat,U32 Options,va_list * pParamList)1205 static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) {
1206   SEGGER_SYSVIEW_PRINTF_DESC BufferDesc;
1207   char          c;
1208   int           v;
1209   unsigned int  NumDigits;
1210   unsigned int  FormatFlags;
1211   unsigned int  FieldWidth;
1212   U8*           pPayloadStart;
1213 #if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
1214   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
1215   SEGGER_SYSVIEW_LOCK();
1216 #else
1217   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
1218 #endif
1219 
1220 #if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
1221   BufferDesc.pBuffer        = aPacket;
1222 #else
1223   BufferDesc.pBuffer        = _aPacket;
1224 #endif
1225   BufferDesc.Cnt            = 0u;
1226   BufferDesc.pPayloadStart  = pPayloadStart;
1227   BufferDesc.pPayload       = BufferDesc.pPayloadStart + 1u;
1228   BufferDesc.Options        =  Options;
1229 
1230   do {
1231     c = *sFormat;
1232     sFormat++;
1233     if (c == 0u) {
1234       break;
1235     }
1236     if (c == '%') {
1237       //
1238       // Filter out flags
1239       //
1240       FormatFlags = 0u;
1241       v = 1;
1242       do {
1243         c = *sFormat;
1244         switch (c) {
1245         case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
1246         case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO;     sFormat++; break;
1247         case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN;   sFormat++; break;
1248         case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE;    sFormat++; break;
1249         default:  v = 0; break;
1250         }
1251       } while (v);
1252       //
1253       // filter out field with
1254       //
1255       FieldWidth = 0u;
1256       do {
1257         c = *sFormat;
1258         if ((c < '0') || (c > '9')) {
1259           break;
1260         }
1261         sFormat++;
1262         FieldWidth = (FieldWidth * 10u) + ((unsigned int)c - '0');
1263       } while (1);
1264 
1265       //
1266       // Filter out precision (number of digits to display)
1267       //
1268       NumDigits = 0u;
1269       c = *sFormat;
1270       if (c == '.') {
1271         sFormat++;
1272         do {
1273           c = *sFormat;
1274           if ((c < '0') || (c > '9')) {
1275             break;
1276           }
1277           sFormat++;
1278           NumDigits = NumDigits * 10u + ((unsigned int)c - '0');
1279         } while (1);
1280       }
1281       //
1282       // Filter out length modifier
1283       //
1284       c = *sFormat;
1285       do {
1286         if ((c == 'l') || (c == 'h')) {
1287           c = *sFormat;
1288           sFormat++;
1289         } else {
1290           break;
1291         }
1292       } while (1);
1293       //
1294       // Handle specifiers
1295       //
1296       switch (c) {
1297       case 'c': {
1298         char c0;
1299         v = va_arg(*pParamList, int);
1300         c0 = (char)v;
1301         _StoreChar(&BufferDesc, c0);
1302         break;
1303       }
1304       case 'd':
1305         v = va_arg(*pParamList, int);
1306         _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
1307         break;
1308       case 'u':
1309         v = va_arg(*pParamList, int);
1310         _PrintUnsigned(&BufferDesc, (unsigned int)v, 10u, NumDigits, FieldWidth, FormatFlags);
1311         break;
1312       case 'x':
1313       case 'X':
1314         v = va_arg(*pParamList, int);
1315         _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, NumDigits, FieldWidth, FormatFlags);
1316         break;
1317       case 'p':
1318         v = va_arg(*pParamList, int);
1319         _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, 8u, 8u, 0u);
1320         break;
1321       case '%':
1322         _StoreChar(&BufferDesc, '%');
1323         break;
1324       default:
1325         break;
1326       }
1327       sFormat++;
1328     } else {
1329       _StoreChar(&BufferDesc, c);
1330     }
1331   } while (*sFormat);
1332 
1333   //
1334   // Write remaining data, if any
1335   //
1336   if (BufferDesc.Cnt != 0u) {
1337     *(BufferDesc.pPayloadStart) = (U8)BufferDesc.Cnt;
1338     ENCODE_U32(BufferDesc.pPayload, BufferDesc.Options);
1339     ENCODE_U32(BufferDesc.pPayload, 0);
1340     _SendPacket(BufferDesc.pPayloadStart, BufferDesc.pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
1341   }
1342 #if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
1343   SEGGER_SYSVIEW_UNLOCK();
1344   RECORD_END();
1345 #else
1346   RECORD_END();
1347 #endif
1348 }
1349 #endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
1350 
1351 /*********************************************************************
1352 *
1353 *       Public code
1354 *
1355 **********************************************************************
1356 */
1357 
1358 /*********************************************************************
1359 *
1360 *       SEGGER_SYSVIEW_Init()
1361 *
1362 *  Function description
1363 *    Initializes the SYSVIEW module.
1364 *    Must be called before the SystemView Application connects to
1365 *    the system.
1366 *
1367 *  Parameters
1368 *    SysFreq        - Frequency of timestamp, usually CPU core clock frequency.
1369 *    CPUFreq        - CPU core clock frequency.
1370 *    pOSAPI         - Pointer to the API structure for OS-specific functions.
1371 *    pfSendSysDesc  - Pointer to record system description callback function.
1372 *
1373 *  Additional information
1374 *    This function initializes the RTT channel used to transport
1375 *    SEGGER SystemView packets.
1376 *    The channel is assigned the label "SysView" for client software
1377 *    to identify the SystemView channel.
1378 *
1379 *    The channel is configured with the macro SEGGER_SYSVIEW_RTT_CHANNEL.
1380 */
SEGGER_SYSVIEW_Init(U32 SysFreq,U32 CPUFreq,const SEGGER_SYSVIEW_OS_API * pOSAPI,SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc)1381 void SEGGER_SYSVIEW_Init(U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc) {
1382 #ifdef SEGGER_RTT_SECTION
1383   //
1384   // Explicitly initialize the RTT Control Block if it is in its dedicated section.
1385   //
1386   SEGGER_RTT_Init();
1387 #endif
1388 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1389 #if SEGGER_SYSVIEW_RTT_CHANNEL > 0
1390   SEGGER_RTT_ConfigUpBuffer(SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1391 #else
1392   _SYSVIEW_Globals.UpChannel = (U8)SEGGER_RTT_AllocUpBuffer  ("SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1393 #endif
1394   _SYSVIEW_Globals.RAMBaseAddress   = SEGGER_SYSVIEW_ID_BASE;
1395   _SYSVIEW_Globals.LastTxTimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
1396   _SYSVIEW_Globals.pOSAPI           = pOSAPI;
1397   _SYSVIEW_Globals.SysFreq          = SysFreq;
1398   _SYSVIEW_Globals.CPUFreq          = CPUFreq;
1399   _SYSVIEW_Globals.pfSendSysDesc    = pfSendSysDesc;
1400   _SYSVIEW_Globals.EnableState      = 0;
1401   _SYSVIEW_Globals.PacketCount      = 0;
1402 #else // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1403 #if SEGGER_SYSVIEW_RTT_CHANNEL > 0
1404   SEGGER_RTT_ConfigUpBuffer   (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1405   SEGGER_RTT_ConfigDownBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1406 #else
1407   _SYSVIEW_Globals.UpChannel = (U8)SEGGER_RTT_AllocUpBuffer  ("SysView", &_UpBuffer[0],   sizeof(_UpBuffer),   SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1408   _SYSVIEW_Globals.DownChannel = _SYSVIEW_Globals.UpChannel;
1409   SEGGER_RTT_ConfigDownBuffer (_SYSVIEW_Globals.DownChannel, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
1410 #endif
1411   _SYSVIEW_Globals.RAMBaseAddress   = SEGGER_SYSVIEW_ID_BASE;
1412   _SYSVIEW_Globals.LastTxTimeStamp  = SEGGER_SYSVIEW_GET_TIMESTAMP();
1413   _SYSVIEW_Globals.pOSAPI           = pOSAPI;
1414   _SYSVIEW_Globals.SysFreq          = SysFreq;
1415   _SYSVIEW_Globals.CPUFreq          = CPUFreq;
1416   _SYSVIEW_Globals.pfSendSysDesc    = pfSendSysDesc;
1417   _SYSVIEW_Globals.EnableState      = 0;
1418 #endif  // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1419 }
1420 
1421 /*********************************************************************
1422 *
1423 *       SEGGER_SYSVIEW_SetRAMBase()
1424 *
1425 *  Function description
1426 *    Sets the RAM base address, which is subtracted from IDs in order
1427 *     to save bandwidth.
1428 *
1429 *  Parameters
1430 *    RAMBaseAddress - Lowest RAM Address. (i.e. 0x20000000 on most Cortex-M)
1431 */
SEGGER_SYSVIEW_SetRAMBase(U32 RAMBaseAddress)1432 void SEGGER_SYSVIEW_SetRAMBase(U32 RAMBaseAddress) {
1433   _SYSVIEW_Globals.RAMBaseAddress = RAMBaseAddress;
1434 }
1435 
1436 /*********************************************************************
1437 *
1438 *       SEGGER_SYSVIEW_RecordVoid()
1439 *
1440 *  Function description
1441 *    Formats and sends a SystemView packet with an empty payload.
1442 *
1443 *  Parameters
1444 *    EventID - SystemView event ID.
1445 */
SEGGER_SYSVIEW_RecordVoid(unsigned int EventID)1446 void SEGGER_SYSVIEW_RecordVoid(unsigned int EventID) {
1447   U8* pPayloadStart;
1448   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
1449   //
1450   _SendPacket(pPayloadStart, pPayloadStart, EventID);
1451   RECORD_END();
1452 }
1453 
1454 /*********************************************************************
1455 *
1456 *       SEGGER_SYSVIEW_RecordU32()
1457 *
1458 *  Function description
1459 *    Formats and sends a SystemView packet containing a single U32
1460 *    parameter payload.
1461 *
1462 *  Parameters
1463 *    EventID - SystemView event ID.
1464 *    Value   - The 32-bit parameter encoded to SystemView packet payload.
1465 */
SEGGER_SYSVIEW_RecordU32(unsigned int EventID,U32 Value)1466 void SEGGER_SYSVIEW_RecordU32(unsigned int EventID, U32 Value) {
1467   U8* pPayload;
1468   U8* pPayloadStart;
1469   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
1470   //
1471   pPayload = pPayloadStart;
1472   ENCODE_U32(pPayload, Value);
1473   _SendPacket(pPayloadStart, pPayload, EventID);
1474   RECORD_END();
1475 }
1476 
1477 /*********************************************************************
1478 *
1479 *       SEGGER_SYSVIEW_RecordU32x2()
1480 *
1481 *  Function description
1482 *    Formats and sends a SystemView packet containing 2 U32 parameter payload.
1483 *
1484 *  Parameters
1485 *    EventID - SystemView event ID.
1486 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1487 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1488 */
SEGGER_SYSVIEW_RecordU32x2(unsigned int EventID,U32 Para0,U32 Para1)1489 void SEGGER_SYSVIEW_RecordU32x2(unsigned int EventID, U32 Para0, U32 Para1) {
1490   U8* pPayload;
1491   U8* pPayloadStart;
1492   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
1493   //
1494   pPayload = pPayloadStart;
1495   ENCODE_U32(pPayload, Para0);
1496   ENCODE_U32(pPayload, Para1);
1497   _SendPacket(pPayloadStart, pPayload, EventID);
1498   RECORD_END();
1499 }
1500 
1501 /*********************************************************************
1502 *
1503 *       SEGGER_SYSVIEW_RecordU32x3()
1504 *
1505 *  Function description
1506 *    Formats and sends a SystemView packet containing 3 U32 parameter payload.
1507 *
1508 *  Parameters
1509 *    EventID - SystemView event ID.
1510 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1511 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1512 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1513 */
SEGGER_SYSVIEW_RecordU32x3(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2)1514 void SEGGER_SYSVIEW_RecordU32x3(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2) {
1515   U8* pPayload;
1516   U8* pPayloadStart;
1517   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 3 * SEGGER_SYSVIEW_QUANTA_U32);
1518   //
1519   pPayload = pPayloadStart;
1520   ENCODE_U32(pPayload, Para0);
1521   ENCODE_U32(pPayload, Para1);
1522   ENCODE_U32(pPayload, Para2);
1523   _SendPacket(pPayloadStart, pPayload, EventID);
1524   RECORD_END();
1525 }
1526 
1527 /*********************************************************************
1528 *
1529 *       SEGGER_SYSVIEW_RecordU32x4()
1530 *
1531 *  Function description
1532 *    Formats and sends a SystemView packet containing 4 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 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1539 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1540 */
SEGGER_SYSVIEW_RecordU32x4(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3)1541 void SEGGER_SYSVIEW_RecordU32x4(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
1542   U8* pPayload;
1543   U8* pPayloadStart;
1544   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
1545   //
1546   pPayload = pPayloadStart;
1547   ENCODE_U32(pPayload, Para0);
1548   ENCODE_U32(pPayload, Para1);
1549   ENCODE_U32(pPayload, Para2);
1550   ENCODE_U32(pPayload, Para3);
1551   _SendPacket(pPayloadStart, pPayload, EventID);
1552   RECORD_END();
1553 }
1554 
1555 /*********************************************************************
1556 *
1557 *       SEGGER_SYSVIEW_RecordU32x5()
1558 *
1559 *  Function description
1560 *    Formats and sends a SystemView packet containing 5 U32 parameter payload.
1561 *
1562 *  Parameters
1563 *    EventID - SystemView event ID.
1564 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1565 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1566 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1567 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1568 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1569 */
SEGGER_SYSVIEW_RecordU32x5(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4)1570 void SEGGER_SYSVIEW_RecordU32x5(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
1571   U8* pPayload;
1572   U8* pPayloadStart;
1573   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32);
1574   //
1575   pPayload = pPayloadStart;
1576   ENCODE_U32(pPayload, Para0);
1577   ENCODE_U32(pPayload, Para1);
1578   ENCODE_U32(pPayload, Para2);
1579   ENCODE_U32(pPayload, Para3);
1580   ENCODE_U32(pPayload, Para4);
1581   _SendPacket(pPayloadStart, pPayload, EventID);
1582   RECORD_END();
1583 }
1584 
1585 /*********************************************************************
1586 *
1587 *       SEGGER_SYSVIEW_RecordU32x6()
1588 *
1589 *  Function description
1590 *    Formats and sends a SystemView packet containing 6 U32 parameter payload.
1591 *
1592 *  Parameters
1593 *    EventID - SystemView event ID.
1594 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1595 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1596 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1597 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1598 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1599 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1600 */
SEGGER_SYSVIEW_RecordU32x6(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5)1601 void SEGGER_SYSVIEW_RecordU32x6(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5) {
1602   U8* pPayload;
1603   U8* pPayloadStart;
1604   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 6 * SEGGER_SYSVIEW_QUANTA_U32);
1605   //
1606   pPayload = pPayloadStart;
1607   ENCODE_U32(pPayload, Para0);
1608   ENCODE_U32(pPayload, Para1);
1609   ENCODE_U32(pPayload, Para2);
1610   ENCODE_U32(pPayload, Para3);
1611   ENCODE_U32(pPayload, Para4);
1612   ENCODE_U32(pPayload, Para5);
1613   _SendPacket(pPayloadStart, pPayload, EventID);
1614   RECORD_END();
1615 }
1616 
1617 /*********************************************************************
1618 *
1619 *       SEGGER_SYSVIEW_RecordU32x7()
1620 *
1621 *  Function description
1622 *    Formats and sends a SystemView packet containing 7 U32 parameter payload.
1623 *
1624 *  Parameters
1625 *    EventID - SystemView event ID.
1626 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1627 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1628 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1629 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1630 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1631 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1632 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1633 */
SEGGER_SYSVIEW_RecordU32x7(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5,U32 Para6)1634 void SEGGER_SYSVIEW_RecordU32x7(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6) {
1635   U8* pPayload;
1636   U8* pPayloadStart;
1637   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 7 * SEGGER_SYSVIEW_QUANTA_U32);
1638   //
1639   pPayload = pPayloadStart;
1640   ENCODE_U32(pPayload, Para0);
1641   ENCODE_U32(pPayload, Para1);
1642   ENCODE_U32(pPayload, Para2);
1643   ENCODE_U32(pPayload, Para3);
1644   ENCODE_U32(pPayload, Para4);
1645   ENCODE_U32(pPayload, Para5);
1646   ENCODE_U32(pPayload, Para6);
1647   _SendPacket(pPayloadStart, pPayload, EventID);
1648   RECORD_END();
1649 }
1650 
1651 /*********************************************************************
1652 *
1653 *       SEGGER_SYSVIEW_RecordU32x8()
1654 *
1655 *  Function description
1656 *    Formats and sends a SystemView packet containing 8 U32 parameter payload.
1657 *
1658 *  Parameters
1659 *    EventID - SystemView event ID.
1660 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1661 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1662 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1663 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1664 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1665 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1666 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1667 *    Para7   - The 32-bit parameter encoded to SystemView packet payload.
1668 */
SEGGER_SYSVIEW_RecordU32x8(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5,U32 Para6,U32 Para7)1669 void SEGGER_SYSVIEW_RecordU32x8(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7) {
1670   U8* pPayload;
1671   U8* pPayloadStart;
1672   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 8 * SEGGER_SYSVIEW_QUANTA_U32);
1673   //
1674   pPayload = pPayloadStart;
1675   ENCODE_U32(pPayload, Para0);
1676   ENCODE_U32(pPayload, Para1);
1677   ENCODE_U32(pPayload, Para2);
1678   ENCODE_U32(pPayload, Para3);
1679   ENCODE_U32(pPayload, Para4);
1680   ENCODE_U32(pPayload, Para5);
1681   ENCODE_U32(pPayload, Para6);
1682   ENCODE_U32(pPayload, Para7);
1683   _SendPacket(pPayloadStart, pPayload, EventID);
1684   RECORD_END();
1685 }
1686 
1687 /*********************************************************************
1688 *
1689 *       SEGGER_SYSVIEW_RecordU32x9()
1690 *
1691 *  Function description
1692 *    Formats and sends a SystemView packet containing 9 U32 parameter payload.
1693 *
1694 *  Parameters
1695 *    EventID - SystemView event ID.
1696 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1697 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1698 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1699 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1700 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1701 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1702 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1703 *    Para7   - The 32-bit parameter encoded to SystemView packet payload.
1704 *    Para8   - The 32-bit parameter encoded to SystemView packet payload.
1705 */
SEGGER_SYSVIEW_RecordU32x9(unsigned int EventID,U32 Para0,U32 Para1,U32 Para2,U32 Para3,U32 Para4,U32 Para5,U32 Para6,U32 Para7,U32 Para8)1706 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) {
1707   U8* pPayload;
1708   U8* pPayloadStart;
1709   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 9 * SEGGER_SYSVIEW_QUANTA_U32);
1710   //
1711   pPayload = pPayloadStart;
1712   ENCODE_U32(pPayload, Para0);
1713   ENCODE_U32(pPayload, Para1);
1714   ENCODE_U32(pPayload, Para2);
1715   ENCODE_U32(pPayload, Para3);
1716   ENCODE_U32(pPayload, Para4);
1717   ENCODE_U32(pPayload, Para5);
1718   ENCODE_U32(pPayload, Para6);
1719   ENCODE_U32(pPayload, Para7);
1720   ENCODE_U32(pPayload, Para8);
1721   _SendPacket(pPayloadStart, pPayload, EventID);
1722   RECORD_END();
1723 }
1724 
1725 /*********************************************************************
1726 *
1727 *       SEGGER_SYSVIEW_RecordU32x10()
1728 *
1729 *  Function description
1730 *    Formats and sends a SystemView packet containing 10 U32 parameter payload.
1731 *
1732 *  Parameters
1733 *    EventID - SystemView event ID.
1734 *    Para0   - The 32-bit parameter encoded to SystemView packet payload.
1735 *    Para1   - The 32-bit parameter encoded to SystemView packet payload.
1736 *    Para2   - The 32-bit parameter encoded to SystemView packet payload.
1737 *    Para3   - The 32-bit parameter encoded to SystemView packet payload.
1738 *    Para4   - The 32-bit parameter encoded to SystemView packet payload.
1739 *    Para5   - The 32-bit parameter encoded to SystemView packet payload.
1740 *    Para6   - The 32-bit parameter encoded to SystemView packet payload.
1741 *    Para7   - The 32-bit parameter encoded to SystemView packet payload.
1742 *    Para8   - The 32-bit parameter encoded to SystemView packet payload.
1743 *    Para9   - The 32-bit parameter encoded to SystemView packet payload.
1744 */
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)1745 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) {
1746   U8* pPayload;
1747   U8* pPayloadStart;
1748   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 10 * SEGGER_SYSVIEW_QUANTA_U32);
1749   //
1750   pPayload = pPayloadStart;
1751   ENCODE_U32(pPayload, Para0);
1752   ENCODE_U32(pPayload, Para1);
1753   ENCODE_U32(pPayload, Para2);
1754   ENCODE_U32(pPayload, Para3);
1755   ENCODE_U32(pPayload, Para4);
1756   ENCODE_U32(pPayload, Para5);
1757   ENCODE_U32(pPayload, Para6);
1758   ENCODE_U32(pPayload, Para7);
1759   ENCODE_U32(pPayload, Para8);
1760   ENCODE_U32(pPayload, Para9);
1761   _SendPacket(pPayloadStart, pPayload, EventID);
1762   RECORD_END();
1763 }
1764 /*********************************************************************
1765 *
1766 *       SEGGER_SYSVIEW_RecordString()
1767 *
1768 *  Function description
1769 *    Formats and sends a SystemView packet containing a string.
1770 *
1771 *  Parameters
1772 *    EventID - SystemView event ID.
1773 *    pString - The string to be sent in the SystemView packet payload.
1774 *
1775 *  Additional information
1776 *    The string is encoded as a count byte followed by the contents
1777 *    of the string.
1778 *    No more than SEGGER_SYSVIEW_MAX_STRING_LEN bytes will be encoded to the payload.
1779 */
SEGGER_SYSVIEW_RecordString(unsigned int EventID,const char * pString)1780 void SEGGER_SYSVIEW_RecordString(unsigned int EventID, const char* pString) {
1781   U8* pPayload;
1782   U8* pPayloadStart;
1783   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
1784   //
1785   pPayload = _EncodeStr(pPayloadStart, pString, SEGGER_SYSVIEW_MAX_STRING_LEN);
1786   _SendPacket(pPayloadStart, pPayload, EventID);
1787   RECORD_END();
1788 }
1789 
1790 /*********************************************************************
1791 *
1792 *       SEGGER_SYSVIEW_Start()
1793 *
1794 *  Function description
1795 *    Start recording SystemView events.
1796 *
1797 *    This function is triggered by the SystemView Application on connect.
1798 *    For single-shot or post-mortem mode recording, it needs to be called
1799 *    by the application.
1800 *
1801 *  Additional information
1802 *    This function enables transmission of SystemView packets recorded
1803 *    by subsequent trace calls and records a SystemView Start event.
1804 *
1805 *    As part of start, a SystemView Init packet is sent, containing the system
1806 *    frequency. The list of current tasks, the current system time and the
1807 *    system description string is sent, too.
1808 *
1809 *  Notes
1810 *    SEGGER_SYSVIEW_Start and SEGGER_SYSVIEW_Stop do not nest.
1811 *    When SEGGER_SYSVIEW_CAN_RESTART is 1, each received start command
1812 *    records the system information. This is required to enable restart
1813 *    of recordings when SystemView unexpectedly disconnects without sending
1814 *    a stop command before.
1815 */
SEGGER_SYSVIEW_Start(void)1816 void SEGGER_SYSVIEW_Start(void) {
1817 #if (SEGGER_SYSVIEW_CAN_RESTART == 0)
1818   if (_SYSVIEW_Globals.EnableState == 0) {
1819 #endif
1820     _SYSVIEW_Globals.EnableState = 1;
1821 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
1822     _SendSyncInfo();
1823 #else
1824     SEGGER_SYSVIEW_LOCK();
1825     SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, _abSync, 10);
1826     SEGGER_SYSVIEW_UNLOCK();
1827     SEGGER_SYSVIEW_ON_EVENT_RECORDED(10);
1828     SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
1829     {
1830       U8* pPayload;
1831       U8* pPayloadStart;
1832       RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
1833       //
1834       pPayload = pPayloadStart;
1835       ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
1836       ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
1837       ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
1838       ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
1839       _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
1840       RECORD_END();
1841     }
1842     if (_SYSVIEW_Globals.pfSendSysDesc) {
1843       _SYSVIEW_Globals.pfSendSysDesc();
1844     }
1845     SEGGER_SYSVIEW_RecordSystime();
1846     SEGGER_SYSVIEW_SendTaskList();
1847     SEGGER_SYSVIEW_SendNumModules();
1848 #endif
1849 #if (SEGGER_SYSVIEW_CAN_RESTART == 0)
1850   }
1851 #endif
1852 }
1853 
1854 /*********************************************************************
1855 *
1856 *       SEGGER_SYSVIEW_Stop()
1857 *
1858 *  Function description
1859 *    Stop recording SystemView events.
1860 *
1861 *    This function is triggered by the SystemView Application on disconnect.
1862 *    For single-shot or post-mortem mode recording, it can be called
1863 *    by the application.
1864 *
1865 *  Additional information
1866 *    This function disables transmission of SystemView packets recorded
1867 *    by subsequent trace calls.  If transmission is enabled when
1868 *    this function is called, a single SystemView Stop event is recorded
1869 *    to the trace, send, and then trace transmission is halted.
1870 */
SEGGER_SYSVIEW_Stop(void)1871 void SEGGER_SYSVIEW_Stop(void) {
1872   U8* pPayloadStart;
1873   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
1874   //
1875   if (_SYSVIEW_Globals.EnableState) {
1876     _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TRACE_STOP);
1877     _SYSVIEW_Globals.EnableState = 0;
1878   }
1879   RECORD_END();
1880 }
1881 
1882 /*********************************************************************
1883 *
1884 *       SEGGER_SYSVIEW_GetChannelID()
1885 *
1886 *  Function description
1887 *    Returns the RTT <Up> / <Down> channel ID used by SystemView.
1888 */
SEGGER_SYSVIEW_GetChannelID(void)1889 int SEGGER_SYSVIEW_GetChannelID(void) {
1890   return CHANNEL_ID_UP;
1891 }
1892 
1893 /*********************************************************************
1894 *
1895 *       SEGGER_SYSVIEW_GetSysDesc()
1896 *
1897 *  Function description
1898 *    Triggers a send of the system information and description.
1899 *
1900 */
SEGGER_SYSVIEW_GetSysDesc(void)1901 void SEGGER_SYSVIEW_GetSysDesc(void) {
1902   U8* pPayload;
1903   U8* pPayloadStart;
1904   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
1905   //
1906   pPayload = pPayloadStart;
1907   ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
1908   ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
1909   ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
1910   ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
1911   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
1912   RECORD_END();
1913   if (_SYSVIEW_Globals.pfSendSysDesc) {
1914     _SYSVIEW_Globals.pfSendSysDesc();
1915   }
1916 }
1917 
1918 /*********************************************************************
1919 *
1920 *       SEGGER_SYSVIEW_SendTaskInfo()
1921 *
1922 *  Function description
1923 *    Send a Task Info Packet, containing TaskId for identification,
1924 *    task priority and task name.
1925 *
1926 *  Parameters
1927 *    pInfo - Pointer to task information to send.
1928 */
SEGGER_SYSVIEW_SendTaskInfo(const SEGGER_SYSVIEW_TASKINFO * pInfo)1929 void SEGGER_SYSVIEW_SendTaskInfo(const SEGGER_SYSVIEW_TASKINFO *pInfo) {
1930   U8* pPayload;
1931   U8* pPayloadStart;
1932   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + 32);
1933   //
1934   pPayload = pPayloadStart;
1935   ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
1936   ENCODE_U32(pPayload, pInfo->Prio);
1937   pPayload = _EncodeStr(pPayload, pInfo->sName, 32);
1938   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_INFO);
1939   //
1940   pPayload = pPayloadStart;
1941   ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
1942   ENCODE_U32(pPayload, pInfo->StackBase);
1943   ENCODE_U32(pPayload, pInfo->StackSize);
1944   ENCODE_U32(pPayload, 0); // Stack End, future use
1945   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_STACK_INFO);
1946   RECORD_END();
1947 }
1948 
1949 /*********************************************************************
1950 *
1951 *       SEGGER_SYSVIEW_SendTaskList()
1952 *
1953 *  Function description
1954 *    Send all tasks descriptors to the host.
1955 */
SEGGER_SYSVIEW_SendTaskList(void)1956 void SEGGER_SYSVIEW_SendTaskList(void) {
1957   if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfSendTaskList) {
1958     _SYSVIEW_Globals.pOSAPI->pfSendTaskList();
1959   }
1960 }
1961 
1962 /*********************************************************************
1963 *
1964 *       SEGGER_SYSVIEW_SendSysDesc()
1965 *
1966 *  Function description
1967 *    Send the system description string to the host.
1968 *    The system description is used by the SystemView Application
1969 *    to identify the current application and handle events accordingly.
1970 *
1971 *    The system description is usually called by the system description
1972 *    callback, to ensure it is only sent when the SystemView Application
1973 *    is connected.
1974 *
1975 *  Parameters
1976 *    sSysDesc - Pointer to the 0-terminated system description string.
1977 *
1978 *  Additional information
1979 *    One system description string may not exceed SEGGER_SYSVIEW_MAX_STRING_LEN characters.
1980 *    Multiple description strings can be recorded.
1981 *
1982 *    The Following items can be described in a system description string.
1983 *    Each item is identified by its identifier, followed by '=' and the value.
1984 *    Items are separated by ','.
1985 */
SEGGER_SYSVIEW_SendSysDesc(const char * sSysDesc)1986 void SEGGER_SYSVIEW_SendSysDesc(const char *sSysDesc) {
1987   U8* pPayload;
1988   U8* pPayloadStart;
1989   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
1990   //
1991   pPayload = _EncodeStr(pPayloadStart, sSysDesc, SEGGER_SYSVIEW_MAX_STRING_LEN);
1992   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_SYSDESC);
1993   RECORD_END();
1994 }
1995 
1996 /*********************************************************************
1997 *
1998 *       SEGGER_SYSVIEW_RecordSystime()
1999 *
2000 *  Function description
2001 *    Formats and sends a SystemView Systime containing a single U64 or U32
2002 *    parameter payload.
2003 */
SEGGER_SYSVIEW_RecordSystime(void)2004 void SEGGER_SYSVIEW_RecordSystime(void) {
2005   U64 Systime;
2006 
2007   if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfGetTime) {
2008     Systime = _SYSVIEW_Globals.pOSAPI->pfGetTime();
2009     SEGGER_SYSVIEW_RecordU32x2(SYSVIEW_EVTID_SYSTIME_US,
2010                                (U32)(Systime),
2011                                (U32)(Systime >> 32));
2012   } else {
2013     SEGGER_SYSVIEW_RecordU32(SYSVIEW_EVTID_SYSTIME_CYCLES, SEGGER_SYSVIEW_GET_TIMESTAMP());
2014   }
2015 }
2016 
2017 /*********************************************************************
2018 *
2019 *       SEGGER_SYSVIEW_RecordEnterISR()
2020 *
2021 *  Function description
2022 *    Format and send an ISR entry event.
2023 *
2024 *  Additional information
2025 *    Example packets sent
2026 *      02 0F 50              // ISR(15) Enter. Timestamp is 80 (0x50)
2027 */
SEGGER_SYSVIEW_RecordEnterISR(void)2028 void SEGGER_SYSVIEW_RecordEnterISR(void) {
2029   unsigned v;
2030   U8* pPayload;
2031   U8* pPayloadStart;
2032   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2033   //
2034   pPayload = pPayloadStart;
2035   v = SEGGER_SYSVIEW_GET_INTERRUPT_ID();
2036   ENCODE_U32(pPayload, v);
2037   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_ISR_ENTER);
2038   RECORD_END();
2039 }
2040 
2041 /*********************************************************************
2042 *
2043 *       SEGGER_SYSVIEW_RecordExitISR()
2044 *
2045 *  Function description
2046 *    Format and send an ISR exit event.
2047 *
2048 *  Additional information
2049 *    Format as follows:
2050 *      03 <TimeStamp>        // Max. packet len is 6
2051 *
2052 *    Example packets sent
2053 *      03 20                // ISR Exit. Timestamp is 32 (0x20)
2054 */
SEGGER_SYSVIEW_RecordExitISR(void)2055 void SEGGER_SYSVIEW_RecordExitISR(void) {
2056   U8* pPayloadStart;
2057   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2058   //
2059   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_EXIT);
2060   RECORD_END();
2061 }
2062 
2063 /*********************************************************************
2064 *
2065 *       SEGGER_SYSVIEW_RecordExitISRToScheduler()
2066 *
2067 *  Function description
2068 *    Format and send an ISR exit into scheduler event.
2069 *
2070 *  Additional information
2071 *    Format as follows:
2072 *      18 <TimeStamp>        // Max. packet len is 6
2073 *
2074 *    Example packets sent
2075 *      18 20                // ISR Exit to Scheduler. Timestamp is 32 (0x20)
2076 */
SEGGER_SYSVIEW_RecordExitISRToScheduler(void)2077 void SEGGER_SYSVIEW_RecordExitISRToScheduler(void) {
2078   U8* pPayloadStart;
2079   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2080   //
2081   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_TO_SCHEDULER);
2082   RECORD_END();
2083 }
2084 
2085 /*********************************************************************
2086 *
2087 *       SEGGER_SYSVIEW_RecordEnterTimer()
2088 *
2089 *  Function description
2090 *    Format and send a Timer entry event.
2091 *
2092 *  Parameters
2093 *    TimerId - Id of the timer which starts.
2094 */
SEGGER_SYSVIEW_RecordEnterTimer(U32 TimerId)2095 void SEGGER_SYSVIEW_RecordEnterTimer(U32 TimerId) {
2096   U8* pPayload;
2097   U8* pPayloadStart;
2098   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2099   //
2100   pPayload = pPayloadStart;
2101   ENCODE_U32(pPayload, SHRINK_ID(TimerId));
2102   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TIMER_ENTER);
2103   RECORD_END();
2104 }
2105 
2106 /*********************************************************************
2107 *
2108 *       SEGGER_SYSVIEW_RecordExitTimer()
2109 *
2110 *  Function description
2111 *    Format and send a Timer exit event.
2112 */
SEGGER_SYSVIEW_RecordExitTimer(void)2113 void SEGGER_SYSVIEW_RecordExitTimer(void) {
2114   U8* pPayloadStart;
2115   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2116   //
2117   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TIMER_EXIT);
2118   RECORD_END();
2119 }
2120 
2121 /*********************************************************************
2122 *
2123 *       SEGGER_SYSVIEW_RecordEndCall()
2124 *
2125 *  Function description
2126 *    Format and send an End API Call event without return value.
2127 *
2128 *  Parameters
2129 *    EventID - Id of API function which ends.
2130 */
SEGGER_SYSVIEW_RecordEndCall(unsigned int EventID)2131 void SEGGER_SYSVIEW_RecordEndCall(unsigned int EventID) {
2132   U8* pPayload;
2133   U8* pPayloadStart;
2134   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2135   //
2136   pPayload = pPayloadStart;
2137   ENCODE_U32(pPayload, EventID);
2138   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
2139   RECORD_END();
2140 }
2141 
2142 /*********************************************************************
2143 *
2144 *       SEGGER_SYSVIEW_RecordEndCallU32()
2145 *
2146 *  Function description
2147 *    Format and send an End API Call event with return value.
2148 *
2149 *  Parameters
2150 *    EventID      - Id of API function which ends.
2151 *    Para0        - Return value which will be returned by the API function.
2152 */
SEGGER_SYSVIEW_RecordEndCallU32(unsigned int EventID,U32 Para0)2153 void SEGGER_SYSVIEW_RecordEndCallU32(unsigned int EventID, U32 Para0) {
2154   U8* pPayload;
2155   U8* pPayloadStart;
2156   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2157   //
2158   pPayload = pPayloadStart;
2159   ENCODE_U32(pPayload, EventID);
2160   ENCODE_U32(pPayload, Para0);
2161   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
2162   RECORD_END();
2163 }
2164 
2165 /*********************************************************************
2166 *
2167 *       SEGGER_SYSVIEW_OnIdle()
2168 *
2169 *  Function description
2170 *    Record an Idle event.
2171 */
SEGGER_SYSVIEW_OnIdle(void)2172 void SEGGER_SYSVIEW_OnIdle(void) {
2173   U8* pPayloadStart;
2174   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2175   //
2176   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_IDLE);
2177   RECORD_END();
2178 }
2179 
2180 /*********************************************************************
2181 *
2182 *       SEGGER_SYSVIEW_OnTaskCreate()
2183 *
2184 *  Function description
2185 *    Record a Task Create event.  The Task Create event corresponds
2186 *    to creating a task in the OS.
2187 *
2188 *  Parameters
2189 *    TaskId        - Task ID of created task.
2190 */
SEGGER_SYSVIEW_OnTaskCreate(U32 TaskId)2191 void SEGGER_SYSVIEW_OnTaskCreate(U32 TaskId) {
2192   U8* pPayload;
2193   U8* pPayloadStart;
2194   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2195   //
2196   pPayload = pPayloadStart;
2197   TaskId = SHRINK_ID(TaskId);
2198   ENCODE_U32(pPayload, TaskId);
2199   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_CREATE);
2200   RECORD_END();
2201 }
2202 
2203 /*********************************************************************
2204 *
2205 *       SEGGER_SYSVIEW_OnTaskTerminate()
2206 *
2207 *  Function description
2208 *    Record a Task termination event.
2209 *    The Task termination event corresponds to terminating a task in
2210 *    the OS. If the TaskId is the currently active task,
2211 *    SEGGER_SYSVIEW_OnTaskStopExec may be used, either.
2212 *
2213 *  Parameters
2214 *    TaskId        - Task ID of terminated task.
2215 */
SEGGER_SYSVIEW_OnTaskTerminate(U32 TaskId)2216 void SEGGER_SYSVIEW_OnTaskTerminate(U32 TaskId) {
2217   U8* pPayload;
2218   U8* pPayloadStart;
2219   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2220   //
2221   pPayload = pPayloadStart;
2222   TaskId = SHRINK_ID(TaskId);
2223   ENCODE_U32(pPayload, TaskId);
2224   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_TERMINATE);
2225   RECORD_END();
2226 }
2227 
2228 /*********************************************************************
2229 *
2230 *       SEGGER_SYSVIEW_OnTaskStartExec()
2231 *
2232 *  Function description
2233 *    Record a Task Start Execution event.  The Task Start event
2234 *    corresponds to when a task has started to execute rather than
2235 *    when it is ready to execute.
2236 *
2237 *  Parameters
2238 *    TaskId - Task ID of task that started to execute.
2239 */
SEGGER_SYSVIEW_OnTaskStartExec(U32 TaskId)2240 void SEGGER_SYSVIEW_OnTaskStartExec(U32 TaskId) {
2241   U8* pPayload;
2242   U8* pPayloadStart;
2243   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2244   //
2245   pPayload = pPayloadStart;
2246   TaskId = SHRINK_ID(TaskId);
2247   ENCODE_U32(pPayload, TaskId);
2248   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_EXEC);
2249   RECORD_END();
2250 }
2251 
2252 /*********************************************************************
2253 *
2254 *       SEGGER_SYSVIEW_OnTaskStopExec()
2255 *
2256 *  Function description
2257 *    Record a Task Stop Execution event.  The Task Stop event
2258 *    corresponds to when a task stops executing and terminates.
2259 */
SEGGER_SYSVIEW_OnTaskStopExec(void)2260 void SEGGER_SYSVIEW_OnTaskStopExec(void) {
2261   U8* pPayloadStart;
2262   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
2263   //
2264   _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TASK_STOP_EXEC);
2265   RECORD_END();
2266 }
2267 
2268 /*********************************************************************
2269 *
2270 *       SEGGER_SYSVIEW_OnTaskStartReady()
2271 *
2272 *  Function description
2273 *    Record a Task Start Ready event.
2274 *
2275 *  Parameters
2276 *    TaskId - Task ID of task that started to execute.
2277 */
SEGGER_SYSVIEW_OnTaskStartReady(U32 TaskId)2278 void SEGGER_SYSVIEW_OnTaskStartReady(U32 TaskId) {
2279   U8* pPayload;
2280   U8* pPayloadStart;
2281   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2282   //
2283   pPayload = pPayloadStart;
2284   TaskId = SHRINK_ID(TaskId);
2285   ENCODE_U32(pPayload, TaskId);
2286   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_READY);
2287   RECORD_END();
2288 }
2289 
2290 /*********************************************************************
2291 *
2292 *       SEGGER_SYSVIEW_OnTaskStopReady()
2293 *
2294 *  Function description
2295 *    Record a Task Stop Ready event.
2296 *
2297 *  Parameters
2298 *    TaskId - Task ID of task that completed execution.
2299 *    Cause  - Reason for task to stop (i.e. Idle/Sleep)
2300 */
SEGGER_SYSVIEW_OnTaskStopReady(U32 TaskId,unsigned int Cause)2301 void SEGGER_SYSVIEW_OnTaskStopReady(U32 TaskId, unsigned int Cause) {
2302   U8* pPayload;
2303   U8* pPayloadStart;
2304   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2305   //
2306   pPayload = pPayloadStart;
2307   TaskId = SHRINK_ID(TaskId);
2308   ENCODE_U32(pPayload, TaskId);
2309   ENCODE_U32(pPayload, Cause);
2310   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_STOP_READY);
2311   RECORD_END();
2312 }
2313 
2314 /*********************************************************************
2315 *
2316 *       SEGGER_SYSVIEW_MarkStart()
2317 *
2318 *  Function description
2319 *    Record a Performance Marker Start event to start measuring runtime.
2320 *
2321 *  Parameters
2322 *    MarkerId  - User defined ID for the marker.
2323 */
SEGGER_SYSVIEW_MarkStart(unsigned MarkerId)2324 void SEGGER_SYSVIEW_MarkStart(unsigned MarkerId) {
2325   U8* pPayload;
2326   U8* pPayloadStart;
2327   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2328   //
2329   pPayload = pPayloadStart;
2330   ENCODE_U32(pPayload, MarkerId);
2331   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MARK_START);
2332   RECORD_END();
2333 }
2334 
2335 /*********************************************************************
2336 *
2337 *       SEGGER_SYSVIEW_MarkStop()
2338 *
2339 *  Function description
2340 *    Record a Performance Marker Stop event to stop measuring runtime.
2341 *
2342 *  Parameters
2343 *    MarkerId  - User defined ID for the marker.
2344 */
SEGGER_SYSVIEW_MarkStop(unsigned MarkerId)2345 void SEGGER_SYSVIEW_MarkStop(unsigned MarkerId) {
2346   U8 * pPayload;
2347   U8 * pPayloadStart;
2348   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
2349   //
2350   pPayload = pPayloadStart;
2351   ENCODE_U32(pPayload, MarkerId);
2352   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MARK_STOP);
2353   RECORD_END();
2354 }
2355 
2356 /*********************************************************************
2357 *
2358 *       SEGGER_SYSVIEW_Mark()
2359 *
2360 *  Function description
2361 *    Record a Performance Marker intermediate event.
2362 *
2363 *  Parameters
2364 *    MarkerId  - User defined ID for the marker.
2365 */
SEGGER_SYSVIEW_Mark(unsigned int MarkerId)2366 void SEGGER_SYSVIEW_Mark(unsigned int MarkerId) {
2367   U8* pPayload;
2368   U8* pPayloadStart;
2369   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2370   //
2371   pPayload = pPayloadStart;
2372   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_MARK);
2373   ENCODE_U32(pPayload, MarkerId);
2374   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2375   RECORD_END();
2376 }
2377 
2378 /*********************************************************************
2379 *
2380 *       SEGGER_SYSVIEW_NameMarker()
2381 *
2382 *  Function description
2383 *    Send the name of a Performance Marker to be displayed in SystemView.
2384 *
2385 *    Marker names are usually set in the system description
2386 *    callback, to ensure it is only sent when the SystemView Application
2387 *    is connected.
2388 *
2389 *  Parameters
2390 *    MarkerId   - User defined ID for the marker.
2391 *    sName      - Pointer to the marker name. (Max. SEGGER_SYSVIEW_MAX_STRING_LEN Bytes)
2392 */
SEGGER_SYSVIEW_NameMarker(unsigned int MarkerId,const char * sName)2393 void SEGGER_SYSVIEW_NameMarker(unsigned int MarkerId, const char* sName) {
2394   U8* pPayload;
2395   U8* pPayloadStart;
2396   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2397   //
2398   pPayload = pPayloadStart;
2399   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_NAME_MARKER);
2400   ENCODE_U32(pPayload, MarkerId);
2401   pPayload = _EncodeStr(pPayload, sName, SEGGER_SYSVIEW_MAX_STRING_LEN);
2402   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2403   RECORD_END();
2404 }
2405 
2406 /*********************************************************************
2407 *
2408 *       SEGGER_SYSVIEW_NameResource()
2409 *
2410 *  Function description
2411 *    Send the name of a resource to be displayed in SystemView.
2412 *
2413 *    Marker names are usually set in the system description
2414 *    callback, to ensure it is only sent when the SystemView Application
2415 *    is connected.
2416 *
2417 *  Parameters
2418 *    ResourceId - Id of the resource to be named. i.e. its address.
2419 *    sName      - Pointer to the resource name. (Max. SEGGER_SYSVIEW_MAX_STRING_LEN Bytes)
2420 */
SEGGER_SYSVIEW_NameResource(U32 ResourceId,const char * sName)2421 void SEGGER_SYSVIEW_NameResource(U32 ResourceId, const char* sName) {
2422   U8* pPayload;
2423   U8* pPayloadStart;
2424   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2425   //
2426   pPayload = pPayloadStart;
2427   ENCODE_U32(pPayload, SHRINK_ID(ResourceId));
2428   pPayload = _EncodeStr(pPayload, sName, SEGGER_SYSVIEW_MAX_STRING_LEN);
2429   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NAME_RESOURCE);
2430   RECORD_END();
2431 }
2432 
2433 /*********************************************************************
2434 *
2435 *       SEGGER_SYSVIEW_HeapDefine()
2436 *
2437 *  Function description
2438 *    Define heap.
2439 *
2440 *  Parameters
2441 *    pHeap        - Pointer to heap control structure.
2442 *    pBase        - Pointer to managed heap memory.
2443 *    HeapSize     - Size of managed heap memory in bytes.
2444 *    MetadataSize - Size of metadata associated with each heap allocation.
2445 *
2446 *  Additional information
2447 *    SystemView can track allocations across multiple heaps.
2448 *
2449 *    HeapSize must be a multiple of the natural alignment unit of the
2450 *    target.  This size is subject to compression, controlled by the
2451 *    specific setting of SEGGER_SYSVIEW_ID_SHIFT.
2452 *
2453 *    MetadataSize defines the size of the per-allocation metadata.
2454 *    For many heap implementations, the metadata size is a multiple of
2455 *    the word size of the machine and typically contains the size
2456 *    of the allocated block (used upon deallocation), optional
2457 *    pointers to the preceding and/or following blocks, and optionally
2458 *    a tag identifying the owner of the block.  Note that MetadataSize
2459 *    is not compressed within the SystemView packet and is not
2460 *    required to be a multiple of 1<<SEGGER_SYSVIEW_ID_SHIFT.
2461 */
SEGGER_SYSVIEW_HeapDefine(void * pHeap,void * pBase,unsigned int HeapSize,unsigned int MetadataSize)2462 void SEGGER_SYSVIEW_HeapDefine(void* pHeap, void *pBase, unsigned int HeapSize, unsigned int MetadataSize) {
2463   U8* pPayload;
2464   U8* pPayloadStart;
2465   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
2466   //
2467   pPayload = pPayloadStart;
2468   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_DEFINE);
2469   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2470   ENCODE_U32(pPayload, SHRINK_ID((U32)pBase));
2471   ENCODE_U32(pPayload, HeapSize >> SEGGER_SYSVIEW_ID_SHIFT);
2472   ENCODE_U32(pPayload, MetadataSize);
2473   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2474   RECORD_END();
2475 }
2476 
2477 /*********************************************************************
2478 *
2479 *       SEGGER_SYSVIEW_HeapAlloc()
2480 *
2481 *  Function description
2482 *    Record a system-heap allocation event.
2483 *
2484 *  Parameters
2485 *    pHeap       - Pointer to heap where allocation was made.
2486 *    pUserData   - Pointer to allocated user data.
2487 *    UserDataLen - Size of block allocated to hold user data, excluding any metadata.
2488 *
2489 *  Additional information
2490 *    The user data must be correctly aligned for the architecture, which
2491 *    typically requires that the alignment is at least the alignment
2492 *    of a double or a long long.  pUserData is, therefore, compressed by
2493 *    shrinking as IDs are compressed, controlled by the specific setting
2494 *    of SEGGER_SYSVIEW_ID_SHIFT.
2495 *
2496 *    In the same way, UserDataLen must reflect the size of the allocated
2497 *    block, not the allocation size requested by the application.  This
2498 *    size is also subject to compression, controlled by the specific setting
2499 *    of SEGGER_SYSVIEW_ID_SHIFT.
2500 *
2501 *    As an example, assume the allocator is running on a Cortex-M device
2502 *    with SEGGER_SYSVIEW_ID_SHIFT set to 2 (the word alignment of the device).
2503 *    If a user requests an allocation of 5 bytes, a hypothetical heap
2504 *    allocator could allocate a block with size 32 bytes for this.  The value
2505 *    of UserDataLen sent to SystemView for recording should be 32, not 5,
2506 *    and the 32 is compressed by shifting by two bits, the configured value
2507 *    of SEGGER_SYSVIEW_ID_SHIFT, and describes the number of bytes that are
2508 *    consumed from managed memory from which SystemView can calculate
2509 *    accurate heap metrics.
2510 */
SEGGER_SYSVIEW_HeapAlloc(void * pHeap,void * pUserData,unsigned int UserDataLen)2511 void SEGGER_SYSVIEW_HeapAlloc(void *pHeap, void* pUserData, unsigned int UserDataLen) {
2512   U8* pPayload;
2513   U8* pPayloadStart;
2514   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 3 * SEGGER_SYSVIEW_QUANTA_U32);
2515   //
2516   pPayload = pPayloadStart;
2517   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_ALLOC);
2518   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2519   ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData));
2520   ENCODE_U32(pPayload, UserDataLen >> SEGGER_SYSVIEW_ID_SHIFT);
2521   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2522   RECORD_END();
2523 }
2524 
2525 /*********************************************************************
2526 *
2527 *       SEGGER_SYSVIEW_HeapAllocEx()
2528 *
2529 *  Function description
2530 *    Record a per-heap allocation event.
2531 *
2532 *  Parameters
2533 *    pHeap       - Pointer to heap where allocation was made.
2534 *    pUserData   - Pointer to allocated user data.
2535 *    UserDataLen - Size of block allocated to hold user data, excluding any metadata.
2536 *    Tag         - Block tag, typically used to identify the owner of the block.
2537 *
2538 *  Additional information
2539 *    The user data must be correctly aligned for the architecture, which
2540 *    typically requires that the alignment is at least the alignment
2541 *    of a double or a long long.  pUserData is, therefore, compressed by
2542 *    shrinking as IDs are compressed, controlled by the specific setting
2543 *    of SEGGER_SYSVIEW_ID_SHIFT.
2544 *
2545 *    In the same way, UserDataLen must reflect the size of the allocated
2546 *    block, not the allocation size requested by the application.  This
2547 *    size is also subject to compression, controlled by the specific setting
2548 *    of SEGGER_SYSVIEW_ID_SHIFT.
2549 *
2550 *    As an example, assume the allocator is running on a Cortex-M device
2551 *    with SEGGER_SYSVIEW_ID_SHIFT set to 2 (the word alignment of the device).
2552 *    If a user requests an allocation of 5 bytes, a hypothetical heap
2553 *    allocator could allocate a block with size 32 bytes for this.  The value
2554 *    of UserDataLen sent to SystemView for recording should be 32, not 5,
2555 *    and the 32 is compressed by shifting by two bits, the configured value
2556 *    of SEGGER_SYSVIEW_ID_SHIFT, and describes the number of bytes that are
2557 *    consumed from managed memory from which SystemView can calculate
2558 *    accurate heap metrics.
2559 *
2560 *  See also
2561 *    SEGGER_SYSVIEW_HeapAlloc().
2562 */
SEGGER_SYSVIEW_HeapAllocEx(void * pHeap,void * pUserData,unsigned int UserDataLen,unsigned int Tag)2563 void SEGGER_SYSVIEW_HeapAllocEx(void *pHeap, void* pUserData, unsigned int UserDataLen, unsigned int Tag) {
2564   U8* pPayload;
2565   U8* pPayloadStart;
2566   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32);
2567   //
2568   pPayload = pPayloadStart;
2569   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_ALLOC_EX);
2570   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2571   ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData));
2572   ENCODE_U32(pPayload, UserDataLen >> SEGGER_SYSVIEW_ID_SHIFT);
2573   ENCODE_U32(pPayload, Tag);
2574   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2575   RECORD_END();
2576 }
2577 
2578 /*********************************************************************
2579 *
2580 *       SEGGER_SYSVIEW_HeapFree()
2581 *
2582 *  Function description
2583 *    Record a heap deallocation event.
2584 *
2585 *  Parameters
2586 *    pHeap     - Pointer to heap where allocation was made.
2587 *    pUserData - Pointer to allocated user data.
2588 *
2589 *  Additional information
2590 *    SystemViews track allocations and knows the size of the
2591 *    allocated data.
2592 */
SEGGER_SYSVIEW_HeapFree(void * pHeap,void * pUserData)2593 void SEGGER_SYSVIEW_HeapFree(void* pHeap, void* pUserData) {
2594   U8* pPayload;
2595   U8* pPayloadStart;
2596   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
2597   //
2598   pPayload = pPayloadStart;
2599   ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_FREE);
2600   ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap));
2601   ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData));
2602   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX);
2603   RECORD_END();
2604 }
2605 
2606 /*********************************************************************
2607 *
2608 *       SEGGER_SYSVIEW_SendPacket()
2609 *
2610 *  Function description
2611 *    Send an event packet.
2612 *
2613 *  Parameters
2614 *    pPacket      - Pointer to the start of the packet.
2615 *    pPayloadEnd  - Pointer to the end of the payload.
2616 *                   Make sure there are at least 5 bytes free after the payload.
2617 *    EventId      - Id of the event packet.
2618 *
2619 *  Return value
2620 *    !=0:  Success, Message sent.
2621 *    ==0:  Buffer full, Message *NOT* sent.
2622 */
SEGGER_SYSVIEW_SendPacket(U8 * pPacket,U8 * pPayloadEnd,unsigned int EventId)2623 int SEGGER_SYSVIEW_SendPacket(U8* pPacket, U8* pPayloadEnd, unsigned int EventId) {
2624 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
2625   SEGGER_SYSVIEW_LOCK();
2626 #endif
2627   _SendPacket(pPacket + 4, pPayloadEnd, EventId);
2628 #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
2629   SEGGER_SYSVIEW_UNLOCK();
2630 #endif
2631   return 0;
2632 }
2633 
2634 /*********************************************************************
2635 *
2636 *       SEGGER_SYSVIEW_EncodeU32()
2637 *
2638 *  Function description
2639 *    Encode a U32 in variable-length format.
2640 *
2641 *  Parameters
2642 *    pPayload - Pointer to where U32 will be encoded.
2643 *    Value    - The 32-bit value to be encoded.
2644 *
2645 *  Return value
2646 *    Pointer to the byte following the value, i.e. the first free
2647 *    byte in the payload and the next position to store payload
2648 *    content.
2649 */
SEGGER_SYSVIEW_EncodeU32(U8 * pPayload,U32 Value)2650 U8* SEGGER_SYSVIEW_EncodeU32(U8* pPayload, U32 Value) {
2651   ENCODE_U32(pPayload, Value);
2652   return pPayload;
2653 }
2654 
2655 /*********************************************************************
2656 *
2657 *       SEGGER_SYSVIEW_EncodeString()
2658 *
2659 *  Function description
2660 *    Encode a string in variable-length format.
2661 *
2662 *  Parameters
2663 *    pPayload - Pointer to where string will be encoded.
2664 *    s        - String to encode.
2665 *    MaxLen   - Maximum number of characters to encode from string.
2666 *
2667 *  Return value
2668 *    Pointer to the byte following the value, i.e. the first free
2669 *    byte in the payload and the next position to store payload
2670 *    content.
2671 *
2672 *  Additional information
2673 *    The string is encoded as a count byte followed by the contents
2674 *    of the string.
2675 *    No more than 1 + MaxLen bytes will be encoded to the payload.
2676 */
SEGGER_SYSVIEW_EncodeString(U8 * pPayload,const char * s,unsigned int MaxLen)2677 U8* SEGGER_SYSVIEW_EncodeString(U8* pPayload, const char* s, unsigned int MaxLen) {
2678   return _EncodeStr(pPayload, s, MaxLen);
2679 }
2680 
2681 /*********************************************************************
2682 *
2683 *       SEGGER_SYSVIEW_EncodeData()
2684 *
2685 *  Function description
2686 *    Encode a byte buffer in variable-length format.
2687 *
2688 *  Parameters
2689 *    pPayload - Pointer to where string will be encoded.
2690 *    pSrc     - Pointer to data buffer to be encoded.
2691 *    NumBytes - Number of bytes in the buffer to be encoded.
2692 *
2693 *  Return value
2694 *    Pointer to the byte following the value, i.e. the first free
2695 *    byte in the payload and the next position to store payload
2696 *    content.
2697 *
2698 *  Additional information
2699 *    The data is encoded as a count byte followed by the contents
2700 *    of the data buffer.
2701 *    Make sure NumBytes + 1 bytes are free for the payload.
2702 */
SEGGER_SYSVIEW_EncodeData(U8 * pPayload,const char * pSrc,unsigned int NumBytes)2703 U8* SEGGER_SYSVIEW_EncodeData(U8 *pPayload, const char* pSrc, unsigned int NumBytes) {
2704   return _EncodeData(pPayload, pSrc, NumBytes);
2705 }
2706 
2707 /*********************************************************************
2708 *
2709 *       SEGGER_SYSVIEW_EncodeId()
2710 *
2711 *  Function description
2712 *    Encode a 32-bit Id in shrunken variable-length format.
2713 *
2714 *  Parameters
2715 *    pPayload - Pointer to where the Id will be encoded.
2716 *    Id       - The 32-bit value to be encoded.
2717 *
2718 *  Return value
2719 *    Pointer to the byte following the value, i.e. the first free
2720 *    byte in the payload and the next position to store payload
2721 *    content.
2722 *
2723 *  Additional information
2724 *    The parameters to shrink an Id can be configured in
2725 *    SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
2726 *     SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
2727 *       (i.e. 0x20000000 when all Ids are an address in this RAM)
2728 *     SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
2729 *       save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
2730 */
SEGGER_SYSVIEW_EncodeId(U8 * pPayload,U32 Id)2731 U8* SEGGER_SYSVIEW_EncodeId(U8* pPayload, U32 Id) {
2732   Id = SHRINK_ID(Id);
2733   ENCODE_U32(pPayload, Id);
2734   return pPayload;
2735 }
2736 
2737 /*********************************************************************
2738 *
2739 *       SEGGER_SYSVIEW_ShrinkId()
2740 *
2741 *  Function description
2742 *    Get the shrunken value of an Id for further processing like in
2743 *    SEGGER_SYSVIEW_NameResource().
2744 *
2745 *  Parameters
2746 *    Id       - The 32-bit value to be shrunken.
2747 *
2748 *  Return value
2749 *    Shrunken Id.
2750 *
2751 *  Additional information
2752 *    The parameters to shrink an Id can be configured in
2753 *    SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
2754 *     SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
2755 *       (i.e. 0x20000000 when all Ids are an address in this RAM)
2756 *     SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
2757 *       save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
2758 */
SEGGER_SYSVIEW_ShrinkId(U32 Id)2759 U32 SEGGER_SYSVIEW_ShrinkId(U32 Id) {
2760   return SHRINK_ID(Id);
2761 }
2762 
2763 /*********************************************************************
2764 *
2765 *       SEGGER_SYSVIEW_RegisterModule()
2766 *
2767 *  Function description
2768 *    Register a middleware module for recording its events.
2769 *
2770 *  Parameters
2771 *    pModule  - The middleware module information.
2772 *
2773 *  Additional information
2774 *    SEGGER_SYSVIEW_MODULE elements:
2775 *      sDescription      - Pointer to a string containing the module name and optionally the module event description.
2776 *      NumEvents         - Number of events the module wants to register.
2777 *      EventOffset       - Offset to be added to the event Ids. Out parameter, set by this function. Do not modify after calling this function.
2778 *      pfSendModuleDesc  - Callback function pointer to send more detailed module description to SystemView Application.
2779 *      pNext             - Pointer to next registered module. Out parameter, set by this function. Do not modify after calling this function.
2780 */
SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE * pModule)2781 void SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE* pModule) {
2782   SEGGER_SYSVIEW_LOCK();
2783   if (_pFirstModule == 0) {
2784     //
2785     // No module registered, yet.
2786     // Start list with new module.
2787     // EventOffset is the base offset for modules
2788     //
2789     pModule->EventOffset = MODULE_EVENT_OFFSET;
2790     pModule->pNext = 0;
2791     _pFirstModule = pModule;
2792     _NumModules = 1;
2793   } else {
2794     //
2795     // Registreded module(s) present.
2796     // Prepend new module in list.
2797     // EventOffset set from number of events and offset of previous module.
2798     //
2799     pModule->EventOffset = _pFirstModule->EventOffset + _pFirstModule->NumEvents;
2800     pModule->pNext = _pFirstModule;
2801     _pFirstModule = pModule;
2802     _NumModules++;
2803   }
2804   SEGGER_SYSVIEW_SendModule(0);
2805   if (pModule->pfSendModuleDesc) {
2806     pModule->pfSendModuleDesc();
2807   }
2808   SEGGER_SYSVIEW_UNLOCK();
2809 }
2810 
2811 /*********************************************************************
2812 *
2813 *       SEGGER_SYSVIEW_RecordModuleDescription()
2814 *
2815 *  Function description
2816 *    Sends detailed information of a registered module to the host.
2817 *
2818 *  Parameters
2819 *    pModule      - Pointer to the described module.
2820 *    sDescription - Pointer to a description string.
2821 */
SEGGER_SYSVIEW_RecordModuleDescription(const SEGGER_SYSVIEW_MODULE * pModule,const char * sDescription)2822 void SEGGER_SYSVIEW_RecordModuleDescription(const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription) {
2823   U8  ModuleId;
2824   SEGGER_SYSVIEW_MODULE* p;
2825 
2826   p = _pFirstModule;
2827   ModuleId = 0;
2828   do {
2829     if (p == pModule) {
2830       break;
2831     }
2832     ModuleId++;
2833     p = p->pNext;
2834   } while (p);
2835   {
2836     U8* pPayload;
2837     U8* pPayloadStart;
2838     RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2839     //
2840     pPayload = pPayloadStart;
2841     //
2842     // Send module description
2843     // Send event offset and number of events
2844     //
2845     ENCODE_U32(pPayload, ModuleId);
2846     ENCODE_U32(pPayload, (pModule->EventOffset));
2847     pPayload = _EncodeStr(pPayload, sDescription, SEGGER_SYSVIEW_MAX_STRING_LEN);
2848     _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
2849     RECORD_END();
2850   }
2851 }
2852 
2853 /*********************************************************************
2854 *
2855 *       SEGGER_SYSVIEW_SendModule()
2856 *
2857 *  Function description
2858 *    Sends the information of a registered module to the host.
2859 *
2860 *  Parameters
2861 *    ModuleId   - Id of the requested module.
2862 */
SEGGER_SYSVIEW_SendModule(U8 ModuleId)2863 void SEGGER_SYSVIEW_SendModule(U8 ModuleId) {
2864   SEGGER_SYSVIEW_MODULE* pModule;
2865   U32 n;
2866 
2867   if (_pFirstModule != 0) {
2868     pModule = _pFirstModule;
2869     for (n = 0; n < ModuleId; n++) {
2870       pModule = pModule->pNext;
2871       if (pModule == 0) {
2872         break;
2873       }
2874     }
2875     if (pModule != 0) {
2876       U8* pPayload;
2877       U8* pPayloadStart;
2878       RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
2879       //
2880       pPayload = pPayloadStart;
2881       //
2882       // Send module description
2883       // Send event offset and number of events
2884       //
2885       ENCODE_U32(pPayload, ModuleId);
2886       ENCODE_U32(pPayload, (pModule->EventOffset));
2887       pPayload = _EncodeStr(pPayload, pModule->sModule, SEGGER_SYSVIEW_MAX_STRING_LEN);
2888       _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
2889       RECORD_END();
2890     }
2891   }
2892 }
2893 
2894 /*********************************************************************
2895 *
2896 *       SEGGER_SYSVIEW_SendModuleDescription()
2897 *
2898 *  Function description
2899 *    Triggers a send of the registered module descriptions.
2900 *
2901 */
SEGGER_SYSVIEW_SendModuleDescription(void)2902 void SEGGER_SYSVIEW_SendModuleDescription(void) {
2903   SEGGER_SYSVIEW_MODULE* pModule;
2904 
2905   if (_pFirstModule != 0) {
2906     pModule = _pFirstModule;
2907     do {
2908       if (pModule->pfSendModuleDesc) {
2909         pModule->pfSendModuleDesc();
2910       }
2911       pModule = pModule->pNext;
2912     } while (pModule);
2913   }
2914 }
2915 
2916 /*********************************************************************
2917 *
2918 *       SEGGER_SYSVIEW_SendNumModules()
2919 *
2920 *  Function description
2921 *    Send the number of registered modules to the host.
2922 */
SEGGER_SYSVIEW_SendNumModules(void)2923 void SEGGER_SYSVIEW_SendNumModules(void) {
2924   U8* pPayload;
2925   U8* pPayloadStart;
2926   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2*SEGGER_SYSVIEW_QUANTA_U32);
2927   pPayload = pPayloadStart;
2928   ENCODE_U32(pPayload, _NumModules);
2929   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NUMMODULES);
2930   RECORD_END();
2931 }
2932 
2933 #ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
2934 
2935 /*********************************************************************
2936 *
2937 *       SEGGER_SYSVIEW_PrintfHostEx()
2938 *
2939 *  Function description
2940 *    Print a string which is formatted on the host by the SystemView Application
2941 *    with Additional information.
2942 *
2943 *  Parameters
2944 *    s        - String to be formatted.
2945 *    Options  - Options for the string. i.e. Log level.
2946 *
2947 *  Additional information
2948 *    All format arguments are treated as 32-bit scalar values.
2949 */
SEGGER_SYSVIEW_PrintfHostEx(const char * s,U32 Options,...)2950 void SEGGER_SYSVIEW_PrintfHostEx(const char* s, U32 Options, ...) {
2951   va_list ParamList;
2952 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
2953   int r;
2954 
2955   va_start(ParamList, Options);
2956   r = _VPrintHost(s, Options, &ParamList);
2957   va_end(ParamList);
2958 
2959   if (r == -1) {
2960     va_start(ParamList, Options);
2961     _VPrintTarget(s, Options, &ParamList);
2962     va_end(ParamList);
2963   }
2964 #else
2965   va_start(ParamList, Options);
2966   _VPrintHost(s, Options, &ParamList);
2967   va_end(ParamList);
2968 #endif
2969 }
2970 
2971 /*********************************************************************
2972 *
2973 *       SEGGER_SYSVIEW_PrintfHost()
2974 *
2975 *  Function description
2976 *    Print a string which is formatted on the host by the SystemView Application.
2977 *
2978 *  Parameters
2979 *    s        - String to be formatted.
2980 *
2981 *  Additional information
2982 *    All format arguments are treated as 32-bit scalar values.
2983 */
SEGGER_SYSVIEW_PrintfHost(const char * s,...)2984 void SEGGER_SYSVIEW_PrintfHost(const char* s, ...) {
2985   va_list ParamList;
2986 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
2987   int r;
2988 
2989   va_start(ParamList, s);
2990   r = _VPrintHost(s, SEGGER_SYSVIEW_LOG, &ParamList);
2991   va_end(ParamList);
2992 
2993   if (r == -1) {
2994     va_start(ParamList, s);
2995     _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamList);
2996     va_end(ParamList);
2997   }
2998 #else
2999   va_start(ParamList, s);
3000   _VPrintHost(s, SEGGER_SYSVIEW_LOG, &ParamList);
3001   va_end(ParamList);
3002 #endif
3003 }
3004 
3005 /*********************************************************************
3006 *
3007 *       SEGGER_SYSVIEW_WarnfHost()
3008 *
3009 *  Function description
3010 *    Print a warning string which is formatted on the host by
3011 *    the SystemView Application.
3012 *
3013 *  Parameters
3014 *    s        - String to be formatted.
3015 *
3016 *  Additional information
3017 *    All format arguments are treated as 32-bit scalar values.
3018 */
SEGGER_SYSVIEW_WarnfHost(const char * s,...)3019 void SEGGER_SYSVIEW_WarnfHost(const char* s, ...) {
3020   va_list ParamList;
3021 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3022   int r;
3023 
3024   va_start(ParamList, s);
3025   r = _VPrintHost(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3026   va_end(ParamList);
3027 
3028   if (r == -1) {
3029     va_start(ParamList, s);
3030     _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3031     va_end(ParamList);
3032   }
3033 #else
3034   va_start(ParamList, s);
3035   _VPrintHost(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3036   va_end(ParamList);
3037 #endif
3038 }
3039 
3040 /*********************************************************************
3041 *
3042 *       SEGGER_SYSVIEW_ErrorfHost()
3043 *
3044 *  Function description
3045 *    Print an error string which is formatted on the host by
3046 *    the SystemView Application.
3047 *
3048 *  Parameters
3049 *    s        - String to be formatted.
3050 *
3051 *  Additional information
3052 *    All format arguments are treated as 32-bit scalar values.
3053 */
SEGGER_SYSVIEW_ErrorfHost(const char * s,...)3054 void SEGGER_SYSVIEW_ErrorfHost(const char* s, ...) {
3055   va_list ParamList;
3056 #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT
3057   int r;
3058 
3059   va_start(ParamList, s);
3060   r = _VPrintHost(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3061   va_end(ParamList);
3062 
3063   if (r == -1) {
3064     va_start(ParamList, s);
3065     _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3066     va_end(ParamList);
3067   }
3068 #else
3069   va_start(ParamList, s);
3070   _VPrintHost(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3071   va_end(ParamList);
3072 #endif
3073 }
3074 
3075 /*********************************************************************
3076 *
3077 *       SEGGER_SYSVIEW_PrintfTargetEx()
3078 *
3079 *  Function description
3080 *    Print a string which is formatted on the target before sent to
3081 *    the host with Additional information.
3082 *
3083 *  Parameters
3084 *    s        - String to be formatted.
3085 *    Options  - Options for the string. i.e. Log level.
3086 */
SEGGER_SYSVIEW_PrintfTargetEx(const char * s,U32 Options,...)3087 void SEGGER_SYSVIEW_PrintfTargetEx(const char* s, U32 Options, ...) {
3088   va_list ParamList;
3089 
3090   va_start(ParamList, Options);
3091   _VPrintTarget(s, Options, &ParamList);
3092   va_end(ParamList);
3093 }
3094 
3095 /*********************************************************************
3096 *
3097 *       SEGGER_SYSVIEW_PrintfTarget()
3098 *
3099 *  Function description
3100 *    Print a string which is formatted on the target before sent to
3101 *    the host.
3102 *
3103 *  Parameters
3104 *    s        - String to be formatted.
3105 */
SEGGER_SYSVIEW_PrintfTarget(const char * s,...)3106 void SEGGER_SYSVIEW_PrintfTarget(const char* s, ...) {
3107   va_list ParamList;
3108 
3109   va_start(ParamList, s);
3110   _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamList);
3111   va_end(ParamList);
3112 }
3113 
3114 /*********************************************************************
3115 *
3116 *       SEGGER_SYSVIEW_WarnfTarget()
3117 *
3118 *  Function description
3119 *    Print a warning string which is formatted on the target before
3120 *    sent to the host.
3121 *
3122 *  Parameters
3123 *    s        - String to be formatted.
3124 */
SEGGER_SYSVIEW_WarnfTarget(const char * s,...)3125 void SEGGER_SYSVIEW_WarnfTarget(const char* s, ...) {
3126   va_list ParamList;
3127 
3128   va_start(ParamList, s);
3129   _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamList);
3130   va_end(ParamList);
3131 }
3132 
3133 /*********************************************************************
3134 *
3135 *       SEGGER_SYSVIEW_ErrorfTarget()
3136 *
3137 *  Function description
3138 *    Print an error string which is formatted on the target before
3139 *    sent to the host.
3140 *
3141 *  Parameters
3142 *    s        - String to be formatted.
3143 */
SEGGER_SYSVIEW_ErrorfTarget(const char * s,...)3144 void SEGGER_SYSVIEW_ErrorfTarget(const char* s, ...) {
3145   va_list ParamList;
3146 
3147   va_start(ParamList, s);
3148   _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamList);
3149   va_end(ParamList);
3150 }
3151 #endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
3152 
3153 /*********************************************************************
3154 *
3155 *       SEGGER_SYSVIEW_Print()
3156 *
3157 *  Function description
3158 *    Print a string to the host.
3159 *
3160 *  Parameters
3161 *    s        - String to sent.
3162 */
SEGGER_SYSVIEW_Print(const char * s)3163 void SEGGER_SYSVIEW_Print(const char* s) {
3164   U8* pPayload;
3165   U8* pPayloadStart;
3166   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
3167   //
3168   pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
3169   ENCODE_U32(pPayload, SEGGER_SYSVIEW_LOG);
3170   ENCODE_U32(pPayload, 0);
3171   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
3172   RECORD_END();
3173 }
3174 
3175 /*********************************************************************
3176 *
3177 *       SEGGER_SYSVIEW_Warn()
3178 *
3179 *  Function description
3180 *    Print a warning string to the host.
3181 *
3182 *  Parameters
3183 *    s        - String to sent.
3184 */
SEGGER_SYSVIEW_Warn(const char * s)3185 void SEGGER_SYSVIEW_Warn(const char* s) {
3186   U8* pPayload;
3187   U8* pPayloadStart;
3188   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
3189   //
3190   pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
3191   ENCODE_U32(pPayload, SEGGER_SYSVIEW_WARNING);
3192   ENCODE_U32(pPayload, 0);
3193   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
3194   RECORD_END();
3195 }
3196 
3197 /*********************************************************************
3198 *
3199 *       SEGGER_SYSVIEW_Error()
3200 *
3201 *  Function description
3202 *    Print an error string to the host.
3203 *
3204 *  Parameters
3205 *    s        - String to sent.
3206 */
SEGGER_SYSVIEW_Error(const char * s)3207 void SEGGER_SYSVIEW_Error(const char* s) {
3208   U8* pPayload;
3209   U8* pPayloadStart;
3210   RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
3211   //
3212   pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
3213   ENCODE_U32(pPayload, SEGGER_SYSVIEW_ERROR);
3214   ENCODE_U32(pPayload, 0);
3215   _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
3216   RECORD_END();
3217 }
3218 
3219 /*********************************************************************
3220 *
3221 *       SEGGER_SYSVIEW_EnableEvents()
3222 *
3223 *  Function description
3224 *    Enable standard SystemView events to be generated.
3225 *
3226 *  Parameters
3227 *    EnableMask   - Events to be enabled.
3228 */
SEGGER_SYSVIEW_EnableEvents(U32 EnableMask)3229 void SEGGER_SYSVIEW_EnableEvents(U32 EnableMask) {
3230   _SYSVIEW_Globals.DisabledEvents &= ~EnableMask;
3231 }
3232 
3233 /*********************************************************************
3234 *
3235 *       SEGGER_SYSVIEW_DisableEvents()
3236 *
3237 *  Function description
3238 *    Disable standard SystemView events to not be generated.
3239 *
3240 *  Parameters
3241 *    DisableMask  - Events to be disabled.
3242 */
SEGGER_SYSVIEW_DisableEvents(U32 DisableMask)3243 void SEGGER_SYSVIEW_DisableEvents(U32 DisableMask) {
3244   _SYSVIEW_Globals.DisabledEvents |= DisableMask;
3245 }
3246 
3247 /*********************************************************************
3248 *
3249 *       SEGGER_SYSVIEW_IsStarted()
3250 *
3251 *  Function description
3252 *    Handle incoming packets if any and check if recording is started.
3253 *
3254 *  Return value
3255 *      0: Recording not started.
3256 *    > 0: Recording started.
3257 */
SEGGER_SYSVIEW_IsStarted(void)3258 int SEGGER_SYSVIEW_IsStarted(void) {
3259 #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
3260   //
3261   // Check if host is sending data which needs to be processed.
3262   //
3263   if (SEGGER_RTT_HASDATA(CHANNEL_ID_DOWN)) {
3264     if (_SYSVIEW_Globals.RecursionCnt == 0) {   // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
3265       _SYSVIEW_Globals.RecursionCnt = 1;
3266       _HandleIncomingPacket();
3267       _SYSVIEW_Globals.RecursionCnt = 0;
3268     }
3269   }
3270 #endif
3271   return _SYSVIEW_Globals.EnableState;
3272 }
3273 
3274 
3275 /*************************** End of file ****************************/
3276