Skip to content

Commit 0f2d763

Browse files
committed
Zero-init RTT control block fields if not in BSS, don't init it twice
If SEGGER_RTT_SECTION is defined, the RTT control block is not in BSS and zero initialization is needed for not initialized fields. Moreover, it the control block is already initialized with the expected SEGGER Id string, the initialization is skipped to allow seamless logging between programs that share it. Typical use case: bootloader and application. Signed-off-by: Giancarlo Stasi <[email protected]>
1 parent e2ff220 commit 0f2d763

File tree

1 file changed

+74
-29
lines changed

1 file changed

+74
-29
lines changed

SEGGER/SEGGER_RTT.c

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,26 @@ Additional information:
167167
#endif
168168
#endif
169169

170+
#ifndef SEGGER_RTT_MEMCMP
171+
#ifdef MEMCPY
172+
#define SEGGER_RTT_MEMCMP(pDest, pSrc, NumBytes) MEMCMP((pDest), (pSrc), (NumBytes))
173+
#else
174+
#define SEGGER_RTT_MEMCMP(pDest, pSrc, NumBytes) memcmp((pDest), (pSrc), (NumBytes))
175+
#endif
176+
#endif
177+
178+
#ifndef SEGGER_RTT_MEMSET
179+
#ifdef MEMSET
180+
#define SEGGER_RTT_MEMSET(pDest, FillChar, NumBytes) MEMCPY((pDest), (FillChar), (NumBytes))
181+
#else
182+
#define SEGGER_RTT_MEMSET(pDest, FillChar, NumBytes) memset((pDest), (FillChar), (NumBytes))
183+
#endif
184+
#endif
185+
186+
#ifndef ARRAY_SIZE
187+
# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
188+
#endif
189+
170190
#ifndef MIN
171191
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
172192
#endif
@@ -285,19 +305,9 @@ static unsigned char _ActiveTerminal;
285305
*
286306
* Function description
287307
* Initializes the control block an buffers.
288-
* May only be called via INIT() to avoid overriding settings.
308+
* May only be called via Init() to avoid overriding settings.
289309
*
290310
*/
291-
#define INIT() { \
292-
volatile SEGGER_RTT_CB* pRTTCBInit; \
293-
pRTTCBInit = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \
294-
do { \
295-
if (pRTTCBInit->acID[0] == '\0') { \
296-
_DoInit(); \
297-
} \
298-
} while (0); \
299-
}
300-
301311
static void _DoInit(void) {
302312
volatile SEGGER_RTT_CB* p; // Volatile to make sure that compiler cannot change the order of accesses to the control block
303313
//
@@ -335,6 +345,41 @@ static void _DoInit(void) {
335345
RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
336346
p->acID[6] = ' ';
337347
RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
348+
#if defined(SEGGER_RTT_SECTION) // Control block not in .bss section: needs explicit zero-initializations
349+
// RTT Viewer checks even trailing null bytes to be initialized
350+
for (unsigned int i = 10; i < ARRAY_SIZE(p->acID); ++i)
351+
{
352+
p->acID[i] = '\0';
353+
}
354+
RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
355+
// Initialize other up buffers
356+
for (unsigned int i = 1; i < ARRAY_SIZE(p->aUp); ++i)
357+
{
358+
SEGGER_RTT_MEMSET((SEGGER_RTT_BUFFER_UP*)&p->aUp[i], 0, sizeof(p->aUp[i]));
359+
}
360+
RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
361+
// Initialize other down buffers
362+
for (unsigned int i = 1; i < ARRAY_SIZE(p->aDown); ++i)
363+
{
364+
SEGGER_RTT_MEMSET((SEGGER_RTT_BUFFER_DOWN*)&p->aDown[i], 0, sizeof(p->aDown[i]));
365+
}
366+
RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order
367+
#endif
368+
}
369+
370+
static void Init(void) {
371+
volatile SEGGER_RTT_CB* p;
372+
p = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);
373+
374+
/* Check the whole Id string buffer (including trailing zeros) to be the expected value.
375+
* If already initialized, the control block initialization is skipped, as it may be shared between bootloader
376+
* and application. Not used a single memcmp() to make sure "SEGGER RTT" is not found in initializer
377+
* memory (usually flash) by J-Link (as above in initializing). */
378+
if (SEGGER_RTT_MEMCMP((char*)&p->acID[7], "RTT", 3) != 0 || SEGGER_RTT_MEMCMP((char*)&p->acID[0], "SEGGER", 6) != 0 ||
379+
p->acID[6] != ' ' || p->acID[10] != '\0' || p->acID[11] != '\0' || p->acID[12] != '\0' ||
380+
p->acID[13] != '\0' || p->acID[14] != '\0' || p->acID[15] != '\0') {
381+
_DoInit();
382+
}
338383
}
339384

340385
/*********************************************************************
@@ -564,7 +609,7 @@ unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsign
564609
SEGGER_RTT_BUFFER_UP* pRing;
565610
volatile char* pSrc;
566611

567-
INIT();
612+
Init();
568613
pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
569614
pBuffer = (unsigned char*)pData;
570615
RdOff = pRing->RdOff;
@@ -656,7 +701,7 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe
656701
SEGGER_RTT_BUFFER_DOWN* pRing;
657702
volatile char* pSrc;
658703
//
659-
INIT();
704+
Init();
660705
pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
661706
pBuffer = (unsigned char*)pData;
662707
RdOff = pRing->RdOff;
@@ -1160,7 +1205,7 @@ unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsig
11601205
unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
11611206
unsigned Status;
11621207

1163-
INIT();
1208+
Init();
11641209
SEGGER_RTT_LOCK();
11651210
Status = SEGGER_RTT_WriteDownBufferNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function
11661211
SEGGER_RTT_UNLOCK();
@@ -1189,7 +1234,7 @@ unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, u
11891234
unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
11901235
unsigned Status;
11911236

1192-
INIT();
1237+
Init();
11931238
SEGGER_RTT_LOCK();
11941239
Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); // Call the non-locking write function
11951240
SEGGER_RTT_UNLOCK();
@@ -1304,7 +1349,7 @@ unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) {
13041349
//
13051350
// Prepare
13061351
//
1307-
INIT();
1352+
Init();
13081353
SEGGER_RTT_LOCK();
13091354
//
13101355
// Get "to-host" ring buffer.
@@ -1363,7 +1408,7 @@ unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) {
13631408
//
13641409
// Prepare
13651410
//
1366-
INIT();
1411+
Init();
13671412
SEGGER_RTT_LOCK();
13681413
//
13691414
// Get "to-host" ring buffer.
@@ -1474,7 +1519,7 @@ int SEGGER_RTT_HasKey(void) {
14741519
unsigned RdOff;
14751520
int r;
14761521

1477-
INIT();
1522+
Init();
14781523
pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[0] + SEGGER_RTT_UNCACHED_OFF); // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
14791524
RdOff = pRing->RdOff;
14801525
if (RdOff != pRing->WrOff) {
@@ -1550,7 +1595,7 @@ int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned Buffer
15501595
int BufferIndex;
15511596
volatile SEGGER_RTT_CB* pRTTCB;
15521597

1553-
INIT();
1598+
Init();
15541599
SEGGER_RTT_LOCK();
15551600
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
15561601
BufferIndex = 0;
@@ -1598,7 +1643,7 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi
15981643
int BufferIndex;
15991644
volatile SEGGER_RTT_CB* pRTTCB;
16001645

1601-
INIT();
1646+
Init();
16021647
SEGGER_RTT_LOCK();
16031648
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
16041649
BufferIndex = 0;
@@ -1653,7 +1698,7 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu
16531698
volatile SEGGER_RTT_CB* pRTTCB;
16541699
volatile SEGGER_RTT_BUFFER_UP* pUp;
16551700

1656-
INIT();
1701+
Init();
16571702
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
16581703
if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) {
16591704
SEGGER_RTT_LOCK();
@@ -1704,7 +1749,7 @@ int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* p
17041749
volatile SEGGER_RTT_CB* pRTTCB;
17051750
volatile SEGGER_RTT_BUFFER_DOWN* pDown;
17061751

1707-
INIT();
1752+
Init();
17081753
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
17091754
if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) {
17101755
SEGGER_RTT_LOCK();
@@ -1747,7 +1792,7 @@ int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) {
17471792
volatile SEGGER_RTT_CB* pRTTCB;
17481793
volatile SEGGER_RTT_BUFFER_UP* pUp;
17491794

1750-
INIT();
1795+
Init();
17511796
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
17521797
if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) {
17531798
SEGGER_RTT_LOCK();
@@ -1782,7 +1827,7 @@ int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
17821827
volatile SEGGER_RTT_CB* pRTTCB;
17831828
volatile SEGGER_RTT_BUFFER_DOWN* pDown;
17841829

1785-
INIT();
1830+
Init();
17861831
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
17871832
if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) {
17881833
SEGGER_RTT_LOCK();
@@ -1817,7 +1862,7 @@ int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) {
18171862
volatile SEGGER_RTT_CB* pRTTCB;
18181863
volatile SEGGER_RTT_BUFFER_UP* pUp;
18191864

1820-
INIT();
1865+
Init();
18211866
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
18221867
if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) {
18231868
SEGGER_RTT_LOCK();
@@ -1852,7 +1897,7 @@ int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
18521897
volatile SEGGER_RTT_CB* pRTTCB;
18531898
volatile SEGGER_RTT_BUFFER_DOWN* pDown;
18541899

1855-
INIT();
1900+
Init();
18561901
pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
18571902
if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) {
18581903
SEGGER_RTT_LOCK();
@@ -1876,7 +1921,7 @@ int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
18761921
*
18771922
*/
18781923
void SEGGER_RTT_Init (void) {
1879-
_DoInit();
1924+
Init();
18801925
}
18811926

18821927
/*********************************************************************
@@ -1902,7 +1947,7 @@ int SEGGER_RTT_SetTerminal (unsigned char TerminalId) {
19021947
unsigned Avail;
19031948
int r;
19041949

1905-
INIT();
1950+
Init();
19061951
r = 0;
19071952
ac[0] = 0xFFu;
19081953
if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels
@@ -1951,7 +1996,7 @@ int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) {
19511996
unsigned Avail;
19521997
SEGGER_RTT_BUFFER_UP* pRing;
19531998
//
1954-
INIT();
1999+
Init();
19552000
//
19562001
// Validate terminal ID.
19572002
//

0 commit comments

Comments
 (0)