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