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