From 2589d48c8b4abf17ac0994cbd4b4facdf898c783 Mon Sep 17 00:00:00 2001 From: cepetr Date: Tue, 15 Oct 2024 16:43:24 +0200 Subject: [PATCH] fix(core): fix & upgrade systemview target code [no changelog] --- core/SConscript.kernel | 4 +- core/embed/firmware/systemview.c | 105 +-- core/embed/firmware/systemview.h | 28 +- core/embed/kernel/main.c | 1 + core/embed/segger/Config/Global.h | 4 +- core/embed/segger/Config/SEGGER_RTT_Conf.h | 10 +- .../embed/segger/Config/SEGGER_SYSVIEW_Conf.h | 12 +- .../SEGGER_SYSVIEW_Config_NoOS.c | 9 +- core/embed/segger/SEGGER/SEGGER.h | 4 +- core/embed/segger/SEGGER/SEGGER_RTT.c | 209 +++-- core/embed/segger/SEGGER/SEGGER_RTT.h | 232 +++-- core/embed/segger/SEGGER/SEGGER_RTT_printf.c | 7 +- core/embed/segger/SEGGER/SEGGER_SYSVIEW.c | 798 +++++++++++++++--- core/embed/segger/SEGGER/SEGGER_SYSVIEW.h | 76 +- .../SEGGER/SEGGER_SYSVIEW_ConfDefaults.h | 42 +- core/embed/segger/SEGGER/SEGGER_SYSVIEW_Int.h | 4 +- .../SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c | 6 +- core/embed/trezorhal/stm32f4/systask.c | 5 - 18 files changed, 1135 insertions(+), 421 deletions(-) rename core/embed/segger/{SEGGER => Config}/SEGGER_SYSVIEW_Config_NoOS.c (96%) diff --git a/core/SConscript.kernel b/core/SConscript.kernel index 80f3b0d7d3..af58880b68 100644 --- a/core/SConscript.kernel +++ b/core/SConscript.kernel @@ -225,8 +225,8 @@ if FEATURE_FLAGS["RDI"]: CPPDEFINES_MOD += ['RDI'] if FEATURE_FLAGS["SYSTEM_VIEW"]: - SOURCE_FIRMWARE += [ - 'embed/segger/SEGGER/SEGGER_SYSVIEW_Config_NoOS.c', + SOURCE_MOD += [ + 'embed/segger/Config/SEGGER_SYSVIEW_Config_NoOS.c', 'embed/segger/SEGGER/SEGGER_SYSVIEW.c', 'embed/segger/SEGGER/SEGGER_RTT.c', 'embed/segger/SEGGER/SEGGER_RTT_ASM_ARMv7M.S', diff --git a/core/embed/firmware/systemview.c b/core/embed/firmware/systemview.c index 91021d2f01..c89c5b95d3 100644 --- a/core/embed/firmware/systemview.c +++ b/core/embed/firmware/systemview.c @@ -1,101 +1,34 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifdef SYSTEM_VIEW #include "systemview.h" -#include -#include #include -#include "irq.h" #include "mpconfigport.h" #include "SEGGER_SYSVIEW.h" #include "SEGGER_SYSVIEW_Conf.h" -#define SYSTICK ((SYSTICK_REGS *)0xE000E010) -#define SCS ((SCS_REGS *)0xE000ED00) - -// for storing DWT CYCCNT from SVC call -volatile uint32_t cyccnt_cycles; - -typedef struct { - volatile unsigned int CSR; - volatile unsigned int RVR; - volatile unsigned int CVR; - volatile unsigned int CALIB; -} SYSTICK_REGS; - -typedef struct { - volatile unsigned int CPUID; // CPUID Base Register - volatile unsigned int ICSR; // Interrupt Control and State Register - volatile unsigned int VTOR; // Vector Table Offset Register - volatile unsigned int - AIRCR; // Application Interrupt and Reset Control Register - volatile unsigned int SCR; // System Control Register - volatile unsigned int CCR; // Configuration and Control Register - volatile unsigned int SHPR1; // System Handler Priority Register 1 - volatile unsigned int SHPR2; // System Handler Priority Register 2 - volatile unsigned int SHPR3; // System Handler Priority Register 3 - volatile unsigned int SHCSR; // System Handler Control and State Register - volatile unsigned int CFSR; // Configurable Fault Status Register - volatile unsigned int HFSR; // HardFault Status Register - volatile unsigned int DFSR; // Debug Fault Status Register - volatile unsigned int MMFAR; // MemManage Fault Address Register - volatile unsigned int BFAR; // BusFault Address Register - volatile unsigned int AFSR; // Auxiliary Fault Status Register - volatile unsigned int aDummy0[4]; // 0x40-0x4C Reserved - volatile unsigned int aDummy1[4]; // 0x50-0x5C Reserved - volatile unsigned int aDummy2[4]; // 0x60-0x6C Reserved - volatile unsigned int aDummy3[4]; // 0x70-0x7C Reserved - volatile unsigned int aDummy4[2]; // 0x80-0x87 - - - Reserved. - volatile unsigned int CPACR; // Coprocessor Access Control Register -} SCS_REGS; - -extern uint32_t SystemCoreClock; - -static inline uint32_t is_mode_unprivileged(void) { - uint32_t r0; - __asm__ volatile("mrs %0, control" : "=r"(r0)); - return r0 & 1; -} - -uint32_t svc_get_dwt_cyccnt() { - if (is_mode_unprivileged()) { - __asm__ __volatile__("svc %0" ::"i"(SVC_GET_DWT_CYCCNT)); - } else { - cyccnt_cycles = *DWT_CYCCNT_ADDR; - } - return cyccnt_cycles; -} - -U32 SEGGER_SYSVIEW_X_GetInterruptId() { - return ((*(U32 *)(0xE000ED04)) & 0x1FF); -} - void enable_systemview() { SEGGER_SYSVIEW_Conf(); SEGGER_SYSVIEW_Start(); - - U32 v; - // - // Configure SysTick and debug monitor interrupt priorities - // Low value means high priority - // A maximum of 8 priority bits and a minimum of 3 bits is implemented per - // interrupt. How many bits are implemented depends on the actual CPU being - // used If less than 8 bits are supported, the lower bits of the priority byte - // are RAZ. In order to make sure that priority of monitor and SysTick always - // differ, please make sure that the difference is visible in the highest 3 - // bits - v = SCS->SHPR3; - v |= (0xFFuL << 24); // Lowest prio for SysTick so SystemView does not get - // interrupted by Systick - SCS->SHPR3 = v; - // - // Configure SysTick interrupt - // SysTick is running at CPU speed - // Configure SysTick to fire every ms - // - SYSTICK->RVR = (SystemCoreClock / 1000) - 1; // set reload - SYSTICK->CVR = 0x00; // set counter - SYSTICK->CSR = 0x07; // enable systick } #ifdef SYSTEMVIEW_DEST_RTT diff --git a/core/embed/firmware/systemview.h b/core/embed/firmware/systemview.h index f21ed18400..e4e3b5ee14 100644 --- a/core/embed/firmware/systemview.h +++ b/core/embed/firmware/systemview.h @@ -1,19 +1,31 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifndef CORE_SYSTEMVIEW_H #define CORE_SYSTEMVIEW_H #ifdef SYSTEM_VIEW -#include #include "SEGGER_SYSVIEW.h" -#define DWT_CYCCNT_ADDR ((uint32_t*)(0xE0001004)); -#define SVC_GET_DWT_CYCCNT 3 - -extern volatile uint32_t cyccnt_cycles; - -void enable_systemview(); -uint32_t svc_get_dwt_cyccnt(); +void enable_systemview(void); #else #define SEGGER_SYSVIEW_RecordEnterISR() diff --git a/core/embed/kernel/main.c b/core/embed/kernel/main.c index 407cd27065..18f9c3c2fc 100644 --- a/core/embed/kernel/main.c +++ b/core/embed/kernel/main.c @@ -45,6 +45,7 @@ #include "secret.h" #include "secure_aes.h" #include "system.h" +#include "systemview.h" #include "systick.h" #include "tamper.h" #include "touch.h" diff --git a/core/embed/segger/Config/Global.h b/core/embed/segger/Config/Global.h index e2ef4264b7..c9c1d72b1d 100644 --- a/core/embed/segger/Config/Global.h +++ b/core/embed/segger/Config/Global.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** ---------------------------------------------------------------------- diff --git a/core/embed/segger/Config/SEGGER_RTT_Conf.h b/core/embed/segger/Config/SEGGER_RTT_Conf.h index 4087f67003..2d7509ce20 100644 --- a/core/embed/segger/Config/SEGGER_RTT_Conf.h +++ b/core/embed/segger/Config/SEGGER_RTT_Conf.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ @@ -50,7 +50,7 @@ File : SEGGER_RTT_Conf.h Purpose : Implementation of SEGGER real-time transfer (RTT) which allows real-time communication on targets which support debugger memory accesses while the CPU is running. -Revision: $Rev: 21386 $ +Revision: $Rev: 24316 $ */ @@ -169,7 +169,7 @@ Revision: $Rev: 21386 $ : \ ); \ } - #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)) + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__)) #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) #endif @@ -190,7 +190,7 @@ Revision: $Rev: 21386 $ ); \ } - #elif defined(__ARM_ARCH_7A__) + #elif (defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)) #define SEGGER_RTT_LOCK() { \ unsigned int _SEGGER_RTT__LockState; \ __asm volatile ("mrs r1, CPSR \n\t" \ diff --git a/core/embed/segger/Config/SEGGER_SYSVIEW_Conf.h b/core/embed/segger/Config/SEGGER_SYSVIEW_Conf.h index 4d88871d35..07fc1628f4 100644 --- a/core/embed/segger/Config/SEGGER_SYSVIEW_Conf.h +++ b/core/embed/segger/Config/SEGGER_SYSVIEW_Conf.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- @@ -74,10 +74,10 @@ Additional information: ********************************************************************** */ -/********************************************************************* -* TODO: Add your defines here. * -********************************************************************** -*/ + +#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 4096 + +#define SEGGER_SYSVIEW_MAX_STRING_LEN 1024 #define SEGGER_SYSVIEW_BUFFER_SECTION "CCMRAM" diff --git a/core/embed/segger/SEGGER/SEGGER_SYSVIEW_Config_NoOS.c b/core/embed/segger/Config/SEGGER_SYSVIEW_Config_NoOS.c similarity index 96% rename from core/embed/segger/SEGGER/SEGGER_SYSVIEW_Config_NoOS.c rename to core/embed/segger/Config/SEGGER_SYSVIEW_Config_NoOS.c index 0061f0a8ff..84a4904e16 100644 --- a/core/embed/segger/SEGGER/SEGGER_SYSVIEW_Config_NoOS.c +++ b/core/embed/segger/Config/SEGGER_SYSVIEW_Config_NoOS.c @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- @@ -68,7 +68,7 @@ extern unsigned int SystemCoreClock; #define SYSVIEW_APP_NAME "Trezor Core" // The target device name -#define SYSVIEW_DEVICE_NAME "STM32F427VI" +#define SYSVIEW_DEVICE_NAME "Cortex-M" // Frequency of the timestamp. Must match SEGGER_SYSVIEW_Conf.h #define SYSVIEW_TIMESTAMP_FREQ (SystemCoreClock) @@ -110,8 +110,9 @@ extern unsigned int SystemCoreClock; */ static void _cbSendSystemDesc(void) { SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME); + SEGGER_SYSVIEW_SendSysDesc("I#11=SVCall"); + SEGGER_SYSVIEW_SendSysDesc("I#14=PendSV"); SEGGER_SYSVIEW_SendSysDesc("I#15=SysTick"); - SEGGER_SYSVIEW_SendSysDesc("I#93=USB_HS"); } /********************************************************************* diff --git a/core/embed/segger/SEGGER/SEGGER.h b/core/embed/segger/SEGGER/SEGGER.h index 397bae8d22..328b636db7 100644 --- a/core/embed/segger/SEGGER/SEGGER.h +++ b/core/embed/segger/SEGGER/SEGGER.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** ---------------------------------------------------------------------- diff --git a/core/embed/segger/SEGGER/SEGGER_RTT.c b/core/embed/segger/SEGGER/SEGGER_RTT.c index 7e6ded94a7..888a3769f4 100644 --- a/core/embed/segger/SEGGER/SEGGER_RTT.c +++ b/core/embed/segger/SEGGER/SEGGER_RTT.c @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ @@ -50,7 +50,7 @@ File : SEGGER_RTT.c Purpose : Implementation of SEGGER real-time transfer (RTT) which allows real-time communication on targets which support debugger memory accesses while the CPU is running. -Revision: $Rev: 20869 $ +Revision: $Rev: 29668 $ Additional information: Type "int" is assumed to be 32-bits in size @@ -168,17 +168,11 @@ Additional information: #endif #ifndef MIN - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX - #define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif -// -// For some environments, NULL may not be defined until certain headers are included -// -#ifndef NULL - #define NULL 0 + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif /********************************************************************* @@ -192,7 +186,7 @@ Additional information: #endif #if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT - #if (defined __GNUC__) + #if ((defined __GNUC__) || (defined __clang__)) #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) #elif (defined __ICCARM__) || (defined __ICCRX__) #define PRAGMA(A) _Pragma(#A) @@ -208,7 +202,7 @@ Additional information: #endif #if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) - #if (defined __GNUC__) + #if ((defined __GNUC__) || (defined __clang__)) #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var #elif (defined __ICCARM__) || (defined __ICCRX__) #define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ @@ -254,7 +248,7 @@ Additional information: ********************************************************************** */ -static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; +static const unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /********************************************************************* * @@ -266,9 +260,26 @@ static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7' // // RTT Control Block and allocate buffers for channel 0 // -SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); -SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)])); -SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)])); +#if SEGGER_RTT_CPU_CACHE_LINE_SIZE + #if ((defined __GNUC__) || (defined __clang__)) + SEGGER_RTT_CB _SEGGER_RTT __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE))); + static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE))); + static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE))); + #elif (defined __ICCARM__) + #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE + SEGGER_RTT_CB _SEGGER_RTT; + #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE + static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)]; + #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE + static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)]; + #else + #error "Don't know how to place _SEGGER_RTT, _acUpBuffer, _acDownBuffer cache-line aligned" + #endif +#else + SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); + SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); + SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); +#endif static unsigned char _ActiveTerminal; @@ -285,25 +296,29 @@ static unsigned char _ActiveTerminal; * * Function description * Initializes the control block an buffers. -* May only be called via INIT() to avoid overriding settings. * +* Notes +* (1) May only be called via INIT() to avoid overriding settings. +* The only exception is SEGGER_RTT_Init(), to make an intentional override possible. */ -#define INIT() { \ - volatile SEGGER_RTT_CB* pRTTCBInit; \ - pRTTCBInit = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \ - do { \ - if (pRTTCBInit->acID[0] == '\0') { \ - _DoInit(); \ - } \ - } while (0); \ - } + #define INIT() \ + do { \ + volatile SEGGER_RTT_CB* pRTTCBInit; \ + pRTTCBInit = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \ + if (pRTTCBInit->acID[0] != 'S') { \ + _DoInit(); \ + } \ + } while (0) static void _DoInit(void) { volatile SEGGER_RTT_CB* p; // Volatile to make sure that compiler cannot change the order of accesses to the control block + static const char _aInitStr[] = "\0\0\0\0\0\0TTR REGGES"; // Init complete ID string to make sure that things also work if RTT is linked to a no-init memory area + unsigned i; // // Initialize control block // - p = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access control block uncached so that nothing in the cache ever becomes dirty and all changes are visible in HW directly + p = (volatile SEGGER_RTT_CB*)((uintptr_t)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); // Access control block uncached so that nothing in the cache ever becomes dirty and all changes are visible in HW directly + memset((SEGGER_RTT_CB*)p, 0, sizeof(_SEGGER_RTT)); // Make sure that the RTT CB is always zero initialized. p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; // @@ -326,15 +341,14 @@ static void _DoInit(void) { p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; // // Finish initialization of the control block. - // Copy Id string in three steps to make sure "SEGGER RTT" is not found - // in initializer memory (usually flash) by J-Link + // Copy Id string backwards to make sure that "SEGGER RTT" is not found in initializer memory (usually flash), + // as this would cause J-Link to "find" the control block at a wrong address. // - STRCPY((char*)&p->acID[7], "RTT"); - RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order - STRCPY((char*)&p->acID[0], "SEGGER"); - RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order - p->acID[6] = ' '; - RTT__DMB(); // Force order of memory accessed inside core for cores that allow to change the order + RTT__DMB(); // Force order of memory accesses for cores that may perform out-of-order memory accesses + for (i = 0; i < sizeof(_aInitStr) - 1; ++i) { + p->acID[i] = _aInitStr[sizeof(_aInitStr) - 2 - i]; // Skip terminating \0 at the end of the array + } + RTT__DMB(); // Force order of memory accesses for cores that may perform out-of-order memory accesses } /********************************************************************* @@ -565,7 +579,7 @@ unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsign volatile char* pSrc; INIT(); - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 pBuffer = (unsigned char*)pData; RdOff = pRing->RdOff; WrOff = pRing->WrOff; @@ -657,7 +671,7 @@ unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned Buffe volatile char* pSrc; // INIT(); - 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 + pRing = (SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_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 pBuffer = (unsigned char*)pData; RdOff = pRing->RdOff; WrOff = pRing->WrOff; @@ -824,7 +838,7 @@ void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuff // Get "to-host" ring buffer and copy some elements into local variables. // pData = (const char *)pBuffer; - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 // // Check if we will overwrite data and need to adjust the RdOff. // @@ -935,14 +949,13 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough // pData = (const char *)pBuffer; - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 RdOff = pRing->RdOff; WrOff = pRing->WrOff; + pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; if (RdOff <= WrOff) { // Case 1), 2) or 3) Avail = pRing->SizeOfBuffer - WrOff - 1u; // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0) if (Avail >= NumBytes) { // Case 1)? -CopyStraight: - pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; memcpy((void*)pDst, pData, NumBytes); RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses pRing->WrOff = WrOff + NumBytes; @@ -951,7 +964,6 @@ CopyStraight: Avail += RdOff; // Space incl. wrap-around if (Avail >= NumBytes) { // Case 2? => If not, we have case 3) (does not fit) Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer - pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF; memcpy((void*)pDst, pData, Rem); // Copy 1st chunk NumBytes -= Rem; // @@ -971,7 +983,10 @@ CopyStraight: } else { // Potential case 4) Avail = RdOff - WrOff - 1u; if (Avail >= NumBytes) { // Case 4)? => If not, we have case 5) (does not fit) - goto CopyStraight; + memcpy((void*)pDst, pData, NumBytes); + RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses + pRing->WrOff = WrOff + NumBytes; + return 1; } } return 0; // No space in buffer @@ -1016,7 +1031,7 @@ unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void* pBuf // It is save to cast that to a "to-host" buffer. Up and Down buffer differ in volatility of offsets that might be modified by J-Link. // pData = (const char *)pBuffer; - pRing = (SEGGER_RTT_BUFFER_UP*)((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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 // // How we output depends upon the mode... // @@ -1090,7 +1105,7 @@ unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsig // Get "to-host" ring buffer. // pData = (const char *)pBuffer; - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 // // How we output depends upon the mode... // @@ -1254,7 +1269,7 @@ unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { // // Get "to-host" ring buffer. // - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 // // Get write position and handle wrap-around if necessary // @@ -1309,7 +1324,7 @@ unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { // // Get "to-host" ring buffer. // - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 // // Get write position and handle wrap-around if necessary // @@ -1368,7 +1383,7 @@ unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { // // Get "to-host" ring buffer. // - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 // // Get write position and handle wrap-around if necessary // @@ -1475,7 +1490,7 @@ int SEGGER_RTT_HasKey(void) { int r; INIT(); - 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 + pRing = (SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_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 RdOff = pRing->RdOff; if (RdOff != pRing->WrOff) { r = 1; @@ -1501,7 +1516,7 @@ unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { SEGGER_RTT_BUFFER_DOWN* pRing; unsigned v; - 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 + pRing = (SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_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 v = pRing->WrOff; return v - pRing->RdOff; } @@ -1522,7 +1537,7 @@ unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { SEGGER_RTT_BUFFER_UP* pRing; unsigned v; - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 v = pRing->RdOff; return pRing->WrOff - v; } @@ -1541,6 +1556,7 @@ unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 - O.K. Buffer Index @@ -1552,7 +1568,7 @@ int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned Buffer INIT(); SEGGER_RTT_LOCK(); - 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 + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 BufferIndex = 0; do { if (pRTTCB->aDown[BufferIndex].pBuffer == NULL) { @@ -1589,6 +1605,7 @@ int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned Buffer * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 - O.K. Buffer Index @@ -1600,7 +1617,7 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi INIT(); SEGGER_RTT_LOCK(); - 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 + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 BufferIndex = 0; do { if (pRTTCB->aUp[BufferIndex].pBuffer == NULL) { @@ -1638,6 +1655,7 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 - O.K. @@ -1651,19 +1669,21 @@ int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSi int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; INIT(); - 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 - if (BufferIndex < (unsigned)pRTTCB->MaxNumUpBuffers) { + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - pRTTCB->aUp[BufferIndex].sName = sName; - pRTTCB->aUp[BufferIndex].pBuffer = (char*)pBuffer; - pRTTCB->aUp[BufferIndex].SizeOfBuffer = BufferSize; - pRTTCB->aUp[BufferIndex].RdOff = 0u; - pRTTCB->aUp[BufferIndex].WrOff = 0u; + pUp = &pRTTCB->aUp[BufferIndex]; + if (BufferIndex) { + pUp->sName = sName; + pUp->pBuffer = (char*)pBuffer; + pUp->SizeOfBuffer = BufferSize; + pUp->RdOff = 0u; + pUp->WrOff = 0u; } - pRTTCB->aUp[BufferIndex].Flags = Flags; + pUp->Flags = Flags; SEGGER_RTT_UNLOCK(); r = 0; } else { @@ -1687,6 +1707,7 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu * pBuffer Pointer to a buffer to be used. * BufferSize Size of the buffer. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 O.K. @@ -1700,19 +1721,21 @@ int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBu int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; INIT(); - 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 - if (BufferIndex < (unsigned)pRTTCB->MaxNumDownBuffers) { + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - pRTTCB->aDown[BufferIndex].sName = sName; - pRTTCB->aDown[BufferIndex].pBuffer = (char*)pBuffer; - pRTTCB->aDown[BufferIndex].SizeOfBuffer = BufferSize; - pRTTCB->aDown[BufferIndex].RdOff = 0u; - pRTTCB->aDown[BufferIndex].WrOff = 0u; + pDown = &pRTTCB->aDown[BufferIndex]; + if (BufferIndex) { + pDown->sName = sName; + pDown->pBuffer = (char*)pBuffer; + pDown->SizeOfBuffer = BufferSize; + pDown->RdOff = 0u; + pDown->WrOff = 0u; } - pRTTCB->aDown[BufferIndex].Flags = Flags; + pDown->Flags = Flags; RTT__DMB(); // Force data write to be complete before writing the , in case CPU is allowed to change the order of memory accesses SEGGER_RTT_UNLOCK(); r = 0; @@ -1741,12 +1764,14 @@ int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* p int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { int r; volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; INIT(); - 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 - if (BufferIndex < (unsigned)pRTTCB->MaxNumUpBuffers) { + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { SEGGER_RTT_LOCK(); - pRTTCB->aUp[BufferIndex].sName = sName; + pUp = &pRTTCB->aUp[BufferIndex]; + pUp->sName = sName; SEGGER_RTT_UNLOCK(); r = 0; } else { @@ -1774,12 +1799,14 @@ int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { int r; volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; INIT(); - 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 - if (BufferIndex < (unsigned)pRTTCB->MaxNumDownBuffers) { + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { SEGGER_RTT_LOCK(); - pRTTCB->aDown[BufferIndex].sName = sName; + pDown = &pRTTCB->aDown[BufferIndex]; + pDown->sName = sName; SEGGER_RTT_UNLOCK(); r = 0; } else { @@ -1799,6 +1826,7 @@ int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { * Parameters * BufferIndex Index of the buffer. * Flags Flags to set for the buffer. +* Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 O.K. @@ -1807,12 +1835,14 @@ int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_UP* pUp; INIT(); - 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 - if (BufferIndex < (unsigned)pRTTCB->MaxNumUpBuffers) { + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 + if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) { SEGGER_RTT_LOCK(); - pRTTCB->aUp[BufferIndex].Flags = Flags; + pUp = &pRTTCB->aUp[BufferIndex]; + pUp->Flags = Flags; SEGGER_RTT_UNLOCK(); r = 0; } else { @@ -1832,6 +1862,7 @@ int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { * Parameters * BufferIndex Index of the buffer to renamed. * Flags Flags to set for the buffer. +* Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. * * Return value * >= 0 O.K. @@ -1840,12 +1871,14 @@ int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { int r; volatile SEGGER_RTT_CB* pRTTCB; + volatile SEGGER_RTT_BUFFER_DOWN* pDown; INIT(); - 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 - if (BufferIndex < (unsigned)pRTTCB->MaxNumDownBuffers) { + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 + if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) { SEGGER_RTT_LOCK(); - pRTTCB->aDown[BufferIndex].Flags = Flags; + pDown = &pRTTCB->aDown[BufferIndex]; + pDown->Flags = Flags; SEGGER_RTT_UNLOCK(); r = 0; } else { @@ -1895,7 +1928,7 @@ int SEGGER_RTT_SetTerminal (unsigned char TerminalId) { ac[0] = 0xFFu; if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels ac[1] = _aTerminalId[TerminalId]; - pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[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 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 if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { _ActiveTerminal = TerminalId; @@ -1947,7 +1980,7 @@ int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) { // // Get "to-host" ring buffer. // - pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[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 // // Need to be able to change terminal, write data, change back. // Compute the fixed and variable sizes. @@ -2024,7 +2057,7 @@ int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) { unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex) { SEGGER_RTT_BUFFER_UP* pRing; - 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 + pRing = (SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_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 return _GetAvailWriteSpace(pRing); } @@ -2051,7 +2084,7 @@ unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex) { // Avoid warnings regarding volatile access order. It's not a problem // in this case, but dampen compiler enthusiasm. // - 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 + pRTTCB = (volatile SEGGER_RTT_CB*)((uintptr_t)&_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 RdOff = pRTTCB->aUp[BufferIndex].RdOff; WrOff = pRTTCB->aUp[BufferIndex].WrOff; if (RdOff <= WrOff) { diff --git a/core/embed/segger/SEGGER/SEGGER_RTT.h b/core/embed/segger/SEGGER/SEGGER_RTT.h index f4115f6491..a8264cd36e 100644 --- a/core/embed/segger/SEGGER/SEGGER_RTT.h +++ b/core/embed/segger/SEGGER/SEGGER_RTT.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ @@ -50,7 +50,7 @@ File : SEGGER_RTT.h Purpose : Implementation of SEGGER real-time transfer which allows real-time communication on targets which support debugger memory accesses while the CPU is running. -Revision: $Rev: 20869 $ +Revision: $Rev: 25842 $ ---------------------------------------------------------------------- */ @@ -65,65 +65,22 @@ Revision: $Rev: 20869 $ * ********************************************************************** */ + #ifndef RTT_USE_ASM - #if (defined __SES_ARM) // SEGGER Embedded Studio + // + // Some cores support out-of-order memory accesses (reordering of memory accesses in the core) + // For such cores, we need to define a memory barrier to guarantee the order of certain accesses to the RTT ring buffers. + // Needed for: + // Cortex-M7 (ARMv7-M) + // Cortex-M23 (ARM-v8M) + // Cortex-M33 (ARM-v8M) + // Cortex-A/R (ARM-v7A/R) + // + // We do not explicitly check for "Embedded Studio" as the compiler in use determines what we support. + // You can use an external toolchain like IAR inside ES. So there is no point in checking for "Embedded Studio" + // + #if (defined __CROSSWORKS_ARM) // Rowley Crossworks #define _CC_HAS_RTT_ASM_SUPPORT 1 - #elif (defined __CROSSWORKS_ARM) // Rowley Crossworks - #define _CC_HAS_RTT_ASM_SUPPORT 1 - #elif (defined __ARMCC_VERSION) // ARM compiler - #if (__ARMCC_VERSION >= 6000000) // ARM compiler V6.0 and later is clang based - #define _CC_HAS_RTT_ASM_SUPPORT 1 - #else - #define _CC_HAS_RTT_ASM_SUPPORT 0 - #endif - #elif (defined __GNUC__) // GCC - #define _CC_HAS_RTT_ASM_SUPPORT 1 - #elif (defined __clang__) // Clang compiler - #define _CC_HAS_RTT_ASM_SUPPORT 1 - #elif ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler - #define _CC_HAS_RTT_ASM_SUPPORT 1 - #else - #define _CC_HAS_RTT_ASM_SUPPORT 0 - #endif - #if ((defined __IASMARM__) || (defined __ICCARM__)) // IAR assembler/compiler - // - // IAR assembler / compiler - // - #if (__VER__ < 6300000) - #define VOLATILE - #else - #define VOLATILE volatile - #endif - #if (defined __ARM7M__) // Needed for old versions that do not know the define yet - #if (__CORE__ == __ARM7M__) // Cortex-M3 - #define _CORE_HAS_RTT_ASM_SUPPORT 1 - #endif - #endif - #if (defined __ARM7EM__) // Needed for old versions that do not know the define yet - #if (__CORE__ == __ARM7EM__) // Cortex-M4/M7 - #define _CORE_HAS_RTT_ASM_SUPPORT 1 - #define _CORE_NEEDS_DMB 1 - #define RTT__DMB() asm VOLATILE ("DMB"); - #endif - #endif - #if (defined __ARM8M_BASELINE__) // Needed for old versions that do not know the define yet - #if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23 - #define _CORE_HAS_RTT_ASM_SUPPORT 0 - #define _CORE_NEEDS_DMB 1 - #define RTT__DMB() asm VOLATILE ("DMB"); - #endif - #endif - #if (defined __ARM8M_MAINLINE__) // Needed for old versions that do not know the define yet - #if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33 - #define _CORE_HAS_RTT_ASM_SUPPORT 1 - #define _CORE_NEEDS_DMB 1 - #define RTT__DMB() asm VOLATILE ("DMB"); - #endif - #endif - #else - // - // GCC / Clang - // #if (defined __ARM_ARCH_7M__) // Cortex-M3 #define _CORE_HAS_RTT_ASM_SUPPORT 1 #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 @@ -138,9 +95,143 @@ Revision: $Rev: 20869 $ #define _CORE_HAS_RTT_ASM_SUPPORT 1 #define _CORE_NEEDS_DMB 1 #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined(__ARM_ARCH_8_1M_MAIN__)) // Cortex-M85 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); #else #define _CORE_HAS_RTT_ASM_SUPPORT 0 #endif + #elif (defined __ARMCC_VERSION) + // + // ARM compiler + // ARM compiler V6.0 and later is clang based. + // Our ASM part is compatible to clang. + // + #if (__ARMCC_VERSION >= 6000000) + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #else + #define _CC_HAS_RTT_ASM_SUPPORT 0 + #endif + #if (defined __ARM_ARCH_6M__) // Cortex-M0 / M1 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 // No ASM support for this architecture + #elif (defined __ARM_ARCH_7M__) // Cortex-M3 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__)) // Cortex-A/R 32-bit ARMv7-A/R + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #else + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #endif + #elif ((defined __GNUC__) || (defined __clang__)) + // + // GCC / Clang + // + #define _CC_HAS_RTT_ASM_SUPPORT 1 + // ARM 7/9: __ARM_ARCH_5__ / __ARM_ARCH_5E__ / __ARM_ARCH_5T__ / __ARM_ARCH_5T__ / __ARM_ARCH_5TE__ + #if (defined __ARM_ARCH_7M__) // Cortex-M3 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 // Only Cortex-M7 needs a DMB but we cannot distinguish M4 and M7 here... + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__)) // Cortex-A/R 32-bit ARMv7-A/R + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() __asm volatile ("dmb\n" : : :); + #else + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #endif + #elif ((defined __IASMARM__) || (defined __ICCARM__)) + // + // IAR assembler/compiler + // + #define _CC_HAS_RTT_ASM_SUPPORT 1 + #if (__VER__ < 6300000) + #define VOLATILE + #else + #define VOLATILE volatile + #endif + #if (defined __ARM7M__) // Needed for old versions that do not know the define yet + #if (__CORE__ == __ARM7M__) // Cortex-M3 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #endif + #endif + #if (defined __ARM7EM__) + #if (__CORE__ == __ARM7EM__) // Cortex-M4/M7 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM8M_BASELINE__) + #if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM8M_MAINLINE__) + #if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33 + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM8EM_MAINLINE__) + #if (__CORE__ == __ARM8EM_MAINLINE__) // Cortex-??? + #define _CORE_HAS_RTT_ASM_SUPPORT 1 + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM7A__) + #if (__CORE__ == __ARM7A__) // Cortex-A 32-bit ARMv7-A + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif + #if (defined __ARM7R__) + #if (__CORE__ == __ARM7R__) // Cortex-R 32-bit ARMv7-R + #define _CORE_NEEDS_DMB 1 + #define RTT__DMB() asm VOLATILE ("DMB"); + #endif + #endif +// TBD: __ARM8A__ => Cortex-A 64-bit ARMv8-A +// TBD: __ARM8R__ => Cortex-R 64-bit ARMv8-R + #else + // + // Other compilers + // + #define _CC_HAS_RTT_ASM_SUPPORT 0 + #define _CORE_HAS_RTT_ASM_SUPPORT 0 #endif // // If IDE and core support the ASM version, enable ASM version by default @@ -155,11 +246,6 @@ Revision: $Rev: 20869 $ #endif #endif -// -// We need to know if a DMB is needed to make sure that on Cortex-M7 etc. -// the order of accesses to the ring buffers is guaranteed -// Needed for: Cortex-M7, Cortex-M23, Cortex-M33 -// #ifndef _CORE_NEEDS_DMB #define _CORE_NEEDS_DMB 0 #endif @@ -192,6 +278,7 @@ Revision: $Rev: 20869 $ #ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file #include #include +#include /********************************************************************* * @@ -232,7 +319,7 @@ typedef struct { unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. unsigned WrOff; // Position of next item to be written by either target. volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. - unsigned Flags; // Contains configuration flags + unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. } SEGGER_RTT_BUFFER_UP; // @@ -245,7 +332,7 @@ typedef struct { unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. unsigned RdOff; // Position of next item to be read by target (down-buffer). - unsigned Flags; // Contains configuration flags + unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode. } SEGGER_RTT_BUFFER_DOWN; // @@ -311,7 +398,7 @@ unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex); // // Function macro for performance optimization // -#define SEGGER_RTT_HASDATA(n) (((SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) +#define SEGGER_RTT_HASDATA(n) (((SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) #if RTT_USE_ASM #define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock @@ -328,7 +415,7 @@ unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void* pDa unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -#define SEGGER_RTT_HASDATA_UP(n) (((SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly +#define SEGGER_RTT_HASDATA_UP(n) (((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly /********************************************************************* * @@ -354,6 +441,13 @@ int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pPa #endif // ifndef(SEGGER_RTT_ASM) +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL ((void*)0) +#endif + /********************************************************************* * * Defines diff --git a/core/embed/segger/SEGGER/SEGGER_RTT_printf.c b/core/embed/segger/SEGGER/SEGGER_RTT_printf.c index 2b9ff123d5..6ed598bd3a 100644 --- a/core/embed/segger/SEGGER/SEGGER_RTT_printf.c +++ b/core/embed/segger/SEGGER/SEGGER_RTT_printf.c @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ @@ -423,6 +423,9 @@ int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pPa case 's': { const char * s = va_arg(*pParamList, const char *); + if (s == NULL) { + s = "(NULL)"; // Print (NULL) instead of crashing or breaking, as it is more informative to the user. + } do { c = *s; s++; diff --git a/core/embed/segger/SEGGER/SEGGER_SYSVIEW.c b/core/embed/segger/SEGGER/SEGGER_SYSVIEW.c index 575d835b3b..2606f93e22 100644 --- a/core/embed/segger/SEGGER/SEGGER_SYSVIEW.c +++ b/core/embed/segger/SEGGER/SEGGER_SYSVIEW.c @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,14 +42,14 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : SEGGER_SYSVIEW.c Purpose : System visualization API implementation. -Revision: $Rev: 21281 $ +Revision: $Rev: 29105 $ Additional information: Packet format: @@ -190,6 +190,17 @@ Additional information: #define MAKE_DELTA_32BIT(Delta) #endif +#if SEGGER_SYSVIEW_SUPPORT_LONG_ID + #define _MAX_ID_BYTES 5u +#else + #define _MAX_ID_BYTES 2u +#endif + +#if SEGGER_SYSVIEW_SUPPORT_LONG_DATA + #define _MAX_DATA_BYTES 5u +#else + #define _MAX_DATA_BYTES 2u +#endif /********************************************************************* * @@ -345,53 +356,6 @@ static const U8 _abSync[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, #endif #endif -#ifdef SEGGER_SYSVIEW_SECTION - #if (defined __GNUC__) - __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE]; - #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) - __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms - #endif - #elif (defined __ICCARM__) || (defined __ICCRX__) - #pragma location=SEGGER_SYSVIEW_SECTION - static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE]; - #pragma location=SEGGER_SYSVIEW_SECTION - static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms - #elif (defined __CC_ARM) - __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE]; - #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) - __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms - #endif - #else - static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE]; - #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) - static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms - #endif - #endif -#else - #if SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE - #if (defined __GNUC__) - static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE] __attribute__ ((aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE))); - #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) - static char _DownBuffer[8] __attribute__ ((aligned (SEGGER_SYSVIEW_CPU_CACHE_LINE_SIZE))); // Small, fixed-size buffer, for back-channel comms - #endif - #elif (defined(__ICCARM__)) - #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE - static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE]; - #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) - #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE - static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms - #endif - #else - #error "Don't know how to place _SEGGER_RTT, _acUpBuffer, _acDownBuffer cache-line aligned" - #endif - #else - static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE]; - #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) - static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms - #endif - #endif -#endif - static SEGGER_SYSVIEW_GLOBALS _SYSVIEW_Globals; static SEGGER_SYSVIEW_MODULE* _pFirstModule; @@ -408,7 +372,7 @@ static U8 _NumModules; U8* pSysviewPointer; \ U32 SysViewData; \ pSysviewPointer = pDest; \ - SysViewData = Value; \ + SysViewData = (U32)Value; \ while(SysViewData > 0x7F) { \ *pSysviewPointer++ = (U8)(SysViewData | 0x80); \ SysViewData >>= 7; \ @@ -417,8 +381,6 @@ static U8 _NumModules; pDest = pSysviewPointer; \ }; - - #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1) static U8 _aPacket[SEGGER_SYSVIEW_MAX_PACKET_SIZE]; @@ -459,17 +421,62 @@ static U8 _aPacket[SEGGER_SYSVIEW_MAX_PACKET_SIZE]; * Make sure NumBytes + 1 bytes are free for the payload. */ static U8* _EncodeData(U8* pPayload, const char* pSrc, unsigned int NumBytes) { - unsigned int n; + unsigned int n; + const U8* p; // n = 0; - *pPayload++ = NumBytes; + p = (const U8*)pSrc; + // + // Write Len + // + if (NumBytes < 255) { + *pPayload++ = (U8)NumBytes; + } else { + *pPayload++ = 255; + *pPayload++ = ((NumBytes >> 8) & 255); + *pPayload++ = (NumBytes & 255); + } while (n < NumBytes) { - *pPayload++ = *pSrc++; + *pPayload++ = *p++; n++; } return pPayload; } +/********************************************************************* +* +* _EncodeFloat() +* +* Function description +* Encode a float value in variable-length format. +* +* Parameters +* pPayload - Pointer to where value will be encoded. +* Value - Value to be encoded. +* +* Return value +* Pointer to the byte following the value, i.e. the first free +* byte in the payload and the next position to store payload +* content. +*/ +static U8* _EncodeFloat(U8* pPayload, float Value) { + float Val; + U8* pSysviewPointer; + U32* SysViewData; + + Val = Value; + pSysviewPointer = pPayload; + SysViewData = (U32*)&Val; + while((*SysViewData) > 0x7F) { + *pSysviewPointer++ = (U8)((*SysViewData) | 0x80); + (*SysViewData) >>= 7; + } + *pSysviewPointer++ = (U8)(*SysViewData); + pPayload = pSysviewPointer; + + return pPayload; +} + /********************************************************************* * * _EncodeStr() @@ -493,36 +500,42 @@ static U8* _EncodeData(U8* pPayload, const char* pSrc, unsigned int NumBytes) { * No more than 1 + Limit bytes will be encoded to the payload. */ static U8 *_EncodeStr(U8 *pPayload, const char *pText, unsigned int Limit) { - unsigned int n; - unsigned int Len; - // - // Compute string len - // - Len = 0; - while(*(pText + Len) != 0) { - Len++; - } - if (Len > Limit) { - Len = Limit; - } - // - // Write Len - // - if (Len < 255) { - *pPayload++ = Len; + U8* pLen; + const char* sStart; + + if (pText == NULL) { + *pPayload++ = (U8)0; } else { - *pPayload++ = 255; - *pPayload++ = (Len & 255); - *pPayload++ = ((Len >> 8) & 255); + sStart = pText; // Remember start of string. + // + // Save space to store count byte(s). + // + pLen = pPayload++; +#if (SEGGER_SYSVIEW_MAX_STRING_LEN >= 255) // Length always encodes in 3 bytes + pPayload += 2; +#endif + // + // Limit string to maximum length and copy into payload buffer. + // + if (Limit > SEGGER_SYSVIEW_MAX_STRING_LEN) { + Limit = SEGGER_SYSVIEW_MAX_STRING_LEN; + } + while ((Limit-- > 0) && (*pText != '\0')) { + *pPayload++ = *pText++; + } + // + // Save string length to buffer. + // +#if (SEGGER_SYSVIEW_MAX_STRING_LEN >= 255) // Length always encodes in 3 bytes + Limit = (unsigned int)(pText - sStart); + *pLen++ = (U8)255; + *pLen++ = (U8)((Limit >> 8) & 255); + *pLen++ = (U8)(Limit & 255); +#else // Length always encodes in 1 byte + *pLen = (U8)(pText - sStart); +#endif } // - // copy string - // - n = 0; - while (n < Len) { - *pPayload++ = *pText++; - n++; - } return pPayload; } @@ -545,7 +558,7 @@ static U8 *_EncodeStr(U8 *pPayload, const char *pText, unsigned int Limit) { * computed and filled in by the sending function. */ static U8* _PreparePacket(U8* pPacket) { - return pPacket + 4; + return pPacket + _MAX_ID_BYTES + _MAX_DATA_BYTES; } /********************************************************************* @@ -563,7 +576,7 @@ static U8* _PreparePacket(U8* pPacket) { #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) static void _HandleIncomingPacket(void) { U8 Cmd; - int Status; + unsigned int Status; // Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1); if (Status > 0) { @@ -642,13 +655,13 @@ static int _TrySendOverflowPacket(void) { // Compute time stamp delta and append it to packet. // TimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP(); - Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp; + Delta = (I32)(TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp); MAKE_DELTA_32BIT(Delta); ENCODE_U32(pPayload, Delta); // // Try to store packet in RTT buffer and update time stamp when this was successful // - Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, aPacket, pPayload - aPacket); + Status = (int)SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, aPacket, (unsigned int)(pPayload - aPacket)); SEGGER_SYSVIEW_ON_EVENT_RECORDED(pPayload - aPacket); if (Status) { _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp; @@ -709,7 +722,6 @@ static void _SendSyncInfo(void) { for (n = 0; n < _NumModules; n++) { SEGGER_SYSVIEW_SendModule(n); } - SEGGER_SYSVIEW_SendModuleDescription(); } } #endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1) @@ -738,7 +750,7 @@ static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId) U32 TimeStamp; U32 Delta; #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1) - int Status; + unsigned int Status; #endif #if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0) @@ -783,21 +795,85 @@ Send: // otherwise prepend packet length and eventId. // if (EventId < 24) { - *--pStartPacket = EventId; + *--pStartPacket = (U8)EventId; } else { - NumBytes = pEndPacket - pStartPacket; - if (NumBytes > 127) { - *--pStartPacket = (NumBytes >> 7); - *--pStartPacket = NumBytes | 0x80; - } else { - *--pStartPacket = NumBytes; - } - if (EventId > 127) { - *--pStartPacket = (EventId >> 7); - *--pStartPacket = EventId | 0x80; - } else { + // + // Get data length and prepend it. + // + NumBytes = (unsigned int)(pEndPacket - pStartPacket); +#if SEGGER_SYSVIEW_SUPPORT_LONG_DATA + if (NumBytes < 127) { *--pStartPacket = EventId; + } else { + // + // Backwards U32 encode EventId. + // + if (NumBytes < (1ul << 14)) { // Encodes in 2 bytes + *--pStartPacket = (U8)(NumBytes >> 7); + *--pStartPacket = (U8)(NumBytes | 0x80); + } else if (NumBytes < (1ul << 21)) { // Encodes in 3 bytes + *--pStartPacket = (U8)(NumBytes >> 14); + *--pStartPacket = (U8)((NumBytes >> 7) | 0x80); + *--pStartPacket = (U8)(NumBytes | 0x80); + } else if (NumBytes < (1ul << 28)) { // Encodes in 4 bytes + *--pStartPacket = (U8)(NumBytes >> 21); + *--pStartPacket = (U8)((NumBytes >> 14) | 0x80); + *--pStartPacket = (U8)((NumBytes >> 7) | 0x80); + *--pStartPacket = (U8)(NumBytes | 0x80); + } else { // Encodes in 5 bytes + *--pStartPacket = (U8)(NumBytes >> 28); + *--pStartPacket = (U8)((NumBytes >> 21) | 0x80); + *--pStartPacket = (U8)((NumBytes >> 14) | 0x80); + *--pStartPacket = (U8)((NumBytes >> 7) | 0x80); + *--pStartPacket = (U8)(NumBytes | 0x80); + } } +#else + if (NumBytes > 127) { + *--pStartPacket = (U8)(NumBytes >> 7); + *--pStartPacket = (U8)(NumBytes | 0x80); + } else { + *--pStartPacket = (U8)NumBytes; + } +#endif + // + // Prepend EventId. + // +#if SEGGER_SYSVIEW_SUPPORT_LONG_ID + if (EventId < 127) { + *--pStartPacket = (U8)EventId; + } else { + // + // Backwards U32 encode EventId. + // + if (EventId < (1u << 14)) { // Encodes in 2 bytes + *--pStartPacket = (U8)(EventId >> 7); + *--pStartPacket = (U8)(EventId | 0x80); + } else if (EventId < (1ul << 21)) { // Encodes in 3 bytes + *--pStartPacket = (U8)(EventId >> 14); + *--pStartPacket = (U8)((EventId >> 7) | 0x80); + *--pStartPacket = (U8)(EventId | 0x80); + } else if (EventId < (1ul << 28)) { // Encodes in 4 bytes + *--pStartPacket = (U8)(EventId >> 21); + *--pStartPacket = (U8)((EventId >> 14) | 0x80); + *--pStartPacket = (U8)((EventId >> 7) | 0x80); + *--pStartPacket = (U8)(EventId | 0x80); + } else { // Encodes in 5 bytes + *--pStartPacket = (U8)(EventId >> 28); + *--pStartPacket = (U8)((EventId >> 21) | 0x80); + *--pStartPacket = (U8)((EventId >> 14) | 0x80); + *--pStartPacket = (U8)((EventId >> 7) | 0x80); + *--pStartPacket = (U8)(EventId | 0x80); + } + } +#else + if (EventId > 127) { + *--pStartPacket = (U8)(EventId >> 7); + *--pStartPacket = (U8)(EventId | 0x80); + } else { + *--pStartPacket = (U8)EventId; + } +#endif } // // Compute time stamp delta and append it to packet. @@ -817,7 +893,7 @@ Send: // // Try to store packet in RTT buffer and update time stamp when this was successful // - Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, pStartPacket, pEndPacket - pStartPacket); + Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, pStartPacket, (unsigned int)(pEndPacket - pStartPacket)); SEGGER_SYSVIEW_ON_EVENT_RECORDED(pEndPacket - pStartPacket); if (Status) { _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp; @@ -901,7 +977,7 @@ static int _VPrintHost(const char* s, U32 Options, va_list* pParamList) { if (c == '%') { c = *p; #if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT == 0 - aParas[NumArguments++] = va_arg(*pParamList, int); + aParas[NumArguments++] = (U32)(va_arg(*pParamList, int)); if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) { break; } @@ -910,7 +986,7 @@ static int _VPrintHost(const char* s, U32 Options, va_list* pParamList) { HasNonScalar = 1; break; } else { - aParas[NumArguments++] = va_arg(*pParamList, int); + aParas[NumArguments++] = (U32)(va_arg(*pParamList, int)); if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) { break; } @@ -962,14 +1038,14 @@ static void _StoreChar(SEGGER_SYSVIEW_PRINTF_DESC * p, char c) { Cnt = p->Cnt; if ((Cnt + 1u) <= SEGGER_SYSVIEW_MAX_STRING_LEN) { - *(p->pPayload++) = c; + *(p->pPayload++) = (U8)c; p->Cnt = Cnt + 1u; } // // Write part of string, when the buffer is full // if (p->Cnt == SEGGER_SYSVIEW_MAX_STRING_LEN) { - *(p->pPayloadStart) = p->Cnt; + *(p->pPayloadStart) = (U8)p->Cnt; pPayload = p->pPayload; Options = p->Options; ENCODE_U32(pPayload, Options); @@ -1169,6 +1245,7 @@ static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) unsigned int FormatFlags; unsigned int FieldWidth; U8* pPayloadStart; + const char* s; #if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0 RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32); SEGGER_SYSVIEW_LOCK(); @@ -1273,6 +1350,20 @@ static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, NumDigits, FieldWidth, FormatFlags); break; + case 's': + s = va_arg(*pParamList, const char*); + if (s == NULL) { + s = "(null)"; + } + do { + c = *s; + s++; + if (c == '\0') { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.Cnt < SEGGER_SYSVIEW_MAX_STRING_LEN); + break; case 'p': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, 8u, 8u, 0u); @@ -1293,7 +1384,7 @@ static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) // Write remaining data, if any // if (BufferDesc.Cnt != 0u) { - *(BufferDesc.pPayloadStart) = BufferDesc.Cnt; + *(BufferDesc.pPayloadStart) = (U8)BufferDesc.Cnt; ENCODE_U32(BufferDesc.pPayload, BufferDesc.Options); ENCODE_U32(BufferDesc.pPayload, 0); _SendPacket(BufferDesc.pPayloadStart, BufferDesc.pPayload, SYSVIEW_EVTID_PRINT_FORMATTED); @@ -1320,7 +1411,7 @@ static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) * * Function description * Initializes the SYSVIEW module. -* Must be called before the Systemview Application connects to +* Must be called before the SystemView Application connects to * the system. * * Parameters @@ -1348,7 +1439,7 @@ void SEGGER_SYSVIEW_Init(U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API * #if SEGGER_SYSVIEW_RTT_CHANNEL > 0 SEGGER_RTT_ConfigUpBuffer(SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); #else - _SYSVIEW_Globals.UpChannel = SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); + _SYSVIEW_Globals.UpChannel = (U8)SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); #endif _SYSVIEW_Globals.RAMBaseAddress = SEGGER_SYSVIEW_ID_BASE; _SYSVIEW_Globals.LastTxTimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP(); @@ -1363,7 +1454,7 @@ void SEGGER_SYSVIEW_Init(U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API * SEGGER_RTT_ConfigUpBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); SEGGER_RTT_ConfigDownBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); #else - _SYSVIEW_Globals.UpChannel = SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); + _SYSVIEW_Globals.UpChannel = (U8)SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); _SYSVIEW_Globals.DownChannel = _SYSVIEW_Globals.UpChannel; SEGGER_RTT_ConfigDownBuffer (_SYSVIEW_Globals.DownChannel, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP); #endif @@ -1818,7 +1909,7 @@ void SEGGER_SYSVIEW_Start(void) { * Stop recording SystemView events. * * This function is triggered by the SystemView Application on disconnect. -* For single-shot or post-mortem mode recording, it can be called +* For single-shot or postmortem mode recording, it can be called * by the application. * * Additional information @@ -1900,11 +1991,61 @@ void SEGGER_SYSVIEW_SendTaskInfo(const SEGGER_SYSVIEW_TASKINFO *pInfo) { ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID)); ENCODE_U32(pPayload, pInfo->StackBase); ENCODE_U32(pPayload, pInfo->StackSize); - ENCODE_U32(pPayload, 0); // Stack End, future use + ENCODE_U32(pPayload, pInfo->StackUsage); _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_STACK_INFO); RECORD_END(); } +/********************************************************************* +* +* SEGGER_SYSVIEW_SendStackInfo() +* +* Function description +* Send a Stack Info Packet, containing TaskId for identification, +* stack base, stack size and stack usage. +* +* +* Parameters +* pInfo - Pointer to stack information to send. +*/ +void SEGGER_SYSVIEW_SendStackInfo(const SEGGER_SYSVIEW_STACKINFO *pInfo) { + U8* pPayload; + U8* pPayloadStart; + RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32); + // + pPayload = pPayloadStart; + ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID)); + ENCODE_U32(pPayload, pInfo->StackBase); + ENCODE_U32(pPayload, pInfo->StackSize); + ENCODE_U32(pPayload, pInfo->StackUsage); + + RECORD_END(); +} + +/********************************************************************* +* +* SEGGER_SYSVIEW_SampleData() +* +* Function description +* Send a Data Sample Packet, containing the data Id and the value. +* +* +* Parameters +* pInfo - Pointer to data sample struct to send. +*/ +void SEGGER_SYSVIEW_SampleData(const SEGGER_SYSVIEW_DATA_SAMPLE *pInfo) { + U8* pPayload; + U8* pPayloadStart; + RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32); + // + pPayload = pPayloadStart; + ENCODE_U32(pPayload, pInfo->ID); + pPayload = _EncodeFloat(pPayload, *(pInfo->pValue.pFloat)); + _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_DATA_SAMPLE); + + RECORD_END(); +} + /********************************************************************* * * SEGGER_SYSVIEW_SendTaskList() @@ -1924,7 +2065,7 @@ void SEGGER_SYSVIEW_SendTaskList(void) { * * Function description * Send the system description string to the host. -* The system description is used by the Systemview Application +* The system description is used by the SystemView Application * to identify the current application and handle events accordingly. * * The system description is usually called by the system description @@ -2389,6 +2530,236 @@ void SEGGER_SYSVIEW_NameResource(U32 ResourceId, const char* sName) { RECORD_END(); } +/********************************************************************* +* +* SEGGER_SYSVIEW_RegisterData() +* +* Function description +* Register data to sample the values via SystemView. +* +* Register functions are usually set in the system description +* callback, to ensure it is only sent when the SystemView Application +* is connected. +* +* Parameters +* pInfo - Struct containing all possible properties that can be sent via this registration event. +*/ +void SEGGER_SYSVIEW_RegisterData(SEGGER_SYSVIEW_DATA_REGISTER* pInfo) { + U8* pPayload; + U8* pPayloadStart; + RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 8 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN); + // + pPayload = pPayloadStart; + ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_REGISTER_DATA); + ENCODE_U32(pPayload, pInfo->ID); + pPayload = _EncodeStr(pPayload, pInfo->sName, SEGGER_SYSVIEW_MAX_STRING_LEN); + + if (pInfo->sUnit != 0) { + ENCODE_U32(pPayload, pInfo->DataType); + ENCODE_U32(pPayload, pInfo->Offset); + ENCODE_U32(pPayload, pInfo->RangeMin); + ENCODE_U32(pPayload, pInfo->RangeMax); + pPayload = _EncodeFloat(pPayload, pInfo->ScalingFactor); + pPayload = _EncodeStr(pPayload, pInfo->sUnit, SEGGER_SYSVIEW_MAX_STRING_LEN); + } else if (pInfo->ScalingFactor != 0) { + ENCODE_U32(pPayload, pInfo->DataType); + ENCODE_U32(pPayload, pInfo->Offset); + ENCODE_U32(pPayload, pInfo->RangeMin); + ENCODE_U32(pPayload, pInfo->RangeMax); + pPayload = _EncodeFloat(pPayload, pInfo->ScalingFactor); + } else if (pInfo->RangeMax != 0) { + ENCODE_U32(pPayload, pInfo->DataType); + ENCODE_U32(pPayload, pInfo->Offset); + ENCODE_U32(pPayload, pInfo->RangeMin); + ENCODE_U32(pPayload, pInfo->RangeMax); + } else if (pInfo->RangeMin != 0) { + ENCODE_U32(pPayload, pInfo->DataType); + ENCODE_U32(pPayload, pInfo->Offset); + ENCODE_U32(pPayload, pInfo->RangeMin); + } else if (pInfo->Offset != 0) { + ENCODE_U32(pPayload, pInfo->DataType); + ENCODE_U32(pPayload, pInfo->Offset); + } else if (pInfo->DataType != 0) { + ENCODE_U32(pPayload, pInfo->DataType); + } + + _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX); + RECORD_END(); +} + +/********************************************************************* +* +* SEGGER_SYSVIEW_HeapDefine() +* +* Function description +* Define heap. +* +* Parameters +* pHeap - Pointer to heap control structure. +* pBase - Pointer to managed heap memory. +* HeapSize - Size of managed heap memory in bytes. +* MetadataSize - Size of metadata associated with each heap allocation. +* +* Additional information +* SystemView can track allocations across multiple heaps. +* +* HeapSize must be a multiple of the natural alignment unit of the +* target. This size is subject to compression, controlled by the +* specific setting of SEGGER_SYSVIEW_ID_SHIFT. +* +* MetadataSize defines the size of the per-allocation metadata. +* For many heap implementations, the metadata size is a multiple of +* the word size of the machine and typically contains the size +* of the allocated block (used upon deallocation), optional +* pointers to the preceding and/or following blocks, and optionally +* a tag identifying the owner of the block. Note that MetadataSize +* is not compressed within the SystemView packet and is not +* required to be a multiple of 1<> SEGGER_SYSVIEW_ID_SHIFT); + ENCODE_U32(pPayload, MetadataSize); + _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX); + RECORD_END(); +} + +/********************************************************************* +* +* SEGGER_SYSVIEW_HeapAlloc() +* +* Function description +* Record a system-heap allocation event. +* +* Parameters +* pHeap - Pointer to heap where allocation was made. +* pUserData - Pointer to allocated user data. +* UserDataLen - Size of block allocated to hold user data, excluding any metadata. +* +* Additional information +* The user data must be correctly aligned for the architecture, which +* typically requires that the alignment is at least the alignment +* of a double or a long long. pUserData is, therefore, compressed by +* shrinking as IDs are compressed, controlled by the specific setting +* of SEGGER_SYSVIEW_ID_SHIFT. +* +* In the same way, UserDataLen must reflect the size of the allocated +* block, not the allocation size requested by the application. This +* size is also subject to compression, controlled by the specific setting +* of SEGGER_SYSVIEW_ID_SHIFT. +* +* As an example, assume the allocator is running on a Cortex-M device +* with SEGGER_SYSVIEW_ID_SHIFT set to 2 (the word alignment of the device). +* If a user requests an allocation of 5 bytes, a hypothetical heap +* allocator could allocate a block with size 32 bytes for this. The value +* of UserDataLen sent to SystemView for recording should be 32, not 5, +* and the 32 is compressed by shifting by two bits, the configured value +* of SEGGER_SYSVIEW_ID_SHIFT, and describes the number of bytes that are +* consumed from managed memory from which SystemView can calculate +* accurate heap metrics. +*/ +void SEGGER_SYSVIEW_HeapAlloc(void *pHeap, void* pUserData, unsigned int UserDataLen) { + U8* pPayload; + U8* pPayloadStart; + RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 3 * SEGGER_SYSVIEW_QUANTA_U32); + // + pPayload = pPayloadStart; + ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_ALLOC); + ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap)); + ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData)); + ENCODE_U32(pPayload, UserDataLen >> SEGGER_SYSVIEW_ID_SHIFT); + _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX); + RECORD_END(); +} + +/********************************************************************* +* +* SEGGER_SYSVIEW_HeapAllocEx() +* +* Function description +* Record a per-heap allocation event. +* +* Parameters +* pHeap - Pointer to heap where allocation was made. +* pUserData - Pointer to allocated user data. +* UserDataLen - Size of block allocated to hold user data, excluding any metadata. +* Tag - Block tag, typically used to identify the owner of the block. +* +* Additional information +* The user data must be correctly aligned for the architecture, which +* typically requires that the alignment is at least the alignment +* of a double or a long long. pUserData is, therefore, compressed by +* shrinking as IDs are compressed, controlled by the specific setting +* of SEGGER_SYSVIEW_ID_SHIFT. +* +* In the same way, UserDataLen must reflect the size of the allocated +* block, not the allocation size requested by the application. This +* size is also subject to compression, controlled by the specific setting +* of SEGGER_SYSVIEW_ID_SHIFT. +* +* As an example, assume the allocator is running on a Cortex-M device +* with SEGGER_SYSVIEW_ID_SHIFT set to 2 (the word alignment of the device). +* If a user requests an allocation of 5 bytes, a hypothetical heap +* allocator could allocate a block with size 32 bytes for this. The value +* of UserDataLen sent to SystemView for recording should be 32, not 5, +* and the 32 is compressed by shifting by two bits, the configured value +* of SEGGER_SYSVIEW_ID_SHIFT, and describes the number of bytes that are +* consumed from managed memory from which SystemView can calculate +* accurate heap metrics. +* +* See also +* SEGGER_SYSVIEW_HeapAlloc(). +*/ +void SEGGER_SYSVIEW_HeapAllocEx(void *pHeap, void* pUserData, unsigned int UserDataLen, unsigned int Tag) { + U8* pPayload; + U8* pPayloadStart; + RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32); + // + pPayload = pPayloadStart; + ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_ALLOC_EX); + ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap)); + ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData)); + ENCODE_U32(pPayload, UserDataLen >> SEGGER_SYSVIEW_ID_SHIFT); + ENCODE_U32(pPayload, Tag); + _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX); + RECORD_END(); +} + +/********************************************************************* +* +* SEGGER_SYSVIEW_HeapFree() +* +* Function description +* Record a heap deallocation event. +* +* Parameters +* pHeap - Pointer to heap where allocation was made. +* pUserData - Pointer to allocated user data. +* +* Additional information +* SystemViews track allocations and knows the size of the +* allocated data. +*/ +void SEGGER_SYSVIEW_HeapFree(void* pHeap, void* pUserData) { + U8* pPayload; + U8* pPayloadStart; + RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32); + // + pPayload = pPayloadStart; + ENCODE_U32(pPayload, SYSVIEW_EVTID_EX_HEAP_FREE); + ENCODE_U32(pPayload, SHRINK_ID((U32)pHeap)); + ENCODE_U32(pPayload, SHRINK_ID((U32)pUserData)); + _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_EX); + RECORD_END(); +} + /********************************************************************* * * SEGGER_SYSVIEW_SendPacket() @@ -2588,9 +2959,6 @@ void SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE* pModule) { _NumModules++; } SEGGER_SYSVIEW_SendModule(0); - if (pModule->pfSendModuleDesc) { - pModule->pfSendModuleDesc(); - } SEGGER_SYSVIEW_UNLOCK(); } @@ -2674,6 +3042,9 @@ void SEGGER_SYSVIEW_SendModule(U8 ModuleId) { _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC); RECORD_END(); } + if (pModule && pModule->pfSendModuleDesc) { + pModule->pfSendModuleDesc(); + } } } @@ -2754,6 +3125,39 @@ void SEGGER_SYSVIEW_PrintfHostEx(const char* s, U32 Options, ...) { #endif } +/********************************************************************* +* +* SEGGER_SYSVIEW_VPrintfHostEx() +* +* Function description +* Print a string which is formatted on the host by the SystemView Application +* with Additional information. +* +* Parameters +* s - String to be formatted. +* Options - Options for the string. i.e. Log level. +* pParamList - Pointer to the list of arguments for the format string +* +* Additional information +* All format arguments are treated as 32-bit scalar values. +*/ +void SEGGER_SYSVIEW_VPrintfHostEx(const char* s, U32 Options, va_list *pParamList) { +#if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT + int r; + va_list ParamListCopy; + va_copy(ParamListCopy, *pParamList); + + r = _VPrintHost(s, Options, pParamList); + + if (r == -1) { + _VPrintTarget(s, Options, &ParamListCopy); + } + va_end(ParamListCopy); +#else + _VPrintHost(s, Options, pParamList); +#endif +} + /********************************************************************* * * SEGGER_SYSVIEW_PrintfHost() @@ -2788,12 +3192,43 @@ void SEGGER_SYSVIEW_PrintfHost(const char* s, ...) { #endif } +/********************************************************************* +* +* SEGGER_SYSVIEW_VPrintfHost() +* +* Function description +* Print a string which is formatted on the host by the SystemView Application. +* +* Parameters +* s - String to be formatted. +* pParamList - Pointer to the list of arguments for the format string +* +* Additional information +* All format arguments are treated as 32-bit scalar values. +*/ +void SEGGER_SYSVIEW_VPrintfHost(const char* s, va_list *pParamList) { +#if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT + int r; + va_list ParamListCopy; + va_copy(ParamListCopy, *pParamList); + + r = _VPrintHost(s, SEGGER_SYSVIEW_LOG, pParamList); + + if (r == -1) { + _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamListCopy); + } + va_end(ParamListCopy); +#else + _VPrintHost(s, SEGGER_SYSVIEW_LOG, pParamList); +#endif +} + /********************************************************************* * * SEGGER_SYSVIEW_WarnfHost() * * Function description -* Print a warnin string which is formatted on the host by +* Print a warning string which is formatted on the host by * the SystemView Application. * * Parameters @@ -2823,6 +3258,38 @@ void SEGGER_SYSVIEW_WarnfHost(const char* s, ...) { #endif } +/********************************************************************* +* +* SEGGER_SYSVIEW_VWarnfHost() +* +* Function description +* Print a warning string which is formatted on the host by +* the SystemView Application. +* +* Parameters +* s - String to be formatted. +* pParamList - Pointer to the list of arguments for the format string +* +* Additional information +* All format arguments are treated as 32-bit scalar values. +*/ +void SEGGER_SYSVIEW_VWarnfHost(const char* s, va_list *pParamList) { +#if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT + int r; + va_list ParamListCopy; + va_copy(ParamListCopy, *pParamList); + + r = _VPrintHost(s, SEGGER_SYSVIEW_WARNING, pParamList); + + if (r == -1) { + _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamListCopy); + } + va_end(ParamListCopy); +#else + _VPrintHost(s, SEGGER_SYSVIEW_WARNING, pParamList); +#endif +} + /********************************************************************* * * SEGGER_SYSVIEW_ErrorfHost() @@ -2858,6 +3325,38 @@ void SEGGER_SYSVIEW_ErrorfHost(const char* s, ...) { #endif } +/********************************************************************* +* +* SEGGER_SYSVIEW_VErrorfHost() +* +* Function description +* Print a warning string which is formatted on the host by +* the SystemView Application. +* +* Parameters +* s - String to be formatted. +* pParamList - Pointer to the list of arguments for the format string +* +* Additional information +* All format arguments are treated as 32-bit scalar values. +*/ +void SEGGER_SYSVIEW_VErrorfHost(const char* s, va_list *pParamList) { +#if SEGGER_SYSVIEW_PRINTF_IMPLICIT_FORMAT + int r; + va_list ParamListCopy; + va_copy(ParamListCopy, *pParamList); + + r = _VPrintHost(s, SEGGER_SYSVIEW_ERROR, pParamList); + + if (r == -1) { + _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamListCopy); + } + va_end(ParamListCopy); +#else + _VPrintHost(s, SEGGER_SYSVIEW_ERROR, pParamList); +#endif +} + /********************************************************************* * * SEGGER_SYSVIEW_PrintfTargetEx() @@ -2878,6 +3377,23 @@ void SEGGER_SYSVIEW_PrintfTargetEx(const char* s, U32 Options, ...) { va_end(ParamList); } +/********************************************************************* +* +* SEGGER_SYSVIEW_VPrintfTargetEx() +* +* Function description +* Print a string which is formatted on the target before sent to +* the host with Additional information. +* +* Parameters +* s - String to be formatted. +* Options - Options for the string. i.e. Log level. +* pParamList - Pointer to the list of arguments for the format string +*/ +void SEGGER_SYSVIEW_VPrintfTargetEx(const char* s, U32 Options, va_list *pParamList) { + _VPrintTarget(s, Options, pParamList); +} + /********************************************************************* * * SEGGER_SYSVIEW_PrintfTarget() @@ -2897,6 +3413,22 @@ void SEGGER_SYSVIEW_PrintfTarget(const char* s, ...) { va_end(ParamList); } +/********************************************************************* +* +* SEGGER_SYSVIEW_VPrintfTarget() +* +* Function description +* Print a string which is formatted on the target before sent to +* the host. +* +* Parameters +* s - String to be formatted. +* pParamList - Pointer to the list of arguments for the format string +*/ +void SEGGER_SYSVIEW_VPrintfTarget(const char* s, va_list* pParamList) { + _VPrintTarget(s, SEGGER_SYSVIEW_LOG, pParamList); +} + /********************************************************************* * * SEGGER_SYSVIEW_WarnfTarget() @@ -2916,6 +3448,22 @@ void SEGGER_SYSVIEW_WarnfTarget(const char* s, ...) { va_end(ParamList); } +/********************************************************************* +* +* SEGGER_SYSVIEW_VWarnfTarget() +* +* Function description +* Print a warning string which is formatted on the target before +* sent to the host. +* +* Parameters +* s - String to be formatted. +* pParamList - Pointer to the list of arguments for the format string +*/ +void SEGGER_SYSVIEW_VWarnfTarget(const char* s, va_list* pParamList) { + _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, pParamList); +} + /********************************************************************* * * SEGGER_SYSVIEW_ErrorfTarget() @@ -2934,6 +3482,22 @@ void SEGGER_SYSVIEW_ErrorfTarget(const char* s, ...) { _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamList); va_end(ParamList); } + +/********************************************************************* +* +* SEGGER_SYSVIEW_VErrorfTarget() +* +* Function description +* Print an error string which is formatted on the target before +* sent to the host. +* +* Parameters +* s - String to be formatted. +* pParamList - Pointer to the list of arguments for the format string +*/ +void SEGGER_SYSVIEW_VErrorfTarget(const char* s, va_list* pParamList) { + _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, pParamList); +} #endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF /********************************************************************* diff --git a/core/embed/segger/SEGGER/SEGGER_SYSVIEW.h b/core/embed/segger/SEGGER/SEGGER_SYSVIEW.h index cf618057ed..03cb01136f 100644 --- a/core/embed/segger/SEGGER/SEGGER_SYSVIEW.h +++ b/core/embed/segger/SEGGER/SEGGER_SYSVIEW.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,13 +42,13 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : SEGGER_SYSVIEW.h Purpose : System visualization API. -Revision: $Rev: 21292 $ +Revision: $Rev: 28768 $ */ #ifndef SEGGER_SYSVIEW_H @@ -77,7 +77,7 @@ extern "C" { */ #define SEGGER_SYSVIEW_MAJOR 3 -#define SEGGER_SYSVIEW_MINOR 10 +#define SEGGER_SYSVIEW_MINOR 32 #define SEGGER_SYSVIEW_REV 0 #define SEGGER_SYSVIEW_VERSION ((SEGGER_SYSVIEW_MAJOR * 10000) + (SEGGER_SYSVIEW_MINOR * 100) + SEGGER_SYSVIEW_REV) @@ -116,7 +116,7 @@ extern "C" { #define SYSVIEW_EVTID_TIMER_EXIT 20 #define SYSVIEW_EVTID_STACK_INFO 21 #define SYSVIEW_EVTID_MODULEDESC 22 - +#define SYSVIEW_EVTID_DATA_SAMPLE 23 #define SYSVIEW_EVTID_INIT 24 #define SYSVIEW_EVTID_NAME_RESOURCE 25 #define SYSVIEW_EVTID_PRINT_FORMATTED 26 @@ -128,8 +128,13 @@ extern "C" { // // SystemView extended events. Sent with ID 31. // -#define SYSVIEW_EVTID_EX_MARK 0 -#define SYSVIEW_EVTID_EX_NAME_MARKER 1 +#define SYSVIEW_EVTID_EX_MARK 0 +#define SYSVIEW_EVTID_EX_NAME_MARKER 1 +#define SYSVIEW_EVTID_EX_HEAP_DEFINE 2 +#define SYSVIEW_EVTID_EX_HEAP_ALLOC 3 +#define SYSVIEW_EVTID_EX_HEAP_ALLOC_EX 4 +#define SYSVIEW_EVTID_EX_HEAP_FREE 5 +#define SYSVIEW_EVTID_EX_REGISTER_DATA 6 // // Event masks to disable/enable events // @@ -156,7 +161,7 @@ extern "C" { #define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT) #define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO) #define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC) - +#define SYSVIEW_EVTMASK_DATA_SAMPLE (1 << SYSVIEW_EVTID_DATA_SAMPLE) #define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT) #define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE) #define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED) @@ -191,8 +196,42 @@ typedef struct { U32 Prio; U32 StackBase; U32 StackSize; + U32 StackUsage; } SEGGER_SYSVIEW_TASKINFO; +typedef struct { + U32 TaskID; + U32 StackBase; + U32 StackSize; + U32 StackUsage; +} SEGGER_SYSVIEW_STACKINFO; + +typedef struct { + U32 ID; + union { + U32* pU32; + I32* pI32; + float* pFloat; + } pValue; +} SEGGER_SYSVIEW_DATA_SAMPLE; + +typedef enum { + SEGGER_SYSVIEW_TYPE_U32 = 0, + SEGGER_SYSVIEW_TYPE_I32 = 1, + SEGGER_SYSVIEW_TYPE_FLOAT = 2 +} SEGGER_SYSVIEW_DATA_TYPE; + +typedef struct { + U32 ID; + SEGGER_SYSVIEW_DATA_TYPE DataType; + I32 Offset; + I32 RangeMin; + I32 RangeMax; + float ScalingFactor; + const char* sName; + const char* sUnit; +} SEGGER_SYSVIEW_DATA_REGISTER; + typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE; struct SEGGER_SYSVIEW_MODULE_STRUCT { @@ -236,8 +275,8 @@ EXTERN unsigned int SEGGER_SYSVIEW_InterruptId; */ typedef struct { - U64 (*pfGetTime) (void); - void (*pfSendTaskList) (void); + U64 (*pfGetTime) (void); + void (*pfSendTaskList) (void); } SEGGER_SYSVIEW_OS_API; /********************************************************************* @@ -251,10 +290,13 @@ void SEGGER_SYSVIEW_Stop (void); void SEGGER_SYSVIEW_GetSysDesc (void); void SEGGER_SYSVIEW_SendTaskList (void); void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo); +void SEGGER_SYSVIEW_SendStackInfo (const SEGGER_SYSVIEW_STACKINFO* pInfo); void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc); int SEGGER_SYSVIEW_IsStarted (void); int SEGGER_SYSVIEW_GetChannelID (void); +void SEGGER_SYSVIEW_SampleData (const SEGGER_SYSVIEW_DATA_SAMPLE *pInfo); + /********************************************************************* * * Event recording functions @@ -292,7 +334,13 @@ void SEGGER_SYSVIEW_MarkStop (unsigned int MarkerId); void SEGGER_SYSVIEW_Mark (unsigned int MarkerId); void SEGGER_SYSVIEW_NameMarker (unsigned int MarkerId, const char* sName); +void SEGGER_SYSVIEW_HeapDefine (void* pHeap, void* pBase, unsigned int HeapSize, unsigned int MetadataSize); +void SEGGER_SYSVIEW_HeapAlloc (void* pHeap, void* pUserData, unsigned int UserDataLen); +void SEGGER_SYSVIEW_HeapAllocEx (void* pHeap, void* pUserData, unsigned int UserDataLen, unsigned int Tag); +void SEGGER_SYSVIEW_HeapFree (void* pHeap, void* pUserData); + void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName); +void SEGGER_SYSVIEW_RegisterData ( SEGGER_SYSVIEW_DATA_REGISTER* pInfo); int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId); @@ -323,13 +371,21 @@ void SEGGER_SYSVIEW_SendNumModules (void); */ #ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...); +void SEGGER_SYSVIEW_VPrintfHostEx (const char* s, U32 Options, va_list* pParamList); void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...); +void SEGGER_SYSVIEW_VPrintfTargetEx (const char* s, U32 Options, va_list* pParamList); void SEGGER_SYSVIEW_PrintfHost (const char* s, ...); +void SEGGER_SYSVIEW_VPrintfHost (const char* s, va_list* pParamList); void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...); +void SEGGER_SYSVIEW_VPrintfTarget (const char* s, va_list* pParamList); void SEGGER_SYSVIEW_WarnfHost (const char* s, ...); +void SEGGER_SYSVIEW_VWarnfHost (const char* s, va_list* pParamList); void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...); +void SEGGER_SYSVIEW_VWarnfTarget (const char* s, va_list* pParamList); void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...); +void SEGGER_SYSVIEW_VErrorfHost (const char* s, va_list* pParamList); void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...); +void SEGGER_SYSVIEW_VErrorfTarget (const char* s, va_list* pParamList); #endif void SEGGER_SYSVIEW_Print (const char* s); diff --git a/core/embed/segger/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h b/core/embed/segger/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h index aefde96a58..22fba14c6f 100644 --- a/core/embed/segger/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h +++ b/core/embed/segger/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,14 +42,14 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : SEGGER_SYSVIEW_ConfDefaults.h Purpose : Defines defaults for configurable defines used in SEGGER SystemView. -Revision: $Rev: 21319 $ +Revision: $Rev: 26230 $ */ #ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H @@ -69,10 +69,6 @@ Revision: $Rev: 21319 $ extern "C" { #endif -#include -extern uint32_t svc_get_dwt_cyccnt(); - - /********************************************************************* * * Defines, fixed @@ -216,7 +212,7 @@ extern uint32_t svc_get_dwt_cyccnt(); */ #ifndef SEGGER_SYSVIEW_GET_TIMESTAMP #if defined (SEGGER_SYSVIEW_CORE) && (SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3) - #define SEGGER_SYSVIEW_GET_TIMESTAMP() svc_get_dwt_cyccnt() // Retrieve a system timestamp. Cortex-M cycle counter. + #define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter. #else #define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function #endif @@ -269,7 +265,7 @@ extern uint32_t svc_get_dwt_cyccnt(); * 1024 */ #ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE - #define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 4096 + #define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 #endif /********************************************************************* @@ -364,7 +360,33 @@ extern uint32_t svc_get_dwt_cyccnt(); * 128 */ #ifndef SEGGER_SYSVIEW_MAX_STRING_LEN - #define SEGGER_SYSVIEW_MAX_STRING_LEN 1024 + #define SEGGER_SYSVIEW_MAX_STRING_LEN 128 +#endif + +/********************************************************************* +* +* Define: SEGGER_SYSVIEW_SUPPORT_LONG_ID +* +* Description +* It set, support enconding Evend Ids longer than 14 bit. +* Default +* 1 +*/ +#ifndef SEGGER_SYSVIEW_SUPPORT_LONG_ID + #define SEGGER_SYSVIEW_SUPPORT_LONG_ID 1 +#endif + +/********************************************************************* +* +* Define: SEGGER_SYSVIEW_SUPPORT_LONG_DATA +* +* Description +* It set, support enconding event data longer than 14 bit. +* Default +* 0 +*/ +#ifndef SEGGER_SYSVIEW_SUPPORT_LONG_DATA + #define SEGGER_SYSVIEW_SUPPORT_LONG_DATA 0 #endif /********************************************************************* diff --git a/core/embed/segger/SEGGER/SEGGER_SYSVIEW_Int.h b/core/embed/segger/SEGGER/SEGGER_SYSVIEW_Int.h index a07938155b..c2d7209156 100644 --- a/core/embed/segger/SEGGER/SEGGER_SYSVIEW_Int.h +++ b/core/embed/segger/SEGGER/SEGGER_SYSVIEW_Int.h @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- diff --git a/core/embed/segger/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c b/core/embed/segger/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c index 88870e39c9..3e38f306e9 100644 --- a/core/embed/segger/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c +++ b/core/embed/segger/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c @@ -3,7 +3,7 @@ * The Embedded Experts * ********************************************************************** * * -* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* (c) 1995 - 2024 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * @@ -42,7 +42,7 @@ * * ********************************************************************** * * -* SystemView version: 3.20 * +* SystemView version: 3.58 * * * ********************************************************************** ---------------------------END-OF-HEADER------------------------------ @@ -50,7 +50,7 @@ File : SEGGER_RTT_Syscalls_GCC.c Purpose : Low-level functions for using printf() via RTT in GCC. To use RTT for printf output, include this file in your application. -Revision: $Rev: 20755 $ +Revision: $Rev: 24316 $ ---------------------------------------------------------------------- */ #if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) && !(defined __ARMCC_VERSION) && !(defined __CC_ARM) diff --git a/core/embed/trezorhal/stm32f4/systask.c b/core/embed/trezorhal/stm32f4/systask.c index d128fee454..bad1ee6034 100644 --- a/core/embed/trezorhal/stm32f4/systask.c +++ b/core/embed/trezorhal/stm32f4/systask.c @@ -479,11 +479,6 @@ __attribute__((no_stack_protector, used)) static uint32_t svc_handler( mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); switch (svc_number) { -#ifdef SYSTEM_VIEW - case SVC_GET_DWT_CYCCNT: - cyccnt_cycles = *DWT_CYCCNT_ADDR; - break; -#endif case SVC_SYSTASK_YIELD: // Yield to the waiting task systask_yield();