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