summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/capture
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2015-03-30 22:19:17 +1100
committerChris Johns <chrisj@rtems.org>2015-03-31 17:04:43 +1100
commita300920de12ed9c14f2637961285588413cab6fb (patch)
treee7a5218ccc0e916dac2769767c8c159a2becd878 /cpukit/libmisc/capture
parentTMS570: Add board reset code to bsp_reset (diff)
downloadrtems-a300920de12ed9c14f2637961285588413cab6fb.tar.bz2
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.
Diffstat (limited to 'cpukit/libmisc/capture')
-rw-r--r--cpukit/libmisc/capture/rtems-trace-buffer-vars.c178
-rw-r--r--cpukit/libmisc/capture/rtems-trace-buffer-vars.h148
2 files changed, 326 insertions, 0 deletions
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 <chrisj@rtems.org>
+ *
+ * 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 <rtems.h>
+
+#include <rtems/trace/rtems-trace-buffer-vars.h>
+
+/**
+ * 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 <chrisj@rtems.org>
+ *
+ * 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