17dc86dfdSMatthias Ringwald /********************************************************************* 2779af47bSMatthias Ringwald * SEGGER Microcontroller GmbH * 3779af47bSMatthias Ringwald * The Embedded Experts * 47dc86dfdSMatthias Ringwald ********************************************************************** 57dc86dfdSMatthias Ringwald * * 6779af47bSMatthias Ringwald * (c) 1995 - 2019 SEGGER Microcontroller GmbH * 77dc86dfdSMatthias Ringwald * * 87dc86dfdSMatthias Ringwald * www.segger.com Support: [email protected] * 97dc86dfdSMatthias Ringwald * * 107dc86dfdSMatthias Ringwald ********************************************************************** 117dc86dfdSMatthias Ringwald * * 127dc86dfdSMatthias Ringwald * SEGGER RTT * Real Time Transfer for embedded targets * 137dc86dfdSMatthias Ringwald * * 147dc86dfdSMatthias Ringwald ********************************************************************** 157dc86dfdSMatthias Ringwald * * 167dc86dfdSMatthias Ringwald * All rights reserved. * 177dc86dfdSMatthias Ringwald * * 187dc86dfdSMatthias Ringwald * SEGGER strongly recommends to not make any changes * 197dc86dfdSMatthias Ringwald * to or modify the source code of this software in order to stay * 207dc86dfdSMatthias Ringwald * compatible with the RTT protocol and J-Link. * 217dc86dfdSMatthias Ringwald * * 227dc86dfdSMatthias Ringwald * Redistribution and use in source and binary forms, with or * 237dc86dfdSMatthias Ringwald * without modification, are permitted provided that the following * 247dc86dfdSMatthias Ringwald * conditions are met: * 257dc86dfdSMatthias Ringwald * * 267dc86dfdSMatthias Ringwald * o Redistributions of source code must retain the above copyright * 277dc86dfdSMatthias Ringwald * notice, this list of conditions and the following disclaimer. * 287dc86dfdSMatthias Ringwald * * 297dc86dfdSMatthias Ringwald * o Redistributions in binary form must reproduce the above * 307dc86dfdSMatthias Ringwald * copyright notice, this list of conditions and the following * 317dc86dfdSMatthias Ringwald * disclaimer in the documentation and/or other materials provided * 327dc86dfdSMatthias Ringwald * with the distribution. * 337dc86dfdSMatthias Ringwald * * 34779af47bSMatthias Ringwald * o Neither the name of SEGGER Microcontroller GmbH * 357dc86dfdSMatthias Ringwald * nor the names of its contributors may be used to endorse or * 367dc86dfdSMatthias Ringwald * promote products derived from this software without specific * 377dc86dfdSMatthias Ringwald * prior written permission. * 387dc86dfdSMatthias Ringwald * * 397dc86dfdSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * 407dc86dfdSMatthias Ringwald * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * 417dc86dfdSMatthias Ringwald * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * 427dc86dfdSMatthias Ringwald * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * 437dc86dfdSMatthias Ringwald * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * 447dc86dfdSMatthias Ringwald * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * 457dc86dfdSMatthias Ringwald * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * 467dc86dfdSMatthias Ringwald * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * 477dc86dfdSMatthias Ringwald * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * 487dc86dfdSMatthias Ringwald * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 497dc86dfdSMatthias Ringwald * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * 507dc86dfdSMatthias Ringwald * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * 517dc86dfdSMatthias Ringwald * DAMAGE. * 527dc86dfdSMatthias Ringwald * * 537dc86dfdSMatthias Ringwald ********************************************************************** 547dc86dfdSMatthias Ringwald ---------------------------END-OF-HEADER------------------------------ 557dc86dfdSMatthias Ringwald File : SEGGER_RTT.c 567dc86dfdSMatthias Ringwald Purpose : Implementation of SEGGER real-time transfer (RTT) which 577dc86dfdSMatthias Ringwald allows real-time communication on targets which support 587dc86dfdSMatthias Ringwald debugger memory accesses while the CPU is running. 59779af47bSMatthias Ringwald Revision: $Rev: 14765 $ 607dc86dfdSMatthias Ringwald 617dc86dfdSMatthias Ringwald Additional information: 627dc86dfdSMatthias Ringwald Type "int" is assumed to be 32-bits in size 637dc86dfdSMatthias Ringwald H->T Host to target communication 647dc86dfdSMatthias Ringwald T->H Target to host communication 657dc86dfdSMatthias Ringwald 667dc86dfdSMatthias Ringwald RTT channel 0 is always present and reserved for Terminal usage. 677dc86dfdSMatthias Ringwald Name is fixed to "Terminal" 687dc86dfdSMatthias Ringwald 697dc86dfdSMatthias Ringwald Effective buffer size: SizeOfBuffer - 1 707dc86dfdSMatthias Ringwald 717dc86dfdSMatthias Ringwald WrOff == RdOff: Buffer is empty 727dc86dfdSMatthias Ringwald WrOff == (RdOff - 1): Buffer is full 737dc86dfdSMatthias Ringwald WrOff > RdOff: Free space includes wrap-around 747dc86dfdSMatthias Ringwald WrOff < RdOff: Used space includes wrap-around 757dc86dfdSMatthias Ringwald (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): 767dc86dfdSMatthias Ringwald Buffer full and wrap-around after next byte 777dc86dfdSMatthias Ringwald 787dc86dfdSMatthias Ringwald 797dc86dfdSMatthias Ringwald ---------------------------------------------------------------------- 807dc86dfdSMatthias Ringwald */ 817dc86dfdSMatthias Ringwald 827dc86dfdSMatthias Ringwald #include "SEGGER_RTT.h" 837dc86dfdSMatthias Ringwald 847dc86dfdSMatthias Ringwald #include <string.h> // for memcpy 857dc86dfdSMatthias Ringwald 867dc86dfdSMatthias Ringwald /********************************************************************* 877dc86dfdSMatthias Ringwald * 887dc86dfdSMatthias Ringwald * Configuration, default values 897dc86dfdSMatthias Ringwald * 907dc86dfdSMatthias Ringwald ********************************************************************** 917dc86dfdSMatthias Ringwald */ 927dc86dfdSMatthias Ringwald 937dc86dfdSMatthias Ringwald #ifndef BUFFER_SIZE_UP 947dc86dfdSMatthias Ringwald #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host 957dc86dfdSMatthias Ringwald #endif 967dc86dfdSMatthias Ringwald 977dc86dfdSMatthias Ringwald #ifndef BUFFER_SIZE_DOWN 987dc86dfdSMatthias Ringwald #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) 997dc86dfdSMatthias Ringwald #endif 1007dc86dfdSMatthias Ringwald 1017dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS 1027dc86dfdSMatthias Ringwald #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target 1037dc86dfdSMatthias Ringwald #endif 1047dc86dfdSMatthias Ringwald 1057dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 1067dc86dfdSMatthias Ringwald #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target 1077dc86dfdSMatthias Ringwald #endif 1087dc86dfdSMatthias Ringwald 1097dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_BUFFER_SECTION 1107dc86dfdSMatthias Ringwald #if defined(SEGGER_RTT_SECTION) 1117dc86dfdSMatthias Ringwald #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION 1127dc86dfdSMatthias Ringwald #endif 1137dc86dfdSMatthias Ringwald #endif 1147dc86dfdSMatthias Ringwald 1157dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_ALIGNMENT 1167dc86dfdSMatthias Ringwald #define SEGGER_RTT_ALIGNMENT 0 1177dc86dfdSMatthias Ringwald #endif 1187dc86dfdSMatthias Ringwald 1197dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_BUFFER_ALIGNMENT 1207dc86dfdSMatthias Ringwald #define SEGGER_RTT_BUFFER_ALIGNMENT 0 1217dc86dfdSMatthias Ringwald #endif 1227dc86dfdSMatthias Ringwald 1237dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_MODE_DEFAULT 1247dc86dfdSMatthias Ringwald #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP 1257dc86dfdSMatthias Ringwald #endif 1267dc86dfdSMatthias Ringwald 1277dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_LOCK 1287dc86dfdSMatthias Ringwald #define SEGGER_RTT_LOCK() 1297dc86dfdSMatthias Ringwald #endif 1307dc86dfdSMatthias Ringwald 1317dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_UNLOCK 1327dc86dfdSMatthias Ringwald #define SEGGER_RTT_UNLOCK() 1337dc86dfdSMatthias Ringwald #endif 1347dc86dfdSMatthias Ringwald 1357dc86dfdSMatthias Ringwald #ifndef STRLEN 1367dc86dfdSMatthias Ringwald #define STRLEN(a) strlen((a)) 1377dc86dfdSMatthias Ringwald #endif 1387dc86dfdSMatthias Ringwald 1397dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP 1407dc86dfdSMatthias Ringwald #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 1417dc86dfdSMatthias Ringwald #endif 1427dc86dfdSMatthias Ringwald 1437dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_MEMCPY 1447dc86dfdSMatthias Ringwald #ifdef MEMCPY 1457dc86dfdSMatthias Ringwald #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) 1467dc86dfdSMatthias Ringwald #else 1477dc86dfdSMatthias Ringwald #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) 1487dc86dfdSMatthias Ringwald #endif 1497dc86dfdSMatthias Ringwald #endif 1507dc86dfdSMatthias Ringwald 1517dc86dfdSMatthias Ringwald #ifndef MIN 1527dc86dfdSMatthias Ringwald #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 1537dc86dfdSMatthias Ringwald #endif 1547dc86dfdSMatthias Ringwald 1557dc86dfdSMatthias Ringwald #ifndef MAX 1567dc86dfdSMatthias Ringwald #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 1577dc86dfdSMatthias Ringwald #endif 1587dc86dfdSMatthias Ringwald // 1597dc86dfdSMatthias Ringwald // For some environments, NULL may not be defined until certain headers are included 1607dc86dfdSMatthias Ringwald // 1617dc86dfdSMatthias Ringwald #ifndef NULL 1627dc86dfdSMatthias Ringwald #define NULL 0 1637dc86dfdSMatthias Ringwald #endif 1647dc86dfdSMatthias Ringwald 1657dc86dfdSMatthias Ringwald /********************************************************************* 1667dc86dfdSMatthias Ringwald * 1677dc86dfdSMatthias Ringwald * Defines, fixed 1687dc86dfdSMatthias Ringwald * 1697dc86dfdSMatthias Ringwald ********************************************************************** 1707dc86dfdSMatthias Ringwald */ 1717dc86dfdSMatthias Ringwald #if (defined __ICCARM__) || (defined __ICCRX__) 1727dc86dfdSMatthias Ringwald #define RTT_PRAGMA(P) _Pragma(#P) 1737dc86dfdSMatthias Ringwald #endif 1747dc86dfdSMatthias Ringwald 1757dc86dfdSMatthias Ringwald #if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT 1767dc86dfdSMatthias Ringwald #if (defined __GNUC__) 1777dc86dfdSMatthias Ringwald #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) 1787dc86dfdSMatthias Ringwald #elif (defined __ICCARM__) || (defined __ICCRX__) 1797dc86dfdSMatthias Ringwald #define PRAGMA(A) _Pragma(#A) 1807dc86dfdSMatthias Ringwald #define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ 1817dc86dfdSMatthias Ringwald Var 1827dc86dfdSMatthias Ringwald #elif (defined __CC_ARM) 1837dc86dfdSMatthias Ringwald #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) 1847dc86dfdSMatthias Ringwald #else 1857dc86dfdSMatthias Ringwald #error "Alignment not supported for this compiler." 1867dc86dfdSMatthias Ringwald #endif 1877dc86dfdSMatthias Ringwald #else 1887dc86dfdSMatthias Ringwald #define SEGGER_RTT_ALIGN(Var, Alignment) Var 1897dc86dfdSMatthias Ringwald #endif 1907dc86dfdSMatthias Ringwald 1917dc86dfdSMatthias Ringwald #if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) 1927dc86dfdSMatthias Ringwald #if (defined __GNUC__) 1937dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var 1947dc86dfdSMatthias Ringwald #elif (defined __ICCARM__) || (defined __ICCRX__) 1957dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ 1967dc86dfdSMatthias Ringwald Var 1977dc86dfdSMatthias Ringwald #elif (defined __CC_ARM) 1987dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var 1997dc86dfdSMatthias Ringwald #else 2007dc86dfdSMatthias Ringwald #error "Section placement not supported for this compiler." 2017dc86dfdSMatthias Ringwald #endif 2027dc86dfdSMatthias Ringwald #else 2037dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_SECTION(Var, Section) Var 2047dc86dfdSMatthias Ringwald #endif 2057dc86dfdSMatthias Ringwald 2067dc86dfdSMatthias Ringwald 2077dc86dfdSMatthias Ringwald #if SEGGER_RTT_ALIGNMENT 2087dc86dfdSMatthias Ringwald #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) 2097dc86dfdSMatthias Ringwald #else 2107dc86dfdSMatthias Ringwald #define SEGGER_RTT_CB_ALIGN(Var) Var 2117dc86dfdSMatthias Ringwald #endif 2127dc86dfdSMatthias Ringwald 2137dc86dfdSMatthias Ringwald #if SEGGER_RTT_BUFFER_ALIGNMENT 2147dc86dfdSMatthias Ringwald #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) 2157dc86dfdSMatthias Ringwald #else 2167dc86dfdSMatthias Ringwald #define SEGGER_RTT_BUFFER_ALIGN(Var) Var 2177dc86dfdSMatthias Ringwald #endif 2187dc86dfdSMatthias Ringwald 2197dc86dfdSMatthias Ringwald 2207dc86dfdSMatthias Ringwald #if defined(SEGGER_RTT_SECTION) 2217dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) 2227dc86dfdSMatthias Ringwald #else 2237dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_CB_SECTION(Var) Var 2247dc86dfdSMatthias Ringwald #endif 2257dc86dfdSMatthias Ringwald 2267dc86dfdSMatthias Ringwald #if defined(SEGGER_RTT_BUFFER_SECTION) 2277dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) 2287dc86dfdSMatthias Ringwald #else 2297dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var 2307dc86dfdSMatthias Ringwald #endif 2317dc86dfdSMatthias Ringwald 2327dc86dfdSMatthias Ringwald /********************************************************************* 2337dc86dfdSMatthias Ringwald * 2347dc86dfdSMatthias Ringwald * Static const data 2357dc86dfdSMatthias Ringwald * 2367dc86dfdSMatthias Ringwald ********************************************************************** 2377dc86dfdSMatthias Ringwald */ 2387dc86dfdSMatthias Ringwald 2397dc86dfdSMatthias Ringwald static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 2407dc86dfdSMatthias Ringwald 2417dc86dfdSMatthias Ringwald /********************************************************************* 2427dc86dfdSMatthias Ringwald * 2437dc86dfdSMatthias Ringwald * Static data 2447dc86dfdSMatthias Ringwald * 2457dc86dfdSMatthias Ringwald ********************************************************************** 2467dc86dfdSMatthias Ringwald */ 2477dc86dfdSMatthias Ringwald // 2487dc86dfdSMatthias Ringwald // RTT Control Block and allocate buffers for channel 0 2497dc86dfdSMatthias Ringwald // 2507dc86dfdSMatthias Ringwald SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); 2517dc86dfdSMatthias Ringwald 2527dc86dfdSMatthias Ringwald SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); 2537dc86dfdSMatthias Ringwald SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); 2547dc86dfdSMatthias Ringwald 255779af47bSMatthias Ringwald static unsigned char _ActiveTerminal; 2567dc86dfdSMatthias Ringwald 2577dc86dfdSMatthias Ringwald /********************************************************************* 2587dc86dfdSMatthias Ringwald * 2597dc86dfdSMatthias Ringwald * Static functions 2607dc86dfdSMatthias Ringwald * 2617dc86dfdSMatthias Ringwald ********************************************************************** 2627dc86dfdSMatthias Ringwald */ 2637dc86dfdSMatthias Ringwald 2647dc86dfdSMatthias Ringwald /********************************************************************* 2657dc86dfdSMatthias Ringwald * 2667dc86dfdSMatthias Ringwald * _DoInit() 2677dc86dfdSMatthias Ringwald * 2687dc86dfdSMatthias Ringwald * Function description 2697dc86dfdSMatthias Ringwald * Initializes the control block an buffers. 2707dc86dfdSMatthias Ringwald * May only be called via INIT() to avoid overriding settings. 2717dc86dfdSMatthias Ringwald * 2727dc86dfdSMatthias Ringwald */ 2737dc86dfdSMatthias Ringwald #define INIT() do { \ 2747dc86dfdSMatthias Ringwald if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ 2757dc86dfdSMatthias Ringwald } while (0) 2767dc86dfdSMatthias Ringwald static void _DoInit(void) { 2777dc86dfdSMatthias Ringwald SEGGER_RTT_CB* p; 2787dc86dfdSMatthias Ringwald // 2797dc86dfdSMatthias Ringwald // Initialize control block 2807dc86dfdSMatthias Ringwald // 2817dc86dfdSMatthias Ringwald p = &_SEGGER_RTT; 2827dc86dfdSMatthias Ringwald p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; 2837dc86dfdSMatthias Ringwald p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; 2847dc86dfdSMatthias Ringwald // 2857dc86dfdSMatthias Ringwald // Initialize up buffer 0 2867dc86dfdSMatthias Ringwald // 2877dc86dfdSMatthias Ringwald p->aUp[0].sName = "Terminal"; 2887dc86dfdSMatthias Ringwald p->aUp[0].pBuffer = _acUpBuffer; 2897dc86dfdSMatthias Ringwald p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); 2907dc86dfdSMatthias Ringwald p->aUp[0].RdOff = 0u; 2917dc86dfdSMatthias Ringwald p->aUp[0].WrOff = 0u; 2927dc86dfdSMatthias Ringwald p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; 2937dc86dfdSMatthias Ringwald // 2947dc86dfdSMatthias Ringwald // Initialize down buffer 0 2957dc86dfdSMatthias Ringwald // 2967dc86dfdSMatthias Ringwald p->aDown[0].sName = "Terminal"; 2977dc86dfdSMatthias Ringwald p->aDown[0].pBuffer = _acDownBuffer; 2987dc86dfdSMatthias Ringwald p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); 2997dc86dfdSMatthias Ringwald p->aDown[0].RdOff = 0u; 3007dc86dfdSMatthias Ringwald p->aDown[0].WrOff = 0u; 3017dc86dfdSMatthias Ringwald p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; 3027dc86dfdSMatthias Ringwald // 3037dc86dfdSMatthias Ringwald // Finish initialization of the control block. 3047dc86dfdSMatthias Ringwald // Copy Id string in three steps to make sure "SEGGER RTT" is not found 3057dc86dfdSMatthias Ringwald // in initializer memory (usually flash) by J-Link 3067dc86dfdSMatthias Ringwald // 3077dc86dfdSMatthias Ringwald strcpy(&p->acID[7], "RTT"); 3087dc86dfdSMatthias Ringwald strcpy(&p->acID[0], "SEGGER"); 3097dc86dfdSMatthias Ringwald p->acID[6] = ' '; 3107dc86dfdSMatthias Ringwald } 3117dc86dfdSMatthias Ringwald 3127dc86dfdSMatthias Ringwald /********************************************************************* 3137dc86dfdSMatthias Ringwald * 3147dc86dfdSMatthias Ringwald * _WriteBlocking() 3157dc86dfdSMatthias Ringwald * 3167dc86dfdSMatthias Ringwald * Function description 3177dc86dfdSMatthias Ringwald * Stores a specified number of characters in SEGGER RTT ring buffer 3187dc86dfdSMatthias Ringwald * and updates the associated write pointer which is periodically 3197dc86dfdSMatthias Ringwald * read by the host. 3207dc86dfdSMatthias Ringwald * The caller is responsible for managing the write chunk sizes as 3217dc86dfdSMatthias Ringwald * _WriteBlocking() will block until all data has been posted successfully. 3227dc86dfdSMatthias Ringwald * 3237dc86dfdSMatthias Ringwald * Parameters 3247dc86dfdSMatthias Ringwald * pRing Ring buffer to post to. 3257dc86dfdSMatthias Ringwald * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. 3267dc86dfdSMatthias Ringwald * NumBytes Number of bytes to be stored in the SEGGER RTT control block. 3277dc86dfdSMatthias Ringwald * 3287dc86dfdSMatthias Ringwald * Return value 3297dc86dfdSMatthias Ringwald * >= 0 - Number of bytes written into buffer. 3307dc86dfdSMatthias Ringwald */ 3317dc86dfdSMatthias Ringwald static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { 3327dc86dfdSMatthias Ringwald unsigned NumBytesToWrite; 3337dc86dfdSMatthias Ringwald unsigned NumBytesWritten; 3347dc86dfdSMatthias Ringwald unsigned RdOff; 3357dc86dfdSMatthias Ringwald unsigned WrOff; 3367dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 3377dc86dfdSMatthias Ringwald char* pDst; 3387dc86dfdSMatthias Ringwald #endif 3397dc86dfdSMatthias Ringwald // 3407dc86dfdSMatthias Ringwald // Write data to buffer and handle wrap-around if necessary 3417dc86dfdSMatthias Ringwald // 3427dc86dfdSMatthias Ringwald NumBytesWritten = 0u; 3437dc86dfdSMatthias Ringwald WrOff = pRing->WrOff; 3447dc86dfdSMatthias Ringwald do { 3457dc86dfdSMatthias Ringwald RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime 3467dc86dfdSMatthias Ringwald if (RdOff > WrOff) { 3477dc86dfdSMatthias Ringwald NumBytesToWrite = RdOff - WrOff - 1u; 3487dc86dfdSMatthias Ringwald } else { 3497dc86dfdSMatthias Ringwald NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); 3507dc86dfdSMatthias Ringwald } 3517dc86dfdSMatthias Ringwald NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around 3527dc86dfdSMatthias Ringwald NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); 3537dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 3547dc86dfdSMatthias Ringwald pDst = pRing->pBuffer + WrOff; 3557dc86dfdSMatthias Ringwald NumBytesWritten += NumBytesToWrite; 3567dc86dfdSMatthias Ringwald NumBytes -= NumBytesToWrite; 3577dc86dfdSMatthias Ringwald WrOff += NumBytesToWrite; 3587dc86dfdSMatthias Ringwald while (NumBytesToWrite--) { 3597dc86dfdSMatthias Ringwald *pDst++ = *pBuffer++; 3607dc86dfdSMatthias Ringwald }; 3617dc86dfdSMatthias Ringwald #else 3627dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); 3637dc86dfdSMatthias Ringwald NumBytesWritten += NumBytesToWrite; 3647dc86dfdSMatthias Ringwald pBuffer += NumBytesToWrite; 3657dc86dfdSMatthias Ringwald NumBytes -= NumBytesToWrite; 3667dc86dfdSMatthias Ringwald WrOff += NumBytesToWrite; 3677dc86dfdSMatthias Ringwald #endif 3687dc86dfdSMatthias Ringwald if (WrOff == pRing->SizeOfBuffer) { 3697dc86dfdSMatthias Ringwald WrOff = 0u; 3707dc86dfdSMatthias Ringwald } 3717dc86dfdSMatthias Ringwald pRing->WrOff = WrOff; 3727dc86dfdSMatthias Ringwald } while (NumBytes); 3737dc86dfdSMatthias Ringwald // 3747dc86dfdSMatthias Ringwald return NumBytesWritten; 3757dc86dfdSMatthias Ringwald } 3767dc86dfdSMatthias Ringwald 3777dc86dfdSMatthias Ringwald /********************************************************************* 3787dc86dfdSMatthias Ringwald * 3797dc86dfdSMatthias Ringwald * _WriteNoCheck() 3807dc86dfdSMatthias Ringwald * 3817dc86dfdSMatthias Ringwald * Function description 3827dc86dfdSMatthias Ringwald * Stores a specified number of characters in SEGGER RTT ring buffer 3837dc86dfdSMatthias Ringwald * and updates the associated write pointer which is periodically 3847dc86dfdSMatthias Ringwald * read by the host. 3857dc86dfdSMatthias Ringwald * It is callers responsibility to make sure data actually fits in buffer. 3867dc86dfdSMatthias Ringwald * 3877dc86dfdSMatthias Ringwald * Parameters 3887dc86dfdSMatthias Ringwald * pRing Ring buffer to post to. 3897dc86dfdSMatthias Ringwald * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. 3907dc86dfdSMatthias Ringwald * NumBytes Number of bytes to be stored in the SEGGER RTT control block. 3917dc86dfdSMatthias Ringwald * 3927dc86dfdSMatthias Ringwald * Notes 3937dc86dfdSMatthias Ringwald * (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking 3947dc86dfdSMatthias Ringwald */ 3957dc86dfdSMatthias Ringwald static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { 3967dc86dfdSMatthias Ringwald unsigned NumBytesAtOnce; 3977dc86dfdSMatthias Ringwald unsigned WrOff; 3987dc86dfdSMatthias Ringwald unsigned Rem; 3997dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 4007dc86dfdSMatthias Ringwald char* pDst; 4017dc86dfdSMatthias Ringwald #endif 4027dc86dfdSMatthias Ringwald 4037dc86dfdSMatthias Ringwald WrOff = pRing->WrOff; 4047dc86dfdSMatthias Ringwald Rem = pRing->SizeOfBuffer - WrOff; 4057dc86dfdSMatthias Ringwald if (Rem > NumBytes) { 4067dc86dfdSMatthias Ringwald // 4077dc86dfdSMatthias Ringwald // All data fits before wrap around 4087dc86dfdSMatthias Ringwald // 4097dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 4107dc86dfdSMatthias Ringwald pDst = pRing->pBuffer + WrOff; 4117dc86dfdSMatthias Ringwald WrOff += NumBytes; 4127dc86dfdSMatthias Ringwald while (NumBytes--) { 4137dc86dfdSMatthias Ringwald *pDst++ = *pData++; 4147dc86dfdSMatthias Ringwald }; 4157dc86dfdSMatthias Ringwald pRing->WrOff = WrOff; 4167dc86dfdSMatthias Ringwald #else 4177dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); 4187dc86dfdSMatthias Ringwald pRing->WrOff = WrOff + NumBytes; 4197dc86dfdSMatthias Ringwald #endif 4207dc86dfdSMatthias Ringwald } else { 4217dc86dfdSMatthias Ringwald // 4227dc86dfdSMatthias Ringwald // We reach the end of the buffer, so need to wrap around 4237dc86dfdSMatthias Ringwald // 4247dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 4257dc86dfdSMatthias Ringwald pDst = pRing->pBuffer + WrOff; 4267dc86dfdSMatthias Ringwald NumBytesAtOnce = Rem; 4277dc86dfdSMatthias Ringwald while (NumBytesAtOnce--) { 4287dc86dfdSMatthias Ringwald *pDst++ = *pData++; 4297dc86dfdSMatthias Ringwald }; 4307dc86dfdSMatthias Ringwald pDst = pRing->pBuffer; 4317dc86dfdSMatthias Ringwald NumBytesAtOnce = NumBytes - Rem; 4327dc86dfdSMatthias Ringwald while (NumBytesAtOnce--) { 4337dc86dfdSMatthias Ringwald *pDst++ = *pData++; 4347dc86dfdSMatthias Ringwald }; 4357dc86dfdSMatthias Ringwald pRing->WrOff = NumBytes - Rem; 4367dc86dfdSMatthias Ringwald #else 4377dc86dfdSMatthias Ringwald NumBytesAtOnce = Rem; 4387dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); 4397dc86dfdSMatthias Ringwald NumBytesAtOnce = NumBytes - Rem; 4407dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce); 4417dc86dfdSMatthias Ringwald pRing->WrOff = NumBytesAtOnce; 4427dc86dfdSMatthias Ringwald #endif 4437dc86dfdSMatthias Ringwald } 4447dc86dfdSMatthias Ringwald } 4457dc86dfdSMatthias Ringwald 4467dc86dfdSMatthias Ringwald /********************************************************************* 4477dc86dfdSMatthias Ringwald * 4487dc86dfdSMatthias Ringwald * _PostTerminalSwitch() 4497dc86dfdSMatthias Ringwald * 4507dc86dfdSMatthias Ringwald * Function description 4517dc86dfdSMatthias Ringwald * Switch terminal to the given terminal ID. It is the caller's 4527dc86dfdSMatthias Ringwald * responsibility to ensure the terminal ID is correct and there is 4537dc86dfdSMatthias Ringwald * enough space in the buffer for this to complete successfully. 4547dc86dfdSMatthias Ringwald * 4557dc86dfdSMatthias Ringwald * Parameters 4567dc86dfdSMatthias Ringwald * pRing Ring buffer to post to. 4577dc86dfdSMatthias Ringwald * TerminalId Terminal ID to switch to. 4587dc86dfdSMatthias Ringwald */ 4597dc86dfdSMatthias Ringwald static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { 460779af47bSMatthias Ringwald unsigned char ac[2]; 4617dc86dfdSMatthias Ringwald 4627dc86dfdSMatthias Ringwald ac[0] = 0xFFu; 4637dc86dfdSMatthias Ringwald ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit 464779af47bSMatthias Ringwald _WriteBlocking(pRing, (const char*)ac, 2u); 4657dc86dfdSMatthias Ringwald } 4667dc86dfdSMatthias Ringwald 4677dc86dfdSMatthias Ringwald /********************************************************************* 4687dc86dfdSMatthias Ringwald * 4697dc86dfdSMatthias Ringwald * _GetAvailWriteSpace() 4707dc86dfdSMatthias Ringwald * 4717dc86dfdSMatthias Ringwald * Function description 4727dc86dfdSMatthias Ringwald * Returns the number of bytes that can be written to the ring 4737dc86dfdSMatthias Ringwald * buffer without blocking. 4747dc86dfdSMatthias Ringwald * 4757dc86dfdSMatthias Ringwald * Parameters 4767dc86dfdSMatthias Ringwald * pRing Ring buffer to check. 4777dc86dfdSMatthias Ringwald * 4787dc86dfdSMatthias Ringwald * Return value 4797dc86dfdSMatthias Ringwald * Number of bytes that are free in the buffer. 4807dc86dfdSMatthias Ringwald */ 4817dc86dfdSMatthias Ringwald static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { 4827dc86dfdSMatthias Ringwald unsigned RdOff; 4837dc86dfdSMatthias Ringwald unsigned WrOff; 4847dc86dfdSMatthias Ringwald unsigned r; 4857dc86dfdSMatthias Ringwald // 4867dc86dfdSMatthias Ringwald // Avoid warnings regarding volatile access order. It's not a problem 4877dc86dfdSMatthias Ringwald // in this case, but dampen compiler enthusiasm. 4887dc86dfdSMatthias Ringwald // 4897dc86dfdSMatthias Ringwald RdOff = pRing->RdOff; 4907dc86dfdSMatthias Ringwald WrOff = pRing->WrOff; 4917dc86dfdSMatthias Ringwald if (RdOff <= WrOff) { 4927dc86dfdSMatthias Ringwald r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; 4937dc86dfdSMatthias Ringwald } else { 4947dc86dfdSMatthias Ringwald r = RdOff - WrOff - 1u; 4957dc86dfdSMatthias Ringwald } 4967dc86dfdSMatthias Ringwald return r; 4977dc86dfdSMatthias Ringwald } 4987dc86dfdSMatthias Ringwald 4997dc86dfdSMatthias Ringwald /********************************************************************* 5007dc86dfdSMatthias Ringwald * 5017dc86dfdSMatthias Ringwald * Public code 5027dc86dfdSMatthias Ringwald * 5037dc86dfdSMatthias Ringwald ********************************************************************** 5047dc86dfdSMatthias Ringwald */ 5057dc86dfdSMatthias Ringwald /********************************************************************* 5067dc86dfdSMatthias Ringwald * 5077dc86dfdSMatthias Ringwald * SEGGER_RTT_ReadNoLock() 5087dc86dfdSMatthias Ringwald * 5097dc86dfdSMatthias Ringwald * Function description 5107dc86dfdSMatthias Ringwald * Reads characters from SEGGER real-time-terminal control block 5117dc86dfdSMatthias Ringwald * which have been previously stored by the host. 5127dc86dfdSMatthias Ringwald * Do not lock against interrupts and multiple access. 5137dc86dfdSMatthias Ringwald * 5147dc86dfdSMatthias Ringwald * Parameters 5157dc86dfdSMatthias Ringwald * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). 5167dc86dfdSMatthias Ringwald * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. 5177dc86dfdSMatthias Ringwald * BufferSize Size of the target application buffer. 5187dc86dfdSMatthias Ringwald * 5197dc86dfdSMatthias Ringwald * Return value 5207dc86dfdSMatthias Ringwald * Number of bytes that have been read. 5217dc86dfdSMatthias Ringwald */ 5227dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { 5237dc86dfdSMatthias Ringwald unsigned NumBytesRem; 5247dc86dfdSMatthias Ringwald unsigned NumBytesRead; 5257dc86dfdSMatthias Ringwald unsigned RdOff; 5267dc86dfdSMatthias Ringwald unsigned WrOff; 5277dc86dfdSMatthias Ringwald unsigned char* pBuffer; 5287dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_DOWN* pRing; 5297dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 5307dc86dfdSMatthias Ringwald const char* pSrc; 5317dc86dfdSMatthias Ringwald #endif 5327dc86dfdSMatthias Ringwald // 5337dc86dfdSMatthias Ringwald INIT(); 5347dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aDown[BufferIndex]; 5357dc86dfdSMatthias Ringwald pBuffer = (unsigned char*)pData; 5367dc86dfdSMatthias Ringwald RdOff = pRing->RdOff; 5377dc86dfdSMatthias Ringwald WrOff = pRing->WrOff; 5387dc86dfdSMatthias Ringwald NumBytesRead = 0u; 5397dc86dfdSMatthias Ringwald // 5407dc86dfdSMatthias Ringwald // Read from current read position to wrap-around of buffer, first 5417dc86dfdSMatthias Ringwald // 5427dc86dfdSMatthias Ringwald if (RdOff > WrOff) { 5437dc86dfdSMatthias Ringwald NumBytesRem = pRing->SizeOfBuffer - RdOff; 5447dc86dfdSMatthias Ringwald NumBytesRem = MIN(NumBytesRem, BufferSize); 5457dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 5467dc86dfdSMatthias Ringwald pSrc = pRing->pBuffer + RdOff; 5477dc86dfdSMatthias Ringwald NumBytesRead += NumBytesRem; 5487dc86dfdSMatthias Ringwald BufferSize -= NumBytesRem; 5497dc86dfdSMatthias Ringwald RdOff += NumBytesRem; 5507dc86dfdSMatthias Ringwald while (NumBytesRem--) { 5517dc86dfdSMatthias Ringwald *pBuffer++ = *pSrc++; 5527dc86dfdSMatthias Ringwald }; 5537dc86dfdSMatthias Ringwald #else 5547dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); 5557dc86dfdSMatthias Ringwald NumBytesRead += NumBytesRem; 5567dc86dfdSMatthias Ringwald pBuffer += NumBytesRem; 5577dc86dfdSMatthias Ringwald BufferSize -= NumBytesRem; 5587dc86dfdSMatthias Ringwald RdOff += NumBytesRem; 5597dc86dfdSMatthias Ringwald #endif 5607dc86dfdSMatthias Ringwald // 5617dc86dfdSMatthias Ringwald // Handle wrap-around of buffer 5627dc86dfdSMatthias Ringwald // 5637dc86dfdSMatthias Ringwald if (RdOff == pRing->SizeOfBuffer) { 5647dc86dfdSMatthias Ringwald RdOff = 0u; 5657dc86dfdSMatthias Ringwald } 5667dc86dfdSMatthias Ringwald } 5677dc86dfdSMatthias Ringwald // 5687dc86dfdSMatthias Ringwald // Read remaining items of buffer 5697dc86dfdSMatthias Ringwald // 5707dc86dfdSMatthias Ringwald NumBytesRem = WrOff - RdOff; 5717dc86dfdSMatthias Ringwald NumBytesRem = MIN(NumBytesRem, BufferSize); 5727dc86dfdSMatthias Ringwald if (NumBytesRem > 0u) { 5737dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 5747dc86dfdSMatthias Ringwald pSrc = pRing->pBuffer + RdOff; 5757dc86dfdSMatthias Ringwald NumBytesRead += NumBytesRem; 5767dc86dfdSMatthias Ringwald BufferSize -= NumBytesRem; 5777dc86dfdSMatthias Ringwald RdOff += NumBytesRem; 5787dc86dfdSMatthias Ringwald while (NumBytesRem--) { 5797dc86dfdSMatthias Ringwald *pBuffer++ = *pSrc++; 5807dc86dfdSMatthias Ringwald }; 5817dc86dfdSMatthias Ringwald #else 5827dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); 5837dc86dfdSMatthias Ringwald NumBytesRead += NumBytesRem; 5847dc86dfdSMatthias Ringwald pBuffer += NumBytesRem; 5857dc86dfdSMatthias Ringwald BufferSize -= NumBytesRem; 5867dc86dfdSMatthias Ringwald RdOff += NumBytesRem; 5877dc86dfdSMatthias Ringwald #endif 5887dc86dfdSMatthias Ringwald } 5897dc86dfdSMatthias Ringwald if (NumBytesRead) { 5907dc86dfdSMatthias Ringwald pRing->RdOff = RdOff; 5917dc86dfdSMatthias Ringwald } 5927dc86dfdSMatthias Ringwald // 5937dc86dfdSMatthias Ringwald return NumBytesRead; 5947dc86dfdSMatthias Ringwald } 5957dc86dfdSMatthias Ringwald 5967dc86dfdSMatthias Ringwald /********************************************************************* 5977dc86dfdSMatthias Ringwald * 5987dc86dfdSMatthias Ringwald * SEGGER_RTT_Read 5997dc86dfdSMatthias Ringwald * 6007dc86dfdSMatthias Ringwald * Function description 6017dc86dfdSMatthias Ringwald * Reads characters from SEGGER real-time-terminal control block 6027dc86dfdSMatthias Ringwald * which have been previously stored by the host. 6037dc86dfdSMatthias Ringwald * 6047dc86dfdSMatthias Ringwald * Parameters 6057dc86dfdSMatthias Ringwald * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). 6067dc86dfdSMatthias Ringwald * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. 6077dc86dfdSMatthias Ringwald * BufferSize Size of the target application buffer. 6087dc86dfdSMatthias Ringwald * 6097dc86dfdSMatthias Ringwald * Return value 6107dc86dfdSMatthias Ringwald * Number of bytes that have been read. 6117dc86dfdSMatthias Ringwald */ 6127dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { 6137dc86dfdSMatthias Ringwald unsigned NumBytesRead; 6147dc86dfdSMatthias Ringwald // 6157dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 6167dc86dfdSMatthias Ringwald // 6177dc86dfdSMatthias Ringwald // Call the non-locking read function 6187dc86dfdSMatthias Ringwald // 6197dc86dfdSMatthias Ringwald NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); 6207dc86dfdSMatthias Ringwald // 6217dc86dfdSMatthias Ringwald // Finish up. 6227dc86dfdSMatthias Ringwald // 6237dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 6247dc86dfdSMatthias Ringwald // 6257dc86dfdSMatthias Ringwald return NumBytesRead; 6267dc86dfdSMatthias Ringwald } 6277dc86dfdSMatthias Ringwald 6287dc86dfdSMatthias Ringwald /********************************************************************* 6297dc86dfdSMatthias Ringwald * 6307dc86dfdSMatthias Ringwald * SEGGER_RTT_WriteWithOverwriteNoLock 6317dc86dfdSMatthias Ringwald * 6327dc86dfdSMatthias Ringwald * Function description 6337dc86dfdSMatthias Ringwald * Stores a specified number of characters in SEGGER RTT 6347dc86dfdSMatthias Ringwald * control block. 6357dc86dfdSMatthias Ringwald * SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application 6367dc86dfdSMatthias Ringwald * and overwrites data if the data does not fit into the buffer. 6377dc86dfdSMatthias Ringwald * 6387dc86dfdSMatthias Ringwald * Parameters 6397dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 6407dc86dfdSMatthias Ringwald * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. 6417dc86dfdSMatthias Ringwald * NumBytes Number of bytes to be stored in the SEGGER RTT control block. 6427dc86dfdSMatthias Ringwald * 6437dc86dfdSMatthias Ringwald * Notes 6447dc86dfdSMatthias Ringwald * (1) If there is not enough space in the "Up"-buffer, data is overwritten. 6457dc86dfdSMatthias Ringwald * (2) For performance reasons this function does not call Init() 6467dc86dfdSMatthias Ringwald * and may only be called after RTT has been initialized. 6477dc86dfdSMatthias Ringwald * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. 6487dc86dfdSMatthias Ringwald * (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link 6497dc86dfdSMatthias Ringwald * connection reads RTT data. 6507dc86dfdSMatthias Ringwald */ 6517dc86dfdSMatthias Ringwald void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { 6527dc86dfdSMatthias Ringwald const char* pData; 6537dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 6547dc86dfdSMatthias Ringwald unsigned Avail; 6557dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 6567dc86dfdSMatthias Ringwald char* pDst; 6577dc86dfdSMatthias Ringwald #endif 6587dc86dfdSMatthias Ringwald 6597dc86dfdSMatthias Ringwald pData = (const char *)pBuffer; 6607dc86dfdSMatthias Ringwald // 6617dc86dfdSMatthias Ringwald // Get "to-host" ring buffer and copy some elements into local variables. 6627dc86dfdSMatthias Ringwald // 6637dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[BufferIndex]; 6647dc86dfdSMatthias Ringwald // 6657dc86dfdSMatthias Ringwald // Check if we will overwrite data and need to adjust the RdOff. 6667dc86dfdSMatthias Ringwald // 6677dc86dfdSMatthias Ringwald if (pRing->WrOff == pRing->RdOff) { 6687dc86dfdSMatthias Ringwald Avail = pRing->SizeOfBuffer - 1u; 6697dc86dfdSMatthias Ringwald } else if ( pRing->WrOff < pRing->RdOff) { 6707dc86dfdSMatthias Ringwald Avail = pRing->RdOff - pRing->WrOff - 1u; 6717dc86dfdSMatthias Ringwald } else { 6727dc86dfdSMatthias Ringwald Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; 6737dc86dfdSMatthias Ringwald } 6747dc86dfdSMatthias Ringwald if (NumBytes > Avail) { 6757dc86dfdSMatthias Ringwald pRing->RdOff += (NumBytes - Avail); 6767dc86dfdSMatthias Ringwald while (pRing->RdOff >= pRing->SizeOfBuffer) { 6777dc86dfdSMatthias Ringwald pRing->RdOff -= pRing->SizeOfBuffer; 6787dc86dfdSMatthias Ringwald } 6797dc86dfdSMatthias Ringwald } 6807dc86dfdSMatthias Ringwald // 6817dc86dfdSMatthias Ringwald // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds 6827dc86dfdSMatthias Ringwald // 6837dc86dfdSMatthias Ringwald Avail = pRing->SizeOfBuffer - pRing->WrOff; 6847dc86dfdSMatthias Ringwald do { 6857dc86dfdSMatthias Ringwald if (Avail > NumBytes) { 6867dc86dfdSMatthias Ringwald // 6877dc86dfdSMatthias Ringwald // Last round 6887dc86dfdSMatthias Ringwald // 6897dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 6907dc86dfdSMatthias Ringwald pDst = pRing->pBuffer + pRing->WrOff; 6917dc86dfdSMatthias Ringwald Avail = NumBytes; 6927dc86dfdSMatthias Ringwald while (NumBytes--) { 6937dc86dfdSMatthias Ringwald *pDst++ = *pData++; 6947dc86dfdSMatthias Ringwald }; 6957dc86dfdSMatthias Ringwald pRing->WrOff += Avail; 6967dc86dfdSMatthias Ringwald #else 6977dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes); 6987dc86dfdSMatthias Ringwald pRing->WrOff += NumBytes; 6997dc86dfdSMatthias Ringwald #endif 7007dc86dfdSMatthias Ringwald break; 7017dc86dfdSMatthias Ringwald } else { 7027dc86dfdSMatthias Ringwald // 7037dc86dfdSMatthias Ringwald // Wrap-around necessary, write until wrap-around and reset WrOff 7047dc86dfdSMatthias Ringwald // 7057dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP 7067dc86dfdSMatthias Ringwald pDst = pRing->pBuffer + pRing->WrOff; 7077dc86dfdSMatthias Ringwald NumBytes -= Avail; 7087dc86dfdSMatthias Ringwald while (Avail--) { 7097dc86dfdSMatthias Ringwald *pDst++ = *pData++; 7107dc86dfdSMatthias Ringwald }; 7117dc86dfdSMatthias Ringwald pRing->WrOff = 0; 7127dc86dfdSMatthias Ringwald #else 7137dc86dfdSMatthias Ringwald SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail); 7147dc86dfdSMatthias Ringwald pData += Avail; 7157dc86dfdSMatthias Ringwald pRing->WrOff = 0; 7167dc86dfdSMatthias Ringwald NumBytes -= Avail; 7177dc86dfdSMatthias Ringwald #endif 7187dc86dfdSMatthias Ringwald Avail = (pRing->SizeOfBuffer - 1); 7197dc86dfdSMatthias Ringwald } 7207dc86dfdSMatthias Ringwald } while (NumBytes); 7217dc86dfdSMatthias Ringwald } 7227dc86dfdSMatthias Ringwald 7237dc86dfdSMatthias Ringwald /********************************************************************* 7247dc86dfdSMatthias Ringwald * 7257dc86dfdSMatthias Ringwald * SEGGER_RTT_WriteSkipNoLock 7267dc86dfdSMatthias Ringwald * 7277dc86dfdSMatthias Ringwald * Function description 7287dc86dfdSMatthias Ringwald * Stores a specified number of characters in SEGGER RTT 7297dc86dfdSMatthias Ringwald * control block which is then read by the host. 7307dc86dfdSMatthias Ringwald * SEGGER_RTT_WriteSkipNoLock does not lock the application and 7317dc86dfdSMatthias Ringwald * skips all data, if the data does not fit into the buffer. 7327dc86dfdSMatthias Ringwald * 7337dc86dfdSMatthias Ringwald * Parameters 7347dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 7357dc86dfdSMatthias Ringwald * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. 7367dc86dfdSMatthias Ringwald * NumBytes Number of bytes to be stored in the SEGGER RTT control block. 737779af47bSMatthias Ringwald * MUST be > 0!!! 738779af47bSMatthias Ringwald * This is done for performance reasons, so no initial check has do be done. 7397dc86dfdSMatthias Ringwald * 7407dc86dfdSMatthias Ringwald * Return value 741779af47bSMatthias Ringwald * 1: Data has been copied 742779af47bSMatthias Ringwald * 0: No space, data has not been copied 7437dc86dfdSMatthias Ringwald * 7447dc86dfdSMatthias Ringwald * Notes 7457dc86dfdSMatthias Ringwald * (1) If there is not enough space in the "Up"-buffer, all data is dropped. 7467dc86dfdSMatthias Ringwald * (2) For performance reasons this function does not call Init() 7477dc86dfdSMatthias Ringwald * and may only be called after RTT has been initialized. 7487dc86dfdSMatthias Ringwald * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. 7497dc86dfdSMatthias Ringwald */ 750779af47bSMatthias Ringwald #if (RTT_USE_ASM == 0) 7517dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { 7527dc86dfdSMatthias Ringwald const char* pData; 7537dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 7547dc86dfdSMatthias Ringwald unsigned Avail; 7557dc86dfdSMatthias Ringwald unsigned RdOff; 7567dc86dfdSMatthias Ringwald unsigned WrOff; 7577dc86dfdSMatthias Ringwald unsigned Rem; 758779af47bSMatthias Ringwald // 759779af47bSMatthias Ringwald // Cases: 760779af47bSMatthias Ringwald // 1) RdOff <= WrOff => Space until wrap-around is sufficient 761779af47bSMatthias Ringwald // 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks) 762779af47bSMatthias Ringwald // 3) RdOff < WrOff => No space in buf 763779af47bSMatthias Ringwald // 4) RdOff > WrOff => Space is sufficient 764779af47bSMatthias Ringwald // 5) RdOff > WrOff => No space in buf 765779af47bSMatthias Ringwald // 766779af47bSMatthias Ringwald // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough 767779af47bSMatthias Ringwald // 7687dc86dfdSMatthias Ringwald pData = (const char *)pBuffer; 7697dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[BufferIndex]; 7707dc86dfdSMatthias Ringwald RdOff = pRing->RdOff; 7717dc86dfdSMatthias Ringwald WrOff = pRing->WrOff; 772779af47bSMatthias Ringwald if (RdOff <= WrOff) { // Case 1), 2) or 3) 773779af47bSMatthias Ringwald Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) 774779af47bSMatthias Ringwald if (Avail >= NumBytes) { // Case 1)? 775779af47bSMatthias Ringwald CopyStraight: 776779af47bSMatthias Ringwald memcpy(pRing->pBuffer + WrOff, pData, NumBytes); 7777dc86dfdSMatthias Ringwald pRing->WrOff = WrOff + NumBytes; 7787dc86dfdSMatthias Ringwald return 1; 7797dc86dfdSMatthias Ringwald } 780779af47bSMatthias Ringwald Avail += RdOff; // Space incl. wrap-around 781779af47bSMatthias Ringwald if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit) 7827dc86dfdSMatthias Ringwald Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer 783779af47bSMatthias Ringwald memcpy(pRing->pBuffer + WrOff, pData, Rem); // Copy 1st chunk 7847dc86dfdSMatthias Ringwald NumBytes -= Rem; 785779af47bSMatthias Ringwald // 786779af47bSMatthias Ringwald // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used 787779af47bSMatthias Ringwald // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element 788779af47bSMatthias Ringwald // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks 789779af47bSMatthias Ringwald // Therefore, check if 2nd memcpy is necessary at all 790779af47bSMatthias Ringwald // 791779af47bSMatthias Ringwald if (NumBytes) { 792779af47bSMatthias Ringwald memcpy(pRing->pBuffer, pData + Rem, NumBytes); 7937dc86dfdSMatthias Ringwald } 794779af47bSMatthias Ringwald pRing->WrOff = NumBytes; 7957dc86dfdSMatthias Ringwald return 1; 7967dc86dfdSMatthias Ringwald } 797779af47bSMatthias Ringwald } else { // Potential case 4) 7987dc86dfdSMatthias Ringwald Avail = RdOff - WrOff - 1u; 799779af47bSMatthias Ringwald if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit) 800779af47bSMatthias Ringwald goto CopyStraight; 801779af47bSMatthias Ringwald } 802779af47bSMatthias Ringwald } 803779af47bSMatthias Ringwald return 0; // No space in buffer 804779af47bSMatthias Ringwald } 8057dc86dfdSMatthias Ringwald #endif 8067dc86dfdSMatthias Ringwald 8077dc86dfdSMatthias Ringwald /********************************************************************* 8087dc86dfdSMatthias Ringwald * 8097dc86dfdSMatthias Ringwald * SEGGER_RTT_WriteNoLock 8107dc86dfdSMatthias Ringwald * 8117dc86dfdSMatthias Ringwald * Function description 8127dc86dfdSMatthias Ringwald * Stores a specified number of characters in SEGGER RTT 8137dc86dfdSMatthias Ringwald * control block which is then read by the host. 8147dc86dfdSMatthias Ringwald * SEGGER_RTT_WriteNoLock does not lock the application. 8157dc86dfdSMatthias Ringwald * 8167dc86dfdSMatthias Ringwald * Parameters 8177dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 8187dc86dfdSMatthias Ringwald * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. 8197dc86dfdSMatthias Ringwald * NumBytes Number of bytes to be stored in the SEGGER RTT control block. 8207dc86dfdSMatthias Ringwald * 8217dc86dfdSMatthias Ringwald * Return value 8227dc86dfdSMatthias Ringwald * Number of bytes which have been stored in the "Up"-buffer. 8237dc86dfdSMatthias Ringwald * 8247dc86dfdSMatthias Ringwald * Notes 8257dc86dfdSMatthias Ringwald * (1) Data is stored according to buffer flags. 8267dc86dfdSMatthias Ringwald * (2) For performance reasons this function does not call Init() 8277dc86dfdSMatthias Ringwald * and may only be called after RTT has been initialized. 8287dc86dfdSMatthias Ringwald * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. 8297dc86dfdSMatthias Ringwald */ 8307dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { 8317dc86dfdSMatthias Ringwald unsigned Status; 8327dc86dfdSMatthias Ringwald unsigned Avail; 8337dc86dfdSMatthias Ringwald const char* pData; 8347dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 8357dc86dfdSMatthias Ringwald 8367dc86dfdSMatthias Ringwald pData = (const char *)pBuffer; 8377dc86dfdSMatthias Ringwald // 8387dc86dfdSMatthias Ringwald // Get "to-host" ring buffer. 8397dc86dfdSMatthias Ringwald // 8407dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[BufferIndex]; 8417dc86dfdSMatthias Ringwald // 8427dc86dfdSMatthias Ringwald // How we output depends upon the mode... 8437dc86dfdSMatthias Ringwald // 8447dc86dfdSMatthias Ringwald switch (pRing->Flags) { 8457dc86dfdSMatthias Ringwald case SEGGER_RTT_MODE_NO_BLOCK_SKIP: 8467dc86dfdSMatthias Ringwald // 8477dc86dfdSMatthias Ringwald // If we are in skip mode and there is no space for the whole 8487dc86dfdSMatthias Ringwald // of this output, don't bother. 8497dc86dfdSMatthias Ringwald // 8507dc86dfdSMatthias Ringwald Avail = _GetAvailWriteSpace(pRing); 8517dc86dfdSMatthias Ringwald if (Avail < NumBytes) { 8527dc86dfdSMatthias Ringwald Status = 0u; 8537dc86dfdSMatthias Ringwald } else { 8547dc86dfdSMatthias Ringwald Status = NumBytes; 8557dc86dfdSMatthias Ringwald _WriteNoCheck(pRing, pData, NumBytes); 8567dc86dfdSMatthias Ringwald } 8577dc86dfdSMatthias Ringwald break; 8587dc86dfdSMatthias Ringwald case SEGGER_RTT_MODE_NO_BLOCK_TRIM: 8597dc86dfdSMatthias Ringwald // 8607dc86dfdSMatthias Ringwald // If we are in trim mode, trim to what we can output without blocking. 8617dc86dfdSMatthias Ringwald // 8627dc86dfdSMatthias Ringwald Avail = _GetAvailWriteSpace(pRing); 8637dc86dfdSMatthias Ringwald Status = Avail < NumBytes ? Avail : NumBytes; 8647dc86dfdSMatthias Ringwald _WriteNoCheck(pRing, pData, Status); 8657dc86dfdSMatthias Ringwald break; 8667dc86dfdSMatthias Ringwald case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: 8677dc86dfdSMatthias Ringwald // 8687dc86dfdSMatthias Ringwald // If we are in blocking mode, output everything. 8697dc86dfdSMatthias Ringwald // 8707dc86dfdSMatthias Ringwald Status = _WriteBlocking(pRing, pData, NumBytes); 8717dc86dfdSMatthias Ringwald break; 8727dc86dfdSMatthias Ringwald default: 8737dc86dfdSMatthias Ringwald Status = 0u; 8747dc86dfdSMatthias Ringwald break; 8757dc86dfdSMatthias Ringwald } 8767dc86dfdSMatthias Ringwald // 8777dc86dfdSMatthias Ringwald // Finish up. 8787dc86dfdSMatthias Ringwald // 8797dc86dfdSMatthias Ringwald return Status; 8807dc86dfdSMatthias Ringwald } 8817dc86dfdSMatthias Ringwald 8827dc86dfdSMatthias Ringwald /********************************************************************* 8837dc86dfdSMatthias Ringwald * 8847dc86dfdSMatthias Ringwald * SEGGER_RTT_Write 8857dc86dfdSMatthias Ringwald * 8867dc86dfdSMatthias Ringwald * Function description 8877dc86dfdSMatthias Ringwald * Stores a specified number of characters in SEGGER RTT 8887dc86dfdSMatthias Ringwald * control block which is then read by the host. 8897dc86dfdSMatthias Ringwald * 8907dc86dfdSMatthias Ringwald * Parameters 8917dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 8927dc86dfdSMatthias Ringwald * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. 8937dc86dfdSMatthias Ringwald * NumBytes Number of bytes to be stored in the SEGGER RTT control block. 8947dc86dfdSMatthias Ringwald * 8957dc86dfdSMatthias Ringwald * Return value 8967dc86dfdSMatthias Ringwald * Number of bytes which have been stored in the "Up"-buffer. 8977dc86dfdSMatthias Ringwald * 8987dc86dfdSMatthias Ringwald * Notes 8997dc86dfdSMatthias Ringwald * (1) Data is stored according to buffer flags. 9007dc86dfdSMatthias Ringwald */ 9017dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { 9027dc86dfdSMatthias Ringwald unsigned Status; 9037dc86dfdSMatthias Ringwald // 9047dc86dfdSMatthias Ringwald INIT(); 9057dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 9067dc86dfdSMatthias Ringwald // 9077dc86dfdSMatthias Ringwald // Call the non-locking write function 9087dc86dfdSMatthias Ringwald // 9097dc86dfdSMatthias Ringwald Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); 9107dc86dfdSMatthias Ringwald // 9117dc86dfdSMatthias Ringwald // Finish up. 9127dc86dfdSMatthias Ringwald // 9137dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 9147dc86dfdSMatthias Ringwald // 9157dc86dfdSMatthias Ringwald return Status; 9167dc86dfdSMatthias Ringwald } 9177dc86dfdSMatthias Ringwald 9187dc86dfdSMatthias Ringwald /********************************************************************* 9197dc86dfdSMatthias Ringwald * 9207dc86dfdSMatthias Ringwald * SEGGER_RTT_WriteString 9217dc86dfdSMatthias Ringwald * 9227dc86dfdSMatthias Ringwald * Function description 9237dc86dfdSMatthias Ringwald * Stores string in SEGGER RTT control block. 9247dc86dfdSMatthias Ringwald * This data is read by the host. 9257dc86dfdSMatthias Ringwald * 9267dc86dfdSMatthias Ringwald * Parameters 9277dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 9287dc86dfdSMatthias Ringwald * s Pointer to string. 9297dc86dfdSMatthias Ringwald * 9307dc86dfdSMatthias Ringwald * Return value 9317dc86dfdSMatthias Ringwald * Number of bytes which have been stored in the "Up"-buffer. 9327dc86dfdSMatthias Ringwald * 9337dc86dfdSMatthias Ringwald * Notes 9347dc86dfdSMatthias Ringwald * (1) Data is stored according to buffer flags. 9357dc86dfdSMatthias Ringwald * (2) String passed to this function has to be \0 terminated 9367dc86dfdSMatthias Ringwald * (3) \0 termination character is *not* stored in RTT buffer 9377dc86dfdSMatthias Ringwald */ 9387dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { 9397dc86dfdSMatthias Ringwald unsigned Len; 9407dc86dfdSMatthias Ringwald 9417dc86dfdSMatthias Ringwald Len = STRLEN(s); 9427dc86dfdSMatthias Ringwald return SEGGER_RTT_Write(BufferIndex, s, Len); 9437dc86dfdSMatthias Ringwald } 9447dc86dfdSMatthias Ringwald 9457dc86dfdSMatthias Ringwald /********************************************************************* 9467dc86dfdSMatthias Ringwald * 9477dc86dfdSMatthias Ringwald * SEGGER_RTT_PutCharSkipNoLock 9487dc86dfdSMatthias Ringwald * 9497dc86dfdSMatthias Ringwald * Function description 9507dc86dfdSMatthias Ringwald * Stores a single character/byte in SEGGER RTT buffer. 9517dc86dfdSMatthias Ringwald * SEGGER_RTT_PutCharSkipNoLock does not lock the application and 9527dc86dfdSMatthias Ringwald * skips the byte, if it does not fit into the buffer. 9537dc86dfdSMatthias Ringwald * 9547dc86dfdSMatthias Ringwald * Parameters 9557dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 9567dc86dfdSMatthias Ringwald * c Byte to be stored. 9577dc86dfdSMatthias Ringwald * 9587dc86dfdSMatthias Ringwald * Return value 9597dc86dfdSMatthias Ringwald * Number of bytes which have been stored in the "Up"-buffer. 9607dc86dfdSMatthias Ringwald * 9617dc86dfdSMatthias Ringwald * Notes 9627dc86dfdSMatthias Ringwald * (1) If there is not enough space in the "Up"-buffer, the character is dropped. 9637dc86dfdSMatthias Ringwald * (2) For performance reasons this function does not call Init() 9647dc86dfdSMatthias Ringwald * and may only be called after RTT has been initialized. 9657dc86dfdSMatthias Ringwald * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. 9667dc86dfdSMatthias Ringwald */ 9677dc86dfdSMatthias Ringwald 9687dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { 9697dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 9707dc86dfdSMatthias Ringwald unsigned WrOff; 9717dc86dfdSMatthias Ringwald unsigned Status; 9727dc86dfdSMatthias Ringwald // 9737dc86dfdSMatthias Ringwald // Get "to-host" ring buffer. 9747dc86dfdSMatthias Ringwald // 9757dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[BufferIndex]; 9767dc86dfdSMatthias Ringwald // 9777dc86dfdSMatthias Ringwald // Get write position and handle wrap-around if necessary 9787dc86dfdSMatthias Ringwald // 9797dc86dfdSMatthias Ringwald WrOff = pRing->WrOff + 1; 9807dc86dfdSMatthias Ringwald if (WrOff == pRing->SizeOfBuffer) { 9817dc86dfdSMatthias Ringwald WrOff = 0; 9827dc86dfdSMatthias Ringwald } 9837dc86dfdSMatthias Ringwald // 9847dc86dfdSMatthias Ringwald // Output byte if free space is available 9857dc86dfdSMatthias Ringwald // 9867dc86dfdSMatthias Ringwald if (WrOff != pRing->RdOff) { 9877dc86dfdSMatthias Ringwald pRing->pBuffer[pRing->WrOff] = c; 9887dc86dfdSMatthias Ringwald pRing->WrOff = WrOff; 9897dc86dfdSMatthias Ringwald Status = 1; 9907dc86dfdSMatthias Ringwald } else { 9917dc86dfdSMatthias Ringwald Status = 0; 9927dc86dfdSMatthias Ringwald } 9937dc86dfdSMatthias Ringwald // 9947dc86dfdSMatthias Ringwald return Status; 9957dc86dfdSMatthias Ringwald } 9967dc86dfdSMatthias Ringwald 9977dc86dfdSMatthias Ringwald /********************************************************************* 9987dc86dfdSMatthias Ringwald * 9997dc86dfdSMatthias Ringwald * SEGGER_RTT_PutCharSkip 10007dc86dfdSMatthias Ringwald * 10017dc86dfdSMatthias Ringwald * Function description 10027dc86dfdSMatthias Ringwald * Stores a single character/byte in SEGGER RTT buffer. 10037dc86dfdSMatthias Ringwald * 10047dc86dfdSMatthias Ringwald * Parameters 10057dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 10067dc86dfdSMatthias Ringwald * c Byte to be stored. 10077dc86dfdSMatthias Ringwald * 10087dc86dfdSMatthias Ringwald * Return value 10097dc86dfdSMatthias Ringwald * Number of bytes which have been stored in the "Up"-buffer. 10107dc86dfdSMatthias Ringwald * 10117dc86dfdSMatthias Ringwald * Notes 10127dc86dfdSMatthias Ringwald * (1) If there is not enough space in the "Up"-buffer, the character is dropped. 10137dc86dfdSMatthias Ringwald */ 10147dc86dfdSMatthias Ringwald 10157dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { 10167dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 10177dc86dfdSMatthias Ringwald unsigned WrOff; 10187dc86dfdSMatthias Ringwald unsigned Status; 10197dc86dfdSMatthias Ringwald // 10207dc86dfdSMatthias Ringwald // Prepare 10217dc86dfdSMatthias Ringwald // 10227dc86dfdSMatthias Ringwald INIT(); 10237dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 10247dc86dfdSMatthias Ringwald // 10257dc86dfdSMatthias Ringwald // Get "to-host" ring buffer. 10267dc86dfdSMatthias Ringwald // 10277dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[BufferIndex]; 10287dc86dfdSMatthias Ringwald // 10297dc86dfdSMatthias Ringwald // Get write position and handle wrap-around if necessary 10307dc86dfdSMatthias Ringwald // 10317dc86dfdSMatthias Ringwald WrOff = pRing->WrOff + 1; 10327dc86dfdSMatthias Ringwald if (WrOff == pRing->SizeOfBuffer) { 10337dc86dfdSMatthias Ringwald WrOff = 0; 10347dc86dfdSMatthias Ringwald } 10357dc86dfdSMatthias Ringwald // 10367dc86dfdSMatthias Ringwald // Output byte if free space is available 10377dc86dfdSMatthias Ringwald // 10387dc86dfdSMatthias Ringwald if (WrOff != pRing->RdOff) { 10397dc86dfdSMatthias Ringwald pRing->pBuffer[pRing->WrOff] = c; 10407dc86dfdSMatthias Ringwald pRing->WrOff = WrOff; 10417dc86dfdSMatthias Ringwald Status = 1; 10427dc86dfdSMatthias Ringwald } else { 10437dc86dfdSMatthias Ringwald Status = 0; 10447dc86dfdSMatthias Ringwald } 10457dc86dfdSMatthias Ringwald // 10467dc86dfdSMatthias Ringwald // Finish up. 10477dc86dfdSMatthias Ringwald // 10487dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 10497dc86dfdSMatthias Ringwald // 10507dc86dfdSMatthias Ringwald return Status; 10517dc86dfdSMatthias Ringwald } 10527dc86dfdSMatthias Ringwald 10537dc86dfdSMatthias Ringwald /********************************************************************* 10547dc86dfdSMatthias Ringwald * 10557dc86dfdSMatthias Ringwald * SEGGER_RTT_PutChar 10567dc86dfdSMatthias Ringwald * 10577dc86dfdSMatthias Ringwald * Function description 10587dc86dfdSMatthias Ringwald * Stores a single character/byte in SEGGER RTT buffer. 10597dc86dfdSMatthias Ringwald * 10607dc86dfdSMatthias Ringwald * Parameters 10617dc86dfdSMatthias Ringwald * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). 10627dc86dfdSMatthias Ringwald * c Byte to be stored. 10637dc86dfdSMatthias Ringwald * 10647dc86dfdSMatthias Ringwald * Return value 10657dc86dfdSMatthias Ringwald * Number of bytes which have been stored in the "Up"-buffer. 10667dc86dfdSMatthias Ringwald * 10677dc86dfdSMatthias Ringwald * Notes 10687dc86dfdSMatthias Ringwald * (1) Data is stored according to buffer flags. 10697dc86dfdSMatthias Ringwald */ 10707dc86dfdSMatthias Ringwald 10717dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { 10727dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 10737dc86dfdSMatthias Ringwald unsigned WrOff; 10747dc86dfdSMatthias Ringwald unsigned Status; 10757dc86dfdSMatthias Ringwald // 10767dc86dfdSMatthias Ringwald // Prepare 10777dc86dfdSMatthias Ringwald // 10787dc86dfdSMatthias Ringwald INIT(); 10797dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 10807dc86dfdSMatthias Ringwald // 10817dc86dfdSMatthias Ringwald // Get "to-host" ring buffer. 10827dc86dfdSMatthias Ringwald // 10837dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[BufferIndex]; 10847dc86dfdSMatthias Ringwald // 10857dc86dfdSMatthias Ringwald // Get write position and handle wrap-around if necessary 10867dc86dfdSMatthias Ringwald // 10877dc86dfdSMatthias Ringwald WrOff = pRing->WrOff + 1; 10887dc86dfdSMatthias Ringwald if (WrOff == pRing->SizeOfBuffer) { 10897dc86dfdSMatthias Ringwald WrOff = 0; 10907dc86dfdSMatthias Ringwald } 10917dc86dfdSMatthias Ringwald // 10927dc86dfdSMatthias Ringwald // Wait for free space if mode is set to blocking 10937dc86dfdSMatthias Ringwald // 10947dc86dfdSMatthias Ringwald if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { 10957dc86dfdSMatthias Ringwald while (WrOff == pRing->RdOff) { 10967dc86dfdSMatthias Ringwald ; 10977dc86dfdSMatthias Ringwald } 10987dc86dfdSMatthias Ringwald } 10997dc86dfdSMatthias Ringwald // 11007dc86dfdSMatthias Ringwald // Output byte if free space is available 11017dc86dfdSMatthias Ringwald // 11027dc86dfdSMatthias Ringwald if (WrOff != pRing->RdOff) { 11037dc86dfdSMatthias Ringwald pRing->pBuffer[pRing->WrOff] = c; 11047dc86dfdSMatthias Ringwald pRing->WrOff = WrOff; 11057dc86dfdSMatthias Ringwald Status = 1; 11067dc86dfdSMatthias Ringwald } else { 11077dc86dfdSMatthias Ringwald Status = 0; 11087dc86dfdSMatthias Ringwald } 11097dc86dfdSMatthias Ringwald // 11107dc86dfdSMatthias Ringwald // Finish up. 11117dc86dfdSMatthias Ringwald // 11127dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 11137dc86dfdSMatthias Ringwald // 11147dc86dfdSMatthias Ringwald return Status; 11157dc86dfdSMatthias Ringwald } 11167dc86dfdSMatthias Ringwald 11177dc86dfdSMatthias Ringwald /********************************************************************* 11187dc86dfdSMatthias Ringwald * 11197dc86dfdSMatthias Ringwald * SEGGER_RTT_GetKey 11207dc86dfdSMatthias Ringwald * 11217dc86dfdSMatthias Ringwald * Function description 11227dc86dfdSMatthias Ringwald * Reads one character from the SEGGER RTT buffer. 11237dc86dfdSMatthias Ringwald * Host has previously stored data there. 11247dc86dfdSMatthias Ringwald * 11257dc86dfdSMatthias Ringwald * Return value 11267dc86dfdSMatthias Ringwald * < 0 - No character available (buffer empty). 11277dc86dfdSMatthias Ringwald * >= 0 - Character which has been read. (Possible values: 0 - 255) 11287dc86dfdSMatthias Ringwald * 11297dc86dfdSMatthias Ringwald * Notes 11307dc86dfdSMatthias Ringwald * (1) This function is only specified for accesses to RTT buffer 0. 11317dc86dfdSMatthias Ringwald */ 11327dc86dfdSMatthias Ringwald int SEGGER_RTT_GetKey(void) { 11337dc86dfdSMatthias Ringwald char c; 11347dc86dfdSMatthias Ringwald int r; 11357dc86dfdSMatthias Ringwald 11367dc86dfdSMatthias Ringwald r = (int)SEGGER_RTT_Read(0u, &c, 1u); 11377dc86dfdSMatthias Ringwald if (r == 1) { 11387dc86dfdSMatthias Ringwald r = (int)(unsigned char)c; 11397dc86dfdSMatthias Ringwald } else { 11407dc86dfdSMatthias Ringwald r = -1; 11417dc86dfdSMatthias Ringwald } 11427dc86dfdSMatthias Ringwald return r; 11437dc86dfdSMatthias Ringwald } 11447dc86dfdSMatthias Ringwald 11457dc86dfdSMatthias Ringwald /********************************************************************* 11467dc86dfdSMatthias Ringwald * 11477dc86dfdSMatthias Ringwald * SEGGER_RTT_WaitKey 11487dc86dfdSMatthias Ringwald * 11497dc86dfdSMatthias Ringwald * Function description 11507dc86dfdSMatthias Ringwald * Waits until at least one character is avaible in the SEGGER RTT buffer. 11517dc86dfdSMatthias Ringwald * Once a character is available, it is read and this function returns. 11527dc86dfdSMatthias Ringwald * 11537dc86dfdSMatthias Ringwald * Return value 11547dc86dfdSMatthias Ringwald * >=0 - Character which has been read. 11557dc86dfdSMatthias Ringwald * 11567dc86dfdSMatthias Ringwald * Notes 11577dc86dfdSMatthias Ringwald * (1) This function is only specified for accesses to RTT buffer 0 11587dc86dfdSMatthias Ringwald * (2) This function is blocking if no character is present in RTT buffer 11597dc86dfdSMatthias Ringwald */ 11607dc86dfdSMatthias Ringwald int SEGGER_RTT_WaitKey(void) { 11617dc86dfdSMatthias Ringwald int r; 11627dc86dfdSMatthias Ringwald 11637dc86dfdSMatthias Ringwald do { 11647dc86dfdSMatthias Ringwald r = SEGGER_RTT_GetKey(); 11657dc86dfdSMatthias Ringwald } while (r < 0); 11667dc86dfdSMatthias Ringwald return r; 11677dc86dfdSMatthias Ringwald } 11687dc86dfdSMatthias Ringwald 11697dc86dfdSMatthias Ringwald /********************************************************************* 11707dc86dfdSMatthias Ringwald * 11717dc86dfdSMatthias Ringwald * SEGGER_RTT_HasKey 11727dc86dfdSMatthias Ringwald * 11737dc86dfdSMatthias Ringwald * Function description 11747dc86dfdSMatthias Ringwald * Checks if at least one character for reading is available in the SEGGER RTT buffer. 11757dc86dfdSMatthias Ringwald * 11767dc86dfdSMatthias Ringwald * Return value 11777dc86dfdSMatthias Ringwald * == 0 - No characters are available to read. 11787dc86dfdSMatthias Ringwald * == 1 - At least one character is available. 11797dc86dfdSMatthias Ringwald * 11807dc86dfdSMatthias Ringwald * Notes 11817dc86dfdSMatthias Ringwald * (1) This function is only specified for accesses to RTT buffer 0 11827dc86dfdSMatthias Ringwald */ 11837dc86dfdSMatthias Ringwald int SEGGER_RTT_HasKey(void) { 11847dc86dfdSMatthias Ringwald unsigned RdOff; 11857dc86dfdSMatthias Ringwald int r; 11867dc86dfdSMatthias Ringwald 11877dc86dfdSMatthias Ringwald INIT(); 11887dc86dfdSMatthias Ringwald RdOff = _SEGGER_RTT.aDown[0].RdOff; 11897dc86dfdSMatthias Ringwald if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { 11907dc86dfdSMatthias Ringwald r = 1; 11917dc86dfdSMatthias Ringwald } else { 11927dc86dfdSMatthias Ringwald r = 0; 11937dc86dfdSMatthias Ringwald } 11947dc86dfdSMatthias Ringwald return r; 11957dc86dfdSMatthias Ringwald } 11967dc86dfdSMatthias Ringwald 11977dc86dfdSMatthias Ringwald /********************************************************************* 11987dc86dfdSMatthias Ringwald * 11997dc86dfdSMatthias Ringwald * SEGGER_RTT_HasData 12007dc86dfdSMatthias Ringwald * 12017dc86dfdSMatthias Ringwald * Function description 12027dc86dfdSMatthias Ringwald * Check if there is data from the host in the given buffer. 12037dc86dfdSMatthias Ringwald * 12047dc86dfdSMatthias Ringwald * Return value: 12057dc86dfdSMatthias Ringwald * ==0: No data 12067dc86dfdSMatthias Ringwald * !=0: Data in buffer 12077dc86dfdSMatthias Ringwald * 12087dc86dfdSMatthias Ringwald */ 12097dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { 12107dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_DOWN* pRing; 12117dc86dfdSMatthias Ringwald unsigned v; 12127dc86dfdSMatthias Ringwald 12137dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aDown[BufferIndex]; 12147dc86dfdSMatthias Ringwald v = pRing->WrOff; 12157dc86dfdSMatthias Ringwald return v - pRing->RdOff; 12167dc86dfdSMatthias Ringwald } 12177dc86dfdSMatthias Ringwald 12187dc86dfdSMatthias Ringwald /********************************************************************* 12197dc86dfdSMatthias Ringwald * 1220779af47bSMatthias Ringwald * SEGGER_RTT_HasDataUp 1221779af47bSMatthias Ringwald * 1222779af47bSMatthias Ringwald * Function description 1223779af47bSMatthias Ringwald * Check if there is data remaining to be sent in the given buffer. 1224779af47bSMatthias Ringwald * 1225779af47bSMatthias Ringwald * Return value: 1226779af47bSMatthias Ringwald * ==0: No data 1227779af47bSMatthias Ringwald * !=0: Data in buffer 1228779af47bSMatthias Ringwald * 1229779af47bSMatthias Ringwald */ 1230779af47bSMatthias Ringwald unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { 1231779af47bSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 1232779af47bSMatthias Ringwald unsigned v; 1233779af47bSMatthias Ringwald 1234779af47bSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[BufferIndex]; 1235779af47bSMatthias Ringwald v = pRing->RdOff; 1236779af47bSMatthias Ringwald return pRing->WrOff - v; 1237779af47bSMatthias Ringwald } 1238779af47bSMatthias Ringwald 1239779af47bSMatthias Ringwald /********************************************************************* 1240779af47bSMatthias Ringwald * 12417dc86dfdSMatthias Ringwald * SEGGER_RTT_AllocDownBuffer 12427dc86dfdSMatthias Ringwald * 12437dc86dfdSMatthias Ringwald * Function description 12447dc86dfdSMatthias Ringwald * Run-time configuration of the next down-buffer (H->T). 12457dc86dfdSMatthias Ringwald * The next buffer, which is not used yet is configured. 12467dc86dfdSMatthias Ringwald * This includes: Buffer address, size, name, flags, ... 12477dc86dfdSMatthias Ringwald * 12487dc86dfdSMatthias Ringwald * Parameters 12497dc86dfdSMatthias Ringwald * sName Pointer to a constant name string. 12507dc86dfdSMatthias Ringwald * pBuffer Pointer to a buffer to be used. 12517dc86dfdSMatthias Ringwald * BufferSize Size of the buffer. 12527dc86dfdSMatthias Ringwald * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). 12537dc86dfdSMatthias Ringwald * 12547dc86dfdSMatthias Ringwald * Return value 12557dc86dfdSMatthias Ringwald * >= 0 - O.K. Buffer Index 12567dc86dfdSMatthias Ringwald * < 0 - Error 12577dc86dfdSMatthias Ringwald */ 12587dc86dfdSMatthias Ringwald int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { 12597dc86dfdSMatthias Ringwald int BufferIndex; 12607dc86dfdSMatthias Ringwald 12617dc86dfdSMatthias Ringwald INIT(); 12627dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 12637dc86dfdSMatthias Ringwald BufferIndex = 0; 12647dc86dfdSMatthias Ringwald do { 12657dc86dfdSMatthias Ringwald if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { 12667dc86dfdSMatthias Ringwald break; 12677dc86dfdSMatthias Ringwald } 12687dc86dfdSMatthias Ringwald BufferIndex++; 12697dc86dfdSMatthias Ringwald } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); 12707dc86dfdSMatthias Ringwald if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { 12717dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].sName = sName; 12727dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; 12737dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; 12747dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; 12757dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; 12767dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; 12777dc86dfdSMatthias Ringwald } else { 12787dc86dfdSMatthias Ringwald BufferIndex = -1; 12797dc86dfdSMatthias Ringwald } 12807dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 12817dc86dfdSMatthias Ringwald return BufferIndex; 12827dc86dfdSMatthias Ringwald } 12837dc86dfdSMatthias Ringwald 12847dc86dfdSMatthias Ringwald /********************************************************************* 12857dc86dfdSMatthias Ringwald * 12867dc86dfdSMatthias Ringwald * SEGGER_RTT_AllocUpBuffer 12877dc86dfdSMatthias Ringwald * 12887dc86dfdSMatthias Ringwald * Function description 12897dc86dfdSMatthias Ringwald * Run-time configuration of the next up-buffer (T->H). 12907dc86dfdSMatthias Ringwald * The next buffer, which is not used yet is configured. 12917dc86dfdSMatthias Ringwald * This includes: Buffer address, size, name, flags, ... 12927dc86dfdSMatthias Ringwald * 12937dc86dfdSMatthias Ringwald * Parameters 12947dc86dfdSMatthias Ringwald * sName Pointer to a constant name string. 12957dc86dfdSMatthias Ringwald * pBuffer Pointer to a buffer to be used. 12967dc86dfdSMatthias Ringwald * BufferSize Size of the buffer. 12977dc86dfdSMatthias Ringwald * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). 12987dc86dfdSMatthias Ringwald * 12997dc86dfdSMatthias Ringwald * Return value 13007dc86dfdSMatthias Ringwald * >= 0 - O.K. Buffer Index 13017dc86dfdSMatthias Ringwald * < 0 - Error 13027dc86dfdSMatthias Ringwald */ 13037dc86dfdSMatthias Ringwald int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { 13047dc86dfdSMatthias Ringwald int BufferIndex; 13057dc86dfdSMatthias Ringwald 13067dc86dfdSMatthias Ringwald INIT(); 13077dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 13087dc86dfdSMatthias Ringwald BufferIndex = 0; 13097dc86dfdSMatthias Ringwald do { 13107dc86dfdSMatthias Ringwald if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { 13117dc86dfdSMatthias Ringwald break; 13127dc86dfdSMatthias Ringwald } 13137dc86dfdSMatthias Ringwald BufferIndex++; 13147dc86dfdSMatthias Ringwald } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); 13157dc86dfdSMatthias Ringwald if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { 13167dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].sName = sName; 13177dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; 13187dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; 13197dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; 13207dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; 13217dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; 13227dc86dfdSMatthias Ringwald } else { 13237dc86dfdSMatthias Ringwald BufferIndex = -1; 13247dc86dfdSMatthias Ringwald } 13257dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 13267dc86dfdSMatthias Ringwald return BufferIndex; 13277dc86dfdSMatthias Ringwald } 13287dc86dfdSMatthias Ringwald 13297dc86dfdSMatthias Ringwald /********************************************************************* 13307dc86dfdSMatthias Ringwald * 13317dc86dfdSMatthias Ringwald * SEGGER_RTT_ConfigUpBuffer 13327dc86dfdSMatthias Ringwald * 13337dc86dfdSMatthias Ringwald * Function description 13347dc86dfdSMatthias Ringwald * Run-time configuration of a specific up-buffer (T->H). 13357dc86dfdSMatthias Ringwald * Buffer to be configured is specified by index. 13367dc86dfdSMatthias Ringwald * This includes: Buffer address, size, name, flags, ... 13377dc86dfdSMatthias Ringwald * 13387dc86dfdSMatthias Ringwald * Parameters 13397dc86dfdSMatthias Ringwald * BufferIndex Index of the buffer to configure. 13407dc86dfdSMatthias Ringwald * sName Pointer to a constant name string. 13417dc86dfdSMatthias Ringwald * pBuffer Pointer to a buffer to be used. 13427dc86dfdSMatthias Ringwald * BufferSize Size of the buffer. 13437dc86dfdSMatthias Ringwald * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). 13447dc86dfdSMatthias Ringwald * 13457dc86dfdSMatthias Ringwald * Return value 13467dc86dfdSMatthias Ringwald * >= 0 - O.K. 13477dc86dfdSMatthias Ringwald * < 0 - Error 13487dc86dfdSMatthias Ringwald * 13497dc86dfdSMatthias Ringwald * Additional information 13507dc86dfdSMatthias Ringwald * Buffer 0 is configured on compile-time. 13517dc86dfdSMatthias Ringwald * May only be called once per buffer. 13527dc86dfdSMatthias Ringwald * Buffer name and flags can be reconfigured using the appropriate functions. 13537dc86dfdSMatthias Ringwald */ 13547dc86dfdSMatthias Ringwald int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { 13557dc86dfdSMatthias Ringwald int r; 13567dc86dfdSMatthias Ringwald 13577dc86dfdSMatthias Ringwald INIT(); 13587dc86dfdSMatthias Ringwald if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { 13597dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 13607dc86dfdSMatthias Ringwald if (BufferIndex > 0u) { 13617dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].sName = sName; 13627dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; 13637dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; 13647dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; 13657dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; 13667dc86dfdSMatthias Ringwald } 13677dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; 13687dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 13697dc86dfdSMatthias Ringwald r = 0; 13707dc86dfdSMatthias Ringwald } else { 13717dc86dfdSMatthias Ringwald r = -1; 13727dc86dfdSMatthias Ringwald } 13737dc86dfdSMatthias Ringwald return r; 13747dc86dfdSMatthias Ringwald } 13757dc86dfdSMatthias Ringwald 13767dc86dfdSMatthias Ringwald /********************************************************************* 13777dc86dfdSMatthias Ringwald * 13787dc86dfdSMatthias Ringwald * SEGGER_RTT_ConfigDownBuffer 13797dc86dfdSMatthias Ringwald * 13807dc86dfdSMatthias Ringwald * Function description 13817dc86dfdSMatthias Ringwald * Run-time configuration of a specific down-buffer (H->T). 13827dc86dfdSMatthias Ringwald * Buffer to be configured is specified by index. 13837dc86dfdSMatthias Ringwald * This includes: Buffer address, size, name, flags, ... 13847dc86dfdSMatthias Ringwald * 13857dc86dfdSMatthias Ringwald * Parameters 13867dc86dfdSMatthias Ringwald * BufferIndex Index of the buffer to configure. 13877dc86dfdSMatthias Ringwald * sName Pointer to a constant name string. 13887dc86dfdSMatthias Ringwald * pBuffer Pointer to a buffer to be used. 13897dc86dfdSMatthias Ringwald * BufferSize Size of the buffer. 13907dc86dfdSMatthias Ringwald * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). 13917dc86dfdSMatthias Ringwald * 13927dc86dfdSMatthias Ringwald * Return value 13937dc86dfdSMatthias Ringwald * >= 0 O.K. 13947dc86dfdSMatthias Ringwald * < 0 Error 13957dc86dfdSMatthias Ringwald * 13967dc86dfdSMatthias Ringwald * Additional information 13977dc86dfdSMatthias Ringwald * Buffer 0 is configured on compile-time. 13987dc86dfdSMatthias Ringwald * May only be called once per buffer. 13997dc86dfdSMatthias Ringwald * Buffer name and flags can be reconfigured using the appropriate functions. 14007dc86dfdSMatthias Ringwald */ 14017dc86dfdSMatthias Ringwald int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { 14027dc86dfdSMatthias Ringwald int r; 14037dc86dfdSMatthias Ringwald 14047dc86dfdSMatthias Ringwald INIT(); 14057dc86dfdSMatthias Ringwald if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { 14067dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 14077dc86dfdSMatthias Ringwald if (BufferIndex > 0u) { 14087dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].sName = sName; 14097dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; 14107dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; 14117dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; 14127dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; 14137dc86dfdSMatthias Ringwald } 14147dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; 14157dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 14167dc86dfdSMatthias Ringwald r = 0; 14177dc86dfdSMatthias Ringwald } else { 14187dc86dfdSMatthias Ringwald r = -1; 14197dc86dfdSMatthias Ringwald } 14207dc86dfdSMatthias Ringwald return r; 14217dc86dfdSMatthias Ringwald } 14227dc86dfdSMatthias Ringwald 14237dc86dfdSMatthias Ringwald /********************************************************************* 14247dc86dfdSMatthias Ringwald * 14257dc86dfdSMatthias Ringwald * SEGGER_RTT_SetNameUpBuffer 14267dc86dfdSMatthias Ringwald * 14277dc86dfdSMatthias Ringwald * Function description 14287dc86dfdSMatthias Ringwald * Run-time configuration of a specific up-buffer name (T->H). 14297dc86dfdSMatthias Ringwald * Buffer to be configured is specified by index. 14307dc86dfdSMatthias Ringwald * 14317dc86dfdSMatthias Ringwald * Parameters 14327dc86dfdSMatthias Ringwald * BufferIndex Index of the buffer to renamed. 14337dc86dfdSMatthias Ringwald * sName Pointer to a constant name string. 14347dc86dfdSMatthias Ringwald * 14357dc86dfdSMatthias Ringwald * Return value 14367dc86dfdSMatthias Ringwald * >= 0 O.K. 14377dc86dfdSMatthias Ringwald * < 0 Error 14387dc86dfdSMatthias Ringwald */ 14397dc86dfdSMatthias Ringwald int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { 14407dc86dfdSMatthias Ringwald int r; 14417dc86dfdSMatthias Ringwald 14427dc86dfdSMatthias Ringwald INIT(); 14437dc86dfdSMatthias Ringwald if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { 14447dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 14457dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].sName = sName; 14467dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 14477dc86dfdSMatthias Ringwald r = 0; 14487dc86dfdSMatthias Ringwald } else { 14497dc86dfdSMatthias Ringwald r = -1; 14507dc86dfdSMatthias Ringwald } 14517dc86dfdSMatthias Ringwald return r; 14527dc86dfdSMatthias Ringwald } 14537dc86dfdSMatthias Ringwald 14547dc86dfdSMatthias Ringwald /********************************************************************* 14557dc86dfdSMatthias Ringwald * 14567dc86dfdSMatthias Ringwald * SEGGER_RTT_SetNameDownBuffer 14577dc86dfdSMatthias Ringwald * 14587dc86dfdSMatthias Ringwald * Function description 14597dc86dfdSMatthias Ringwald * Run-time configuration of a specific Down-buffer name (T->H). 14607dc86dfdSMatthias Ringwald * Buffer to be configured is specified by index. 14617dc86dfdSMatthias Ringwald * 14627dc86dfdSMatthias Ringwald * Parameters 14637dc86dfdSMatthias Ringwald * BufferIndex Index of the buffer to renamed. 14647dc86dfdSMatthias Ringwald * sName Pointer to a constant name string. 14657dc86dfdSMatthias Ringwald * 14667dc86dfdSMatthias Ringwald * Return value 14677dc86dfdSMatthias Ringwald * >= 0 O.K. 14687dc86dfdSMatthias Ringwald * < 0 Error 14697dc86dfdSMatthias Ringwald */ 14707dc86dfdSMatthias Ringwald int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { 14717dc86dfdSMatthias Ringwald int r; 14727dc86dfdSMatthias Ringwald 14737dc86dfdSMatthias Ringwald INIT(); 14747dc86dfdSMatthias Ringwald if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { 14757dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 14767dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].sName = sName; 14777dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 14787dc86dfdSMatthias Ringwald r = 0; 14797dc86dfdSMatthias Ringwald } else { 14807dc86dfdSMatthias Ringwald r = -1; 14817dc86dfdSMatthias Ringwald } 14827dc86dfdSMatthias Ringwald return r; 14837dc86dfdSMatthias Ringwald } 14847dc86dfdSMatthias Ringwald 14857dc86dfdSMatthias Ringwald /********************************************************************* 14867dc86dfdSMatthias Ringwald * 14877dc86dfdSMatthias Ringwald * SEGGER_RTT_SetFlagsUpBuffer 14887dc86dfdSMatthias Ringwald * 14897dc86dfdSMatthias Ringwald * Function description 14907dc86dfdSMatthias Ringwald * Run-time configuration of specific up-buffer flags (T->H). 14917dc86dfdSMatthias Ringwald * Buffer to be configured is specified by index. 14927dc86dfdSMatthias Ringwald * 14937dc86dfdSMatthias Ringwald * Parameters 14947dc86dfdSMatthias Ringwald * BufferIndex Index of the buffer. 14957dc86dfdSMatthias Ringwald * Flags Flags to set for the buffer. 14967dc86dfdSMatthias Ringwald * 14977dc86dfdSMatthias Ringwald * Return value 14987dc86dfdSMatthias Ringwald * >= 0 O.K. 14997dc86dfdSMatthias Ringwald * < 0 Error 15007dc86dfdSMatthias Ringwald */ 15017dc86dfdSMatthias Ringwald int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { 15027dc86dfdSMatthias Ringwald int r; 15037dc86dfdSMatthias Ringwald 15047dc86dfdSMatthias Ringwald INIT(); 15057dc86dfdSMatthias Ringwald if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { 15067dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 15077dc86dfdSMatthias Ringwald _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; 15087dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 15097dc86dfdSMatthias Ringwald r = 0; 15107dc86dfdSMatthias Ringwald } else { 15117dc86dfdSMatthias Ringwald r = -1; 15127dc86dfdSMatthias Ringwald } 15137dc86dfdSMatthias Ringwald return r; 15147dc86dfdSMatthias Ringwald } 15157dc86dfdSMatthias Ringwald 15167dc86dfdSMatthias Ringwald /********************************************************************* 15177dc86dfdSMatthias Ringwald * 15187dc86dfdSMatthias Ringwald * SEGGER_RTT_SetFlagsDownBuffer 15197dc86dfdSMatthias Ringwald * 15207dc86dfdSMatthias Ringwald * Function description 15217dc86dfdSMatthias Ringwald * Run-time configuration of specific Down-buffer flags (T->H). 15227dc86dfdSMatthias Ringwald * Buffer to be configured is specified by index. 15237dc86dfdSMatthias Ringwald * 15247dc86dfdSMatthias Ringwald * Parameters 15257dc86dfdSMatthias Ringwald * BufferIndex Index of the buffer to renamed. 15267dc86dfdSMatthias Ringwald * Flags Flags to set for the buffer. 15277dc86dfdSMatthias Ringwald * 15287dc86dfdSMatthias Ringwald * Return value 15297dc86dfdSMatthias Ringwald * >= 0 O.K. 15307dc86dfdSMatthias Ringwald * < 0 Error 15317dc86dfdSMatthias Ringwald */ 15327dc86dfdSMatthias Ringwald int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { 15337dc86dfdSMatthias Ringwald int r; 15347dc86dfdSMatthias Ringwald 15357dc86dfdSMatthias Ringwald INIT(); 15367dc86dfdSMatthias Ringwald if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { 15377dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 15387dc86dfdSMatthias Ringwald _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; 15397dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 15407dc86dfdSMatthias Ringwald r = 0; 15417dc86dfdSMatthias Ringwald } else { 15427dc86dfdSMatthias Ringwald r = -1; 15437dc86dfdSMatthias Ringwald } 15447dc86dfdSMatthias Ringwald return r; 15457dc86dfdSMatthias Ringwald } 15467dc86dfdSMatthias Ringwald 15477dc86dfdSMatthias Ringwald /********************************************************************* 15487dc86dfdSMatthias Ringwald * 15497dc86dfdSMatthias Ringwald * SEGGER_RTT_Init 15507dc86dfdSMatthias Ringwald * 15517dc86dfdSMatthias Ringwald * Function description 15527dc86dfdSMatthias Ringwald * Initializes the RTT Control Block. 15537dc86dfdSMatthias Ringwald * Should be used in RAM targets, at start of the application. 15547dc86dfdSMatthias Ringwald * 15557dc86dfdSMatthias Ringwald */ 15567dc86dfdSMatthias Ringwald void SEGGER_RTT_Init (void) { 15577dc86dfdSMatthias Ringwald _DoInit(); 15587dc86dfdSMatthias Ringwald } 15597dc86dfdSMatthias Ringwald 15607dc86dfdSMatthias Ringwald /********************************************************************* 15617dc86dfdSMatthias Ringwald * 15627dc86dfdSMatthias Ringwald * SEGGER_RTT_SetTerminal 15637dc86dfdSMatthias Ringwald * 15647dc86dfdSMatthias Ringwald * Function description 15657dc86dfdSMatthias Ringwald * Sets the terminal to be used for output on channel 0. 15667dc86dfdSMatthias Ringwald * 15677dc86dfdSMatthias Ringwald * Parameters 15687dc86dfdSMatthias Ringwald * TerminalId Index of the terminal. 15697dc86dfdSMatthias Ringwald * 15707dc86dfdSMatthias Ringwald * Return value 15717dc86dfdSMatthias Ringwald * >= 0 O.K. 15727dc86dfdSMatthias Ringwald * < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) 15737dc86dfdSMatthias Ringwald */ 1574779af47bSMatthias Ringwald int SEGGER_RTT_SetTerminal (unsigned char TerminalId) { 1575779af47bSMatthias Ringwald unsigned char ac[2]; 15767dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 15777dc86dfdSMatthias Ringwald unsigned Avail; 15787dc86dfdSMatthias Ringwald int r; 15797dc86dfdSMatthias Ringwald // 15807dc86dfdSMatthias Ringwald INIT(); 15817dc86dfdSMatthias Ringwald // 15827dc86dfdSMatthias Ringwald r = 0; 1583779af47bSMatthias Ringwald ac[0] = 0xFFu; 1584779af47bSMatthias Ringwald if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels 1585779af47bSMatthias Ringwald ac[1] = _aTerminalId[TerminalId]; 15867dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed 15877dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing 15887dc86dfdSMatthias Ringwald if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { 15897dc86dfdSMatthias Ringwald _ActiveTerminal = TerminalId; 1590779af47bSMatthias Ringwald _WriteBlocking(pRing, (const char*)ac, 2u); 15917dc86dfdSMatthias Ringwald } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes 15927dc86dfdSMatthias Ringwald Avail = _GetAvailWriteSpace(pRing); 15937dc86dfdSMatthias Ringwald if (Avail >= 2) { 15947dc86dfdSMatthias Ringwald _ActiveTerminal = TerminalId; // Only change active terminal in case of success 1595779af47bSMatthias Ringwald _WriteNoCheck(pRing, (const char*)ac, 2u); 15967dc86dfdSMatthias Ringwald } else { 15977dc86dfdSMatthias Ringwald r = -1; 15987dc86dfdSMatthias Ringwald } 15997dc86dfdSMatthias Ringwald } 16007dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 16017dc86dfdSMatthias Ringwald } else { 16027dc86dfdSMatthias Ringwald r = -1; 16037dc86dfdSMatthias Ringwald } 16047dc86dfdSMatthias Ringwald return r; 16057dc86dfdSMatthias Ringwald } 16067dc86dfdSMatthias Ringwald 16077dc86dfdSMatthias Ringwald /********************************************************************* 16087dc86dfdSMatthias Ringwald * 16097dc86dfdSMatthias Ringwald * SEGGER_RTT_TerminalOut 16107dc86dfdSMatthias Ringwald * 16117dc86dfdSMatthias Ringwald * Function description 16127dc86dfdSMatthias Ringwald * Writes a string to the given terminal 16137dc86dfdSMatthias Ringwald * without changing the terminal for channel 0. 16147dc86dfdSMatthias Ringwald * 16157dc86dfdSMatthias Ringwald * Parameters 16167dc86dfdSMatthias Ringwald * TerminalId Index of the terminal. 16177dc86dfdSMatthias Ringwald * s String to be printed on the terminal. 16187dc86dfdSMatthias Ringwald * 16197dc86dfdSMatthias Ringwald * Return value 16207dc86dfdSMatthias Ringwald * >= 0 - Number of bytes written. 16217dc86dfdSMatthias Ringwald * < 0 - Error. 16227dc86dfdSMatthias Ringwald * 16237dc86dfdSMatthias Ringwald */ 1624779af47bSMatthias Ringwald int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) { 16257dc86dfdSMatthias Ringwald int Status; 16267dc86dfdSMatthias Ringwald unsigned FragLen; 16277dc86dfdSMatthias Ringwald unsigned Avail; 16287dc86dfdSMatthias Ringwald SEGGER_RTT_BUFFER_UP* pRing; 16297dc86dfdSMatthias Ringwald // 16307dc86dfdSMatthias Ringwald INIT(); 16317dc86dfdSMatthias Ringwald // 16327dc86dfdSMatthias Ringwald // Validate terminal ID. 16337dc86dfdSMatthias Ringwald // 16347dc86dfdSMatthias Ringwald if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels 16357dc86dfdSMatthias Ringwald // 16367dc86dfdSMatthias Ringwald // Get "to-host" ring buffer. 16377dc86dfdSMatthias Ringwald // 16387dc86dfdSMatthias Ringwald pRing = &_SEGGER_RTT.aUp[0]; 16397dc86dfdSMatthias Ringwald // 16407dc86dfdSMatthias Ringwald // Need to be able to change terminal, write data, change back. 16417dc86dfdSMatthias Ringwald // Compute the fixed and variable sizes. 16427dc86dfdSMatthias Ringwald // 16437dc86dfdSMatthias Ringwald FragLen = STRLEN(s); 16447dc86dfdSMatthias Ringwald // 16457dc86dfdSMatthias Ringwald // How we output depends upon the mode... 16467dc86dfdSMatthias Ringwald // 16477dc86dfdSMatthias Ringwald SEGGER_RTT_LOCK(); 16487dc86dfdSMatthias Ringwald Avail = _GetAvailWriteSpace(pRing); 16497dc86dfdSMatthias Ringwald switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { 16507dc86dfdSMatthias Ringwald case SEGGER_RTT_MODE_NO_BLOCK_SKIP: 16517dc86dfdSMatthias Ringwald // 16527dc86dfdSMatthias Ringwald // If we are in skip mode and there is no space for the whole 16537dc86dfdSMatthias Ringwald // of this output, don't bother switching terminals at all. 16547dc86dfdSMatthias Ringwald // 16557dc86dfdSMatthias Ringwald if (Avail < (FragLen + 4u)) { 16567dc86dfdSMatthias Ringwald Status = 0; 16577dc86dfdSMatthias Ringwald } else { 16587dc86dfdSMatthias Ringwald _PostTerminalSwitch(pRing, TerminalId); 16597dc86dfdSMatthias Ringwald Status = (int)_WriteBlocking(pRing, s, FragLen); 16607dc86dfdSMatthias Ringwald _PostTerminalSwitch(pRing, _ActiveTerminal); 16617dc86dfdSMatthias Ringwald } 16627dc86dfdSMatthias Ringwald break; 16637dc86dfdSMatthias Ringwald case SEGGER_RTT_MODE_NO_BLOCK_TRIM: 16647dc86dfdSMatthias Ringwald // 16657dc86dfdSMatthias Ringwald // If we are in trim mode and there is not enough space for everything, 16667dc86dfdSMatthias Ringwald // trim the output but always include the terminal switch. If no room 16677dc86dfdSMatthias Ringwald // for terminal switch, skip that totally. 16687dc86dfdSMatthias Ringwald // 16697dc86dfdSMatthias Ringwald if (Avail < 4u) { 16707dc86dfdSMatthias Ringwald Status = -1; 16717dc86dfdSMatthias Ringwald } else { 16727dc86dfdSMatthias Ringwald _PostTerminalSwitch(pRing, TerminalId); 16737dc86dfdSMatthias Ringwald Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); 16747dc86dfdSMatthias Ringwald _PostTerminalSwitch(pRing, _ActiveTerminal); 16757dc86dfdSMatthias Ringwald } 16767dc86dfdSMatthias Ringwald break; 16777dc86dfdSMatthias Ringwald case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: 16787dc86dfdSMatthias Ringwald // 16797dc86dfdSMatthias Ringwald // If we are in blocking mode, output everything. 16807dc86dfdSMatthias Ringwald // 16817dc86dfdSMatthias Ringwald _PostTerminalSwitch(pRing, TerminalId); 16827dc86dfdSMatthias Ringwald Status = (int)_WriteBlocking(pRing, s, FragLen); 16837dc86dfdSMatthias Ringwald _PostTerminalSwitch(pRing, _ActiveTerminal); 16847dc86dfdSMatthias Ringwald break; 16857dc86dfdSMatthias Ringwald default: 16867dc86dfdSMatthias Ringwald Status = -1; 16877dc86dfdSMatthias Ringwald break; 16887dc86dfdSMatthias Ringwald } 16897dc86dfdSMatthias Ringwald // 16907dc86dfdSMatthias Ringwald // Finish up. 16917dc86dfdSMatthias Ringwald // 16927dc86dfdSMatthias Ringwald SEGGER_RTT_UNLOCK(); 16937dc86dfdSMatthias Ringwald } else { 16947dc86dfdSMatthias Ringwald Status = -1; 16957dc86dfdSMatthias Ringwald } 16967dc86dfdSMatthias Ringwald return Status; 16977dc86dfdSMatthias Ringwald } 16987dc86dfdSMatthias Ringwald 1699*a20be900SMatthias Ringwald /********************************************************************* 1700*a20be900SMatthias Ringwald * 1701*a20be900SMatthias Ringwald * SEGGER_RTT_GetAvailWriteSpace 1702*a20be900SMatthias Ringwald * Returns the number of bytes that can be written to the ring 1703*a20be900SMatthias Ringwald * buffer without blocking. 1704*a20be900SMatthias Ringwald * 1705*a20be900SMatthias Ringwald * Parameters 1706*a20be900SMatthias Ringwald * BufferIndex Index of the buffer. 1707*a20be900SMatthias Ringwald * 1708*a20be900SMatthias Ringwald * Return value 1709*a20be900SMatthias Ringwald * Number of bytes that are free in the buffer. 1710*a20be900SMatthias Ringwald */ 1711*a20be900SMatthias Ringwald 1712*a20be900SMatthias Ringwald unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex){ 1713*a20be900SMatthias Ringwald return _GetAvailWriteSpace(&_SEGGER_RTT.aUp[BufferIndex]); 1714*a20be900SMatthias Ringwald } 1715*a20be900SMatthias Ringwald 17167dc86dfdSMatthias Ringwald 17177dc86dfdSMatthias Ringwald /*************************** End of file ****************************/ 1718