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