From 741626dc8f9037397abe35a2c5d4d64504129776 Mon Sep 17 00:00:00 2001 From: Diego Ismirlian Date: Sun, 29 Sep 2019 12:37:06 -0300 Subject: Add SEGGER RTT and SystemView bindings for ChibiOS --- .../segger_bindings/RTT/SEGGER_RTT_streams.c | 116 +++++++++ .../segger_bindings/RTT/SEGGER_RTT_streams.h | 107 ++++++++ .../SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.c | 73 ++++++ .../SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h | 281 +++++++++++++++++++++ .../segger_bindings/SYSTEMVIEW/SYSVIEW_ChibiOS.txt | 8 + .../example_configurations/SEGGER_RTT_Conf.h | 123 +++++++++ .../example_configurations/SEGGER_SYSVIEW_Conf.h | 174 +++++++++++++ os/various/segger_bindings/segger_rtt.mk | 14 + os/various/segger_bindings/segger_systemview.mk | 13 + 9 files changed, 909 insertions(+) create mode 100644 os/various/segger_bindings/RTT/SEGGER_RTT_streams.c create mode 100644 os/various/segger_bindings/RTT/SEGGER_RTT_streams.h create mode 100644 os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.c create mode 100644 os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h create mode 100644 os/various/segger_bindings/SYSTEMVIEW/SYSVIEW_ChibiOS.txt create mode 100644 os/various/segger_bindings/example_configurations/SEGGER_RTT_Conf.h create mode 100644 os/various/segger_bindings/example_configurations/SEGGER_SYSVIEW_Conf.h create mode 100644 os/various/segger_bindings/segger_rtt.mk create mode 100644 os/various/segger_bindings/segger_systemview.mk (limited to 'os') diff --git a/os/various/segger_bindings/RTT/SEGGER_RTT_streams.c b/os/various/segger_bindings/RTT/SEGGER_RTT_streams.c new file mode 100644 index 0000000..253a2f1 --- /dev/null +++ b/os/various/segger_bindings/RTT/SEGGER_RTT_streams.c @@ -0,0 +1,116 @@ +/* + ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio + Copyright (C) 2019 Diego Ismirlian, (dismirlian(at)google's mail) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "hal.h" +#include "SEGGER_RTT_streams.h" + +RTTDriver RTTD0; +static bool rtt_global_init; + +static size_t _write(RTTDriver *rttdp, const uint8_t *bp, size_t n) { + return SEGGER_RTT_Write(rttdp->up_buffer_index, bp, n); +} + +static size_t _read(RTTDriver *rttdp, uint8_t *bp, size_t n) { + (void)rttdp, (void)bp, (void)n; + /* TODO: implement */ + return 0; +} + +static msg_t _put(RTTDriver *rttdp, uint8_t b) { + if (SEGGER_RTT_PutChar(rttdp->up_buffer_index, b) == 1) { + return MSG_OK; + } + return MSG_TIMEOUT; +} + +static msg_t _get(RTTDriver *rttdp) { + (void)rttdp; + /* TODO: implement */ + return MSG_TIMEOUT; +} + +static const struct RTTDriverVMT vmt = { + (size_t)0, + (size_t (*)(void *, const uint8_t *, size_t))_write, + (size_t (*)(void *, uint8_t *, size_t))_read, + (msg_t (*)(void *, uint8_t))_put, + (msg_t (*)(void *))_get, +}; + +static inline void _object_init(RTTDriver *rttdp) { + rttdp->state = RTT_STATE_READY; + rttdp->vmt = &vmt; +} + +void rttInit(void) { + osalDbgAssert(rtt_global_init == false, "double init"); + SEGGER_RTT_LOCK(); + SEGGER_RTT_Init(); + RTTD0.up_buffer_index = 0; + RTTD0.down_buffer_index = 0; + _object_init(&RTTD0); + rtt_global_init = true; + RTTD0.state = RTT_STATE_READY; + SEGGER_RTT_UNLOCK(); +} + +void rttObjectInit(RTTDriver *rttdp, const RTTConfig *cfg) { + osalDbgCheck(rttdp); + osalDbgAssert(rtt_global_init, "uninitialized"); + osalDbgAssert(rttdp != &RTTD0, "RTTD0 is automatically initialized on rttInit"); + + int idx; + + SEGGER_RTT_LOCK(); + if (cfg->down.size) { + idx = SEGGER_RTT_AllocDownBuffer(cfg->name, cfg->down.buff, cfg->down.size, cfg->down.flags); + osalDbgAssert(idx > 0, "can't alloc down buffer"); + rttdp->down_buffer_index = (unsigned)idx; + } else { + rttdp->down_buffer_index = 0; + } + + if (cfg->up.size) { + idx = SEGGER_RTT_AllocUpBuffer(cfg->name, cfg->up.buff, cfg->up.size, cfg->up.flags); + osalDbgAssert(idx > 0, "can't alloc up buffer"); + rttdp->up_buffer_index = (unsigned)idx; + } else { + rttdp->up_buffer_index = 0; + } + + _object_init(rttdp); + SEGGER_RTT_UNLOCK(); +} + +void rttSetUpFlags(RTTDriver *rttdp, rtt_mode_flags_t flags) { + int ret = SEGGER_RTT_SetFlagsUpBuffer(rttdp->up_buffer_index, (unsigned)flags); + osalDbgAssert(ret >= 0, "error"); +} + +void rttSetDownFlags(RTTDriver *rttdp, rtt_mode_flags_t flags) { + int ret = SEGGER_RTT_SetFlagsDownBuffer(rttdp->down_buffer_index, (unsigned)flags); + osalDbgAssert(ret >= 0, "error"); +} + +void rttStart(RTTDriver *rttdp) { + osalDbgCheck(rttdp); + osalDbgAssert(rtt_global_init, "uninitialized"); + osalDbgAssert((rttdp->state == RTT_STATE_ACTIVE) + || (rttdp->state == RTT_STATE_READY), "wrong state"); + rttdp->state = RTT_STATE_READY; +} diff --git a/os/various/segger_bindings/RTT/SEGGER_RTT_streams.h b/os/various/segger_bindings/RTT/SEGGER_RTT_streams.h new file mode 100644 index 0000000..3ee679c --- /dev/null +++ b/os/various/segger_bindings/RTT/SEGGER_RTT_streams.h @@ -0,0 +1,107 @@ +/* + ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio + Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef SEGGER_RTT_streams_H_ +#define SEGGER_RTT_streams_H_ + +#include "hal.h" +#include "SEGGER_RTT.h" + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +typedef enum { + RTT_STATE_UNINIT = 0, + RTT_STATE_STOP = 1, + RTT_STATE_ACTIVE = 2, + RTT_STATE_READY = 3 +} rtt_state_t; + +typedef enum { + RTT_MODE_FLAGS_NO_BLOCK_SKIP = SEGGER_RTT_MODE_NO_BLOCK_SKIP, + RTT_MODE_FLAGS_NO_BLOCK_TRIM = SEGGER_RTT_MODE_NO_BLOCK_TRIM, + RTT_MODE_FLAGS_BLOCK_IF_FIFO_FULL = SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL, +} rtt_mode_flags_t; + +#define _rtt_driver_methods \ + _base_sequential_stream_methods + +struct RTTDriverVMT { + _rtt_driver_methods +}; + +typedef struct RTTDriver RTTDriver; +typedef struct RTTConfig RTTConfig; +typedef struct RTTBufferConfig RTTBufferConfig; + +struct RTTDriver { + /* inherited from abstract asyncrhonous channel driver */ + const struct RTTDriverVMT *vmt; + _base_sequential_stream_data + + rtt_state_t state; + unsigned int up_buffer_index; + unsigned int down_buffer_index; +}; + +struct RTTBufferConfig { + void *buff; + unsigned int size; + rtt_mode_flags_t flags; +}; + +struct RTTConfig { + const char *name; + RTTBufferConfig up; + RTTBufferConfig down; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ +#define rttGetState(rttdp) ((rttdp)->state) +#define rttGetUpBufferIndex(rttdp) ((rttdp)->up_buffer_index) +#define rttGetDownBufferIndex(rttdp) ((rttdp)->down_buffer_index) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ +extern RTTDriver RTTD0; + +#ifdef __cplusplus +extern "C" { +#endif + /* RTT device driver */ + void rttInit(void); + void rttObjectInit(RTTDriver *rttdp, const RTTConfig *cfg); + void rttStart(RTTDriver *rttdp); + void rttSetUpFlags(RTTDriver *rttdp, rtt_mode_flags_t flags); + void rttSetDownFlags(RTTDriver *rttdp, rtt_mode_flags_t flags); +#ifdef __cplusplus +} +#endif + +#endif /* SEGGER_RTT_streams_H_ */ diff --git a/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.c b/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.c new file mode 100644 index 0000000..08d2e73 --- /dev/null +++ b/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.c @@ -0,0 +1,73 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + Copyright (C) 2019 Diego Ismirlian, (dismirlian (at) google's mail) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ch.h" +#include "SEGGER_SYSVIEW.h" +#include "hal.h" + +#include + +static systime_t start; +static const char *isr_desc; + +static void _cbSendTaskList(void) { + thread_t *tp; + tp = chRegFirstThread(); + do { + SYSVIEW_ChibiOS_SendTaskInfo(tp); + tp = chRegNextThread(tp); + } while (tp != NULL); +} + +static U64 _cbGetTime(void) { + return TIME_I2US(chVTTimeElapsedSinceX(start)); +} + +static void _cbSendSystemDesc(void) { + SEGGER_SYSVIEW_SendSysDesc("O=ChibiOS"); + SEGGER_SYSVIEW_SendSysDesc(isr_desc); +} + +static const SEGGER_SYSVIEW_OS_API os_api = { + _cbGetTime, + _cbSendTaskList, +}; + +void SYSVIEW_ChibiOS_Start(U32 SysFreq, U32 CPUFreq, const char *isr_description) { + start = chVTGetSystemTimeX(); + isr_desc = isr_description; + SEGGER_SYSVIEW_Init(SysFreq, CPUFreq, &os_api, _cbSendSystemDesc); + SEGGER_SYSVIEW_Start(); +} + +void SYSVIEW_ChibiOS_SendTaskInfo(const void *_tp) { + const thread_t *const tp = (const thread_t *)_tp; + SEGGER_SYSVIEW_TASKINFO TaskInfo; + + //Fill all elements with 0 to allow extending the structure + //in future version without breaking the code + memset(&TaskInfo, 0, sizeof(TaskInfo)); + TaskInfo.TaskID = (U32)tp; + TaskInfo.sName = tp->name; + TaskInfo.Prio = (U32)tp->prio; +#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) + TaskInfo.StackBase = (U32)tp->wabase; + TaskInfo.StackSize = (U32)tp->ctx.sp - (U32)tp->wabase; +#else + TaskInfo.StackBase = 0U; + TaskInfo.StackSize = (U32)tp->wabase; +#endif + SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo); +} diff --git a/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h b/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h new file mode 100644 index 0000000..c3e0384 --- /dev/null +++ b/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.h @@ -0,0 +1,281 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + Copyright (C) 2019 Diego Ismirlian, (dismirlian(at)google's mail) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * To use: + * + * 1) + * #include this file at the bottom of chconf.h. You may need to + * redefine some of the hooks in chconf.h, for example + * + * CH_CFG_THREAD_INIT_HOOK => _CH_CFG_THREAD_INIT_HOOK. + * + * If you don't use those hooks in your original code, you may just delete + * them from chconf.h + * + * + * 2) + * Copy the SEGGER_RTT_Conf.h and SEGGER_SYSVIEW_Conf.h files from the + * segger_bindings/example_configurations/ directory to the project's + * cfg directory. + * + * You can tune the config files to suit your needs; see the SEGGER RTT and + * SystemView documentation for details. + * + * + * 3) + * Add the following call to main(): + * SYSVIEW_ChibiOS_Start(STM32_SYSCLK, STM32_SYSCLK, "I#15=SysTick"); + * + * The first parameter, SysFreq, is the time base for all the timestamps. It + * must match SEGGER_SYSVIEW_GET_TIMESTAMP in SEGGER_SYSVIEW_Conf.h. By + * default, SEGGER_SYSVIEW_GET_TIMESTAMP is configured to use the DWT cycle + * counter, so this parameter should match the CPU frequency (eg. + * STM32_SYSCLK). + * + * The second parameter, CPUFreq, appears to be just for information. + * + * The third parameter can be used to name the interrupts in the system. + * For example, on the Cortex-M*, when using the classic periodic tick for + * ChibiOS (CH_CFG_ST_TIMEDELTA == 0), this parameter should include + * "I#15=OSTick" (interrupt #15 is the SysTick). When using the tick-less + * mode, this parameter could be tuned to show the ISR name of the timer + * module used as the OS timer. + * + * Also, you can include all other interrupts in this configuration string + * (eg. "I#15=OSTick,I#54=USART2"). + * + * See the SystemView documentation for more details. + * + * + * 4) + * Copy the file SYSVIEW_ChibiOS.txt (in the segger_bindings directory) to + * the following directory: + * + * Path\to\SystemView\Description\ + * + * This will allow SystemView to map the ChibiOS's task state values to names. + * + */ + +#ifndef SYSVIEW_CHIBIOS_H +#define SYSVIEW_CHIBIOS_H + +#include "SEGGER_SYSVIEW.h" +void SYSVIEW_ChibiOS_SendTaskInfo(const void *_tp); +void SYSVIEW_ChibiOS_Start(U32 SysFreq, U32 CPUFreq, const char *isr_description); + +/********************************************************************/ +/* Checks */ +/********************************************************************/ +#if !(CH_CFG_USE_REGISTRY == TRUE) +#error "SYSVIEW integration requires CH_CFG_USE_REGISTRY" +#endif + +#if defined(CH_CFG_THREAD_INIT_HOOK) +#error "SYSVIEW integration: rename CH_CFG_THREAD_INIT_HOOK to _CH_CFG_THREAD_INIT_HOOK" +#endif + +#if defined(CH_CFG_THREAD_READY_HOOK) +#error "SYSVIEW integration: rename CH_CFG_THREAD_READY_HOOK to _CH_CFG_THREAD_READY_HOOK" +#endif + +#if defined(CH_CFG_CONTEXT_SWITCH_HOOK) +#error "SYSVIEW integration: rename CH_CFG_CONTEXT_SWITCH_HOOK to _CH_CFG_CONTEXT_SWITCH_HOOK" +#endif + +#if defined(CH_CFG_THREAD_EXIT_HOOK) +#error "SYSVIEW integration: rename CH_CFG_THREAD_EXIT_HOOK to _CH_CFG_THREAD_EXIT_HOOK" +#endif + +#if defined(CH_CFG_IRQ_PROLOGUE_HOOK) +#error "SYSVIEW integration: rename CH_CFG_IRQ_PROLOGUE_HOOK to _CH_CFG_IRQ_PROLOGUE_HOOK" +#endif + +#if defined(CH_CFG_IRQ_EPILOGUE_HOOK) +#error "SYSVIEW integration: rename CH_CFG_IRQ_EPILOGUE_HOOK to _CH_CFG_IRQ_EPILOGUE_HOOK" +#endif + +#if defined(CH_CFG_SYSTEM_HALT_HOOK) +#error "SYSVIEW integration: rename CH_CFG_SYSTEM_HALT_HOOK to _CH_CFG_SYSTEM_HALT_HOOK" +#endif + +#if !defined(_CH_CFG_THREAD_INIT_HOOK) +#define _CH_CFG_THREAD_INIT_HOOK(tp) do {} while(0) +#endif + +#if !defined(_CH_CFG_THREAD_READY_HOOK) +#define _CH_CFG_THREAD_READY_HOOK(tp) do {} while(0) +#endif + +#if !defined(_CH_CFG_CONTEXT_SWITCH_HOOK) +#define _CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) do {} while(0) +#endif + +#if !defined(_CH_CFG_THREAD_EXIT_HOOK) +#define _CH_CFG_THREAD_EXIT_HOOK(tp) do {} while(0) +#endif + +#if !defined(_CH_CFG_IRQ_PROLOGUE_HOOK) +#define _CH_CFG_IRQ_PROLOGUE_HOOK() do {} while(0) +#endif + +#if !defined(_CH_CFG_IRQ_EPILOGUE_HOOK) +#define _CH_CFG_IRQ_EPILOGUE_HOOK() do {} while(0) +#endif + +#if !defined(_CH_CFG_SYSTEM_HALT_HOOK) +#define _CH_CFG_SYSTEM_HALT_HOOK(reason) do {} while(0) +#endif + +/* CH_CFG_THREAD_INIT_HOOK: + * + * We report the thread creation and we immediately send the TaskInfo + * structure, so that SystemView can show it as early as possible. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + _CH_CFG_THREAD_INIT_HOOK(tp); \ + SEGGER_SYSVIEW_OnTaskCreate((U32)tp); \ + SYSVIEW_ChibiOS_SendTaskInfo((const void *)tp); \ +} + +/* CH_CFG_THREAD_READY_HOOK: + * + * This is an *extra* hook, not present in the "stock" ChibiOS code. It is + * important if you want SystemView to show all the ready threads, even if + * they are not executing. + * + * The hook should be placed just before the return lines of the chSchReadyI + * and the chSchReadyAheadI functions, in chschd.c: + * + * thread_t *chSchReadyAheadI(thread_t *tp) { + * ... + * CH_CFG_THREAD_READY_HOOK(tp); + * return tp; + * } + * + * thread_t *chSchReadyI(thread_t *tp) { + * ... + * CH_CFG_THREAD_READY_HOOK(tp); + * return tp; + * } + */ +#define CH_CFG_THREAD_READY_HOOK(tp) { \ + _CH_CFG_THREAD_READY_HOOK(tp); \ + SEGGER_SYSVIEW_OnTaskStartReady((U32)tp); \ +} + +/* CH_CFG_CONTEXT_SWITCH_HOOK: + * + * This hook is called when switching context from Thread to Thread, or by the + * tail ISR exit sequence (see comments at CH_CFG_IRQ_EPILOGUE_HOOK). + * + * First, we report the switching-out of the "old" thread (otp), and then the + * switching-in of the "new" thread. Unfortunately, SystemView treats the idle + * thread as a special case, so we need to do some ugly handling here. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + if (otp->prio != IDLEPRIO) { \ + SEGGER_SYSVIEW_OnTaskStopReady((U32)otp, otp->state); \ + } \ + if (ntp->prio == IDLEPRIO) { \ + SEGGER_SYSVIEW_OnIdle(); \ + } else { \ + SEGGER_SYSVIEW_OnTaskStartExec((U32)ntp); \ + } \ + _CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp); \ +} + +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + _CH_CFG_THREAD_EXIT_HOOK(tp); \ + SEGGER_SYSVIEW_OnTaskStopExec(); \ +} + +/* CH_CFG_IRQ_PROLOGUE_HOOK: + * + * For the ARM Cortex-M* architectures, the PORT_IRQ_PROLOGUE doesn't contain + * any code, so the timestamp shown by SystemView for the ISR entry is quite + * accurate. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + SEGGER_SYSVIEW_RecordEnterISR(); \ + _CH_CFG_IRQ_PROLOGUE_HOOK(); \ +} + +/* CH_CFG_IRQ_EPILOGUE_HOOK: + * + * When the ISR is at the tail, and preemption is required, we tell SystemView + * that we exit the ISR to the scheduler first so that the code between + * CH_CFG_IRQ_EPILOGUE_HOOK and the actual context switch will be shown as + * "scheduler". Otherwise, that time will be shown as belonging to the thread + * that was running before the first ISR. If the ISR is not at the tail, we + * simply tell SystemView that the ISR has been exited. If the ISR is at the + * tail but preemption is not required, we tell Systemview that we exit the ISR + * so that it shows that the last thread resumes execution. + * + * When the ISR is at the tail, and preemption is required, this hook will + * be immediately followed by CH_CFG_CONTEXT_SWITCH_HOOK (see + * _port_switch_from_isr()). + * + * Actually, this hook runs a bit early in the ISR exit sequence, so the + * scheduler time shown by SystemView will be underestimated. The ideal place + * to place these calls would be at _port_irq_epilogue. + * + * Note: Unfortunately, this hook is specific to the Cortex-M architecture + * until ChibiOS gets a generic "_isr_is_tail()" macro/function. + */ +#if defined(__GNUC__) +# if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__)) +# define _isr_is_tail() (_saved_lr != (regarm_t)0xFFFFFFF1U) +# elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)) +# define _isr_is_tail() ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0U) +# else +# error "SYSVIEW integration: unsupported architecture" +# endif +#elif defined(__ICCARM__) +# if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) +# define _isr_is_tail() (_saved_lr != (regarm_t)0xFFFFFFF1U) +# elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) +# define _isr_is_tail() ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0U) +# else +# error "SYSVIEW integration: unsupported architecture" +# endif +#elif defined(__CC_ARM) +# if (defined __TARGET_ARCH_6S_M) +# define _isr_is_tail() (_saved_lr != (regarm_t)0xFFFFFFF1U) +# elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) +# define _isr_is_tail() ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0U) +# else +# error "SYSVIEW integration: unsupported architecture" +# endif +#else +# error "SYSVIEW integration: unsupported compiler" +#endif + +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + _CH_CFG_IRQ_EPILOGUE_HOOK(); \ + if (_isr_is_tail() && chSchIsPreemptionRequired()) { \ + SEGGER_SYSVIEW_RecordExitISRToScheduler(); \ + } else { \ + SEGGER_SYSVIEW_RecordExitISR(); \ + } \ +} + +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + _CH_CFG_SYSTEM_HALT_HOOK(reason); \ + SEGGER_SYSVIEW_Error(reason); \ +} + +#endif diff --git a/os/various/segger_bindings/SYSTEMVIEW/SYSVIEW_ChibiOS.txt b/os/various/segger_bindings/SYSTEMVIEW/SYSVIEW_ChibiOS.txt new file mode 100644 index 0000000..a0e97db --- /dev/null +++ b/os/various/segger_bindings/SYSTEMVIEW/SYSVIEW_ChibiOS.txt @@ -0,0 +1,8 @@ +# This file describes the ChibiOS Tasks' states. +# Put this file in the following directory: +# Path\to\SystemView\Description\ + +# +# Task States +# +TaskState 0xFF 0=Ready, 1=Current, 2=Wait start, 3=Suspended, 4=Wait queue, 5=Wait semaphore, 6=Wait mutex, 7=Wait condvar, 8=Sleeping, 9=Wait thread, 10=Wait one event, 11=Wait several events, 12=Send message queue, 13=Wait answer, 14=Wait message, 15=Terminated diff --git a/os/various/segger_bindings/example_configurations/SEGGER_RTT_Conf.h b/os/various/segger_bindings/example_configurations/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..5aa7a69 --- /dev/null +++ b/os/various/segger_bindings/example_configurations/SEGGER_RTT_Conf.h @@ -0,0 +1,123 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.44i * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +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: 13430 $ + +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 3) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 3) + +#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (128u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) + +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +/********************************************************************* +* +* RTT memcpy configuration +* +* memcpy() is good for large amounts of data, +* but the overhead is big for small amounts, which are usually stored via RTT. +* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. +* +* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. +* This is may be required with memory access restrictions, +* such as on Cortex-A devices with MMU. +*/ +#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop +// +// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets +// +//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) +// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) +//#endif + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +#if !defined(SEGGER_RTT_ASM) +#include "ch.h" +#define SEGGER_RTT_LOCK() do { \ + syssts_t LockState = chSysGetStatusAndLockX() +#define SEGGER_RTT_UNLOCK() chSysRestoreStatusX(LockState); \ + } while(0) +#endif +#endif +/*************************** End of file ****************************/ diff --git a/os/various/segger_bindings/example_configurations/SEGGER_SYSVIEW_Conf.h b/os/various/segger_bindings/example_configurations/SEGGER_SYSVIEW_Conf.h new file mode 100644 index 0000000..8d8ffa2 --- /dev/null +++ b/os/various/segger_bindings/example_configurations/SEGGER_SYSVIEW_Conf.h @@ -0,0 +1,174 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER SystemView * Real-time application analysis * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* SystemView version: V2.52h * +* * +********************************************************************** +-------------------------- END-OF-HEADER ----------------------------- + +File : SEGGER_SYSVIEW_Conf.h +Purpose : SEGGER SystemView configuration. +Revision: $Rev: 13453 $ +*/ + +#ifndef SEGGER_SYSVIEW_CONF_H +#define SEGGER_SYSVIEW_CONF_H + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +// +// Constants for known core configuration +// +#define SEGGER_SYSVIEW_CORE_OTHER 0 +#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1 +#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7 +#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX + +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) || (defined __clang__) + #if (defined __ARM_ARCH_6M__) || (defined __ARM_ARCH_8M_BASE__) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 + #endif +#elif defined(__ICCARM__) + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 + #elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__))) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 + #endif +#elif defined(__CC_ARM) + #if (defined(__TARGET_ARCH_6S_M)) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 + #endif +#elif defined(__TI_ARM__) + #ifdef __TI_ARM_V6M0__ + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0 + #elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__)) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3 + #endif +#elif defined(__ICCRX__) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX +#elif defined(__RX) + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX +#endif + +#ifndef SEGGER_SYSVIEW_CORE + #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ +/********************************************************************* +* +* SystemView buffer configuration +*/ +#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 2048 // Number of bytes that SystemView uses for the buffer. +#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection + +#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack + +#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode + +/********************************************************************* +* +* SystemView timestamp configuration +*/ +#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3 + #define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter. + #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source +#else + #define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function + #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp() +#endif + +/********************************************************************* +* +* SystemView Id configuration +*/ +#define SEGGER_SYSVIEW_ID_BASE 0x20000000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM) +#define SEGGER_SYSVIEW_ID_SHIFT 2 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned) + +/********************************************************************* +* +* SystemView interrupt configuration +*/ +#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3 + #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector) +#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0 + #if defined(__ICCARM__) + #if (__VER__ > 6100000) + #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead. + #else + #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Older versions of IAR do not include __get_IPSR, but might also not optimize to byte-access. + #endif + #else + #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector) + #endif +#else + #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function. +#endif + +#endif // SEGGER_SYSVIEW_CONF_H + +/*************************** End of file ****************************/ diff --git a/os/various/segger_bindings/segger_rtt.mk b/os/various/segger_bindings/segger_rtt.mk new file mode 100644 index 0000000..b2f1840 --- /dev/null +++ b/os/various/segger_bindings/segger_rtt.mk @@ -0,0 +1,14 @@ +# SEGGER RTT files. +SEGGERASMSRC = $(CHIBIOS_CONTRIB)/ext/SEGGER/RTT/SEGGER_RTT_ASM_ARMv7M.s +SEGGERRTTCSRC = $(CHIBIOS_CONTRIB)/ext/SEGGER/RTT/SEGGER_RTT.c \ + $(CHIBIOS_CONTRIB)/ext/SEGGER/RTT/SEGGER_RTT_printf.c \ + $(CHIBIOS_CONTRIB)/os/various/segger_bindings/RTT/SEGGER_RTT_streams.c +SEGGERRTTINC = $(CHIBIOS_CONTRIB)/ext/SEGGER/RTT \ + $(CHIBIOS_CONTRIB)/os/various/segger_bindings/RTT + + +SEGGER_RTT_ACTIVE = 1 + +ALLASMSRC += $(SEGGERASMSRC) +ALLCSRC += $(SEGGERRTTCSRC) +ALLINC += $(SEGGERRTTINC) \ No newline at end of file diff --git a/os/various/segger_bindings/segger_systemview.mk b/os/various/segger_bindings/segger_systemview.mk new file mode 100644 index 0000000..577c6ed --- /dev/null +++ b/os/various/segger_bindings/segger_systemview.mk @@ -0,0 +1,13 @@ +# Compiler options here. +ifeq ($(SEGGER_RTT_ACTIVE),) + $(error "SEGGER SystemView needs segger_rtt.mk") +endif + +# SEGGER RTT files. +SEGGERSYSTEMVIEWCSRC = $(CHIBIOS_CONTRIB)/ext/SEGGER/SYSTEMVIEW/SEGGER_SYSVIEW.c \ + $(CHIBIOS_CONTRIB)/os/various/segger_bindings/SYSTEMVIEW/SEGGER_SYSVIEW_ChibiOS.c +SEGGERSYSTEMVIEWINC = $(CHIBIOS_CONTRIB)/ext/SEGGER/SYSTEMVIEW \ + $(CHIBIOS_CONTRIB)/os/various/segger_bindings/SYSTEMVIEW + +ALLCSRC += $(SEGGERSYSTEMVIEWCSRC) +ALLINC += $(SEGGERSYSTEMVIEWINC) \ No newline at end of file -- cgit v1.2.3