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