From a300920de12ed9c14f2637961285588413cab6fb Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Mon, 30 Mar 2015 22:19:17 +1100 Subject: libmisc/shell: Add the rtrace command for buffered tracing support. The rtrace command interfaces to the RTEMS Trace Linker's trace buffering data allowing users to capture and report trace data. --- cpukit/libmisc/capture/rtems-trace-buffer-vars.c | 178 +++++++++++++++++++++++ cpukit/libmisc/capture/rtems-trace-buffer-vars.h | 148 +++++++++++++++++++ 2 files changed, 326 insertions(+) create mode 100644 cpukit/libmisc/capture/rtems-trace-buffer-vars.c create mode 100644 cpukit/libmisc/capture/rtems-trace-buffer-vars.h (limited to 'cpukit/libmisc/capture') diff --git a/cpukit/libmisc/capture/rtems-trace-buffer-vars.c b/cpukit/libmisc/capture/rtems-trace-buffer-vars.c new file mode 100644 index 0000000000..ef958c58f7 --- /dev/null +++ b/cpukit/libmisc/capture/rtems-trace-buffer-vars.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015 Chris Johns + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +/** + * External Trace Linker and TBG data. We provide weak versions to allow us to + * link and be present in an application that has not been trace linked. + */ + +/* + * Trace linker data. + */ +uint32_t __rtld_trace_names_size __attribute__ ((weak)); +const char const* __rtld_trace_names[1] __attribute__ ((weak)); +uint32_t __rtld_trace_enables_size __attribute__ ((weak)); +const uint32_t __rtld_trace_enables[1] __attribute__ ((weak)); +uint32_t __rtld_trace_triggers_size __attribute__ ((weak)); +const uint32_t __rtld_trace_triggers[1] __attribute__ ((weak)); +const __rtld_trace_sig __rtld_trace_signatures[1] __attribute__ ((weak)); + +/* + * Trace buffer generator data. + */ +const bool __rtld_tbg_present __attribute__ ((weak)); +const uint32_t __rtld_tbg_mode __attribute__ ((weak)); +const uint32_t __rtld_tbg_buffer_size __attribute__ ((weak)); +uint32_t __rtld_tbg_buffer[1] __attribute__ ((weak)); +volatile uint32_t __rtld_tbg_buffer_in __attribute__ ((weak)); +volatile bool __rtld_tbg_finished __attribute__ ((weak)); +volatile bool __rtld_tbg_triggered __attribute__ ((weak)); + +uint32_t +rtems_trace_names_size (void) +{ + return __rtld_trace_names_size; +} + +const char* +rtems_trace_names (const uint32_t index) +{ + return __rtld_trace_names[index]; +} + +uint32_t +rtems_trace_enables_size (void) +{ + return __rtld_trace_enables_size; +} + +uint32_t +rtems_trace_enables (const uint32_t index) +{ + return __rtld_trace_enables[index]; +} + +uint32_t +rtems_trace_triggers_size (void) +{ + return __rtld_trace_triggers_size; +} + +uint32_t +rtems_trace_triggers (const uint32_t index) +{ + return __rtld_trace_triggers[index]; +} + +const rtems_trace_sig* +rtems_trace_signatures (const uint32_t index) +{ + return &__rtld_trace_signatures[index]; +} + +bool +rtems_trace_enable_set(const uint32_t index) +{ + return (__rtld_trace_enables[index / 32] & (1 << (index & (32 - 1)))) != 0 ? true : false; +} + +bool +rtems_trace_trigger_set(const uint32_t index) +{ + return (__rtld_trace_triggers[index / 32] & (1 << (index & (32 - 1)))) != 0 ? true : false; +} + +bool +rtems_trace_buffering_present (void) +{ + return __rtld_tbg_present; +} + +uint32_t +rtems_trace_buffering_mode (void) +{ + return __rtld_tbg_mode; +} + +uint32_t +rtems_trace_buffering_buffer_size (void) +{ + return __rtld_tbg_buffer_size; +} + +uint32_t* +rtems_trace_buffering_buffer (void) +{ + return &__rtld_tbg_buffer[0]; +} + +uint32_t +rtems_trace_buffering_buffer_in (void) +{ + rtems_interrupt_lock_context lcontext; + uint32_t in; + rtems_interrupt_lock_acquire(&__rtld_tbg_lock, &lcontext); + in = __rtld_tbg_buffer_in; + rtems_interrupt_lock_release(&__rtld_tbg_lock, &lcontext); + return in; +} + +bool +rtems_trace_buffering_finished (void) +{ + rtems_interrupt_lock_context lcontext; + bool finished; + rtems_interrupt_lock_acquire(&__rtld_tbg_lock, &lcontext); + finished = __rtld_tbg_finished; + rtems_interrupt_lock_release(&__rtld_tbg_lock, &lcontext); + return finished; +} + +bool +rtems_trace_buffering_triggered (void) +{ + rtems_interrupt_lock_context lcontext; + bool triggered; + rtems_interrupt_lock_acquire(&__rtld_tbg_lock, &lcontext); + triggered = __rtld_tbg_triggered; + rtems_interrupt_lock_release(&__rtld_tbg_lock, &lcontext); + return triggered; +} + +void +rtems_trace_buffering_start (void) +{ + rtems_interrupt_lock_context lcontext; + rtems_interrupt_lock_acquire(&__rtld_tbg_lock, &lcontext); + __rtld_tbg_triggered = false; + __rtld_tbg_buffer_in = 0; + __rtld_tbg_finished = false; + rtems_interrupt_lock_release(&__rtld_tbg_lock, &lcontext); +} + +void +rtems_trace_buffering_stop (void) +{ + rtems_interrupt_lock_context lcontext; + rtems_interrupt_lock_acquire(&__rtld_tbg_lock, &lcontext); + __rtld_tbg_finished = true; + rtems_interrupt_lock_release(&__rtld_tbg_lock, &lcontext); +} + +void +rtems_trace_buffering_resume (void) +{ + rtems_interrupt_lock_context lcontext; + rtems_interrupt_lock_acquire(&__rtld_tbg_lock, &lcontext); + __rtld_tbg_finished = false; + rtems_interrupt_lock_release(&__rtld_tbg_lock, &lcontext); +} diff --git a/cpukit/libmisc/capture/rtems-trace-buffer-vars.h b/cpukit/libmisc/capture/rtems-trace-buffer-vars.h new file mode 100644 index 0000000000..8f0ff08587 --- /dev/null +++ b/cpukit/libmisc/capture/rtems-trace-buffer-vars.h @@ -0,0 +1,148 @@ +/** + * @file + * + * @ingroup Shell + * + * @brief Access to the RTEMS Trace Buffer Generator (TBG). + */ +/* + * Copyright (c) 2015 Chris Johns + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if !defined (_RTEMS_TRACE_BUFFER_VARS_H_) +#define _RTEMS_TRACE_BUFFER_VARS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * These functions are provided as a separated interface to the Trace Buffer + * Generatror (TBG) data are not really designed for any real-time performance + * type interface. + * + * Separating the data from the codes stops the compiler incorrectly loop + * optimising. + */ + +typedef struct +{ + uint32_t size; + const char* const type; +} __rtld_trace_sig_arg; + + typedef struct { + uint32_t argc; + const __rtld_trace_sig_arg* args; +} __rtld_trace_sig; + +typedef __rtld_trace_sig_arg rtems_trace_sig_arg; +typedef __rtld_trace_sig rtems_trace_sig; + +/** + * Returns the number of trace functions. + */ +uint32_t rtems_trace_names_size (void); + +/** + * Return the name given an index. No range checking. + */ +const char* rtems_trace_names (const uint32_t index); + +/** + * Returns the number of words in the enables array. + */ +uint32_t rtems_trace_enables_size (void); + +/** + * Return the enable 32bit bitmap indexed into the enables array. No range + * checking. + */ +uint32_t rtems_trace_enables (const uint32_t index); + +/** + * Returns the number of words in the triggers array. + */ +uint32_t rtems_trace_triggers_size (void); + +/** + * Return the trigger 32bit bitmap indexed into the triggers array. No range + * checking. + */ +uint32_t rtems_trace_triggers (const uint32_t index); + +/** + * Return the trace function signature. + */ +const rtems_trace_sig* rtems_trace_signatures (const uint32_t index); + +/** + * Return true is the enable bit is set for the trace function index. + */ +bool rtems_trace_enable_set(const uint32_t index); + +/** + * Return true is the trigger bit is set for the trace function index. + */ +bool rtems_trace_trigger_set(const uint32_t index); + +/** + * The application has been linked with Trace Buffering generated code. + */ +bool rtems_trace_buffering_present (void); + +/** + * Return the trace buffering mode flags. + */ +uint32_t rtems_trace_buffering_mode (void); + +/** + * Return the size of the trace buffering buffer in words. + */ +uint32_t rtems_trace_buffering_buffer_size (void); + +/** + * Return the base of the trace buffering buffer. + */ +uint32_t* rtems_trace_buffering_buffer (void); + +/** + * Return the buffer level. This is only stable if tracing has finished. + */ +uint32_t rtems_trace_buffering_buffer_in (void); + +/** + * The tracing has finished. + */ +bool rtems_trace_buffering_finished (void); + +/** + * Trace has been triggered and enable trace functions are being recorded. + */ +bool rtems_trace_buffering_triggered (void); + +/** + * Start tracing by clearing the triggered flag, setting to 0 and clearing the + * finished flag. + */ +void rtems_trace_buffering_start (void); + +/** + * Stop tracing by setting the finished flag. + */ +void rtems_trace_buffering_stop (void); + +/** + * Resume tracing by setting the finished flag. + */ +void rtems_trace_buffering_resume (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif -- cgit v1.2.3