summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/capture/capture.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libmisc/capture/capture.h')
-rw-r--r--cpukit/libmisc/capture/capture.h257
1 files changed, 199 insertions, 58 deletions
diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h
index d439968005..91eaed38d6 100644
--- a/cpukit/libmisc/capture/capture.h
+++ b/cpukit/libmisc/capture/capture.h
@@ -11,9 +11,8 @@
/*
------------------------------------------------------------------------
- Copyright Objective Design Systems Pty Ltd, 2002
- All rights reserved Objective Design Systems Pty Ltd, 2002
- Chris Johns (ccj@acm.org)
+ Copyright 2002, 2016 Chris Johns <chrisj@rtems.org>.
+ All rights reserved.
COPYRIGHT (c) 1989-2014
On-Line Applications Research Corporation (OAR).
@@ -33,6 +32,10 @@
#ifndef __CAPTURE_H_
#define __CAPTURE_H_
+#include <rtems.h>
+#include <rtems/rtems/tasksimpl.h>
+#include <rtems/score/schedulerimpl.h>
+
/**
* @defgroup libmisc_capture RTEMS Capture Engine
*
@@ -45,9 +48,22 @@
extern "C" {
#endif
-#include <rtems.h>
-#include <rtems/rtems/tasksimpl.h>
-#include <rtems/score/schedulerimpl.h>
+/*
+ * Global capture flags.
+ */
+#define RTEMS_CAPTURE_INIT (1u << 0)
+#define RTEMS_CAPTURE_ON (1U << 1)
+#define RTEMS_CAPTURE_NO_MEMORY (1U << 2)
+#define RTEMS_CAPTURE_TRIGGERED (1U << 3)
+#define RTEMS_CAPTURE_GLOBAL_WATCH (1U << 4)
+#define RTEMS_CAPTURE_ONLY_MONITOR (1U << 5)
+
+/*
+ * Per-CPU capture flags.
+ */
+#define RTEMS_CAPTURE_OVERFLOW (1U << 0)
+#define RTEMS_CAPTURE_READER_ACTIVE (1U << 1)
+#define RTEMS_CAPTURE_READER_WAITING (1U << 2)
/**
* The number of tasks in a trigger group.
@@ -154,11 +170,11 @@ typedef struct rtems_capture_control_s
*/
typedef struct rtems_capture_record_s
{
- rtems_capture_time_t time;
size_t size;
uint32_t events;
+ rtems_capture_time_t time;
rtems_id task_id;
-} rtems_capture_record_t;
+} RTEMS_PACKED rtems_capture_record_t;
/*
* @brief Capture task record.
@@ -169,11 +185,10 @@ typedef struct rtems_capture_record_s
*/
typedef struct rtems_capture_task_record_s
{
- rtems_capture_record_t rec;
- rtems_name name;
- rtems_task_priority start_priority;
- uint32_t stack_size;
-} rtems_capture_task_record_t;
+ rtems_name name;
+ rtems_task_priority start_priority;
+ uint32_t stack_size;
+} RTEMS_PACKED rtems_capture_task_record_t;
/**
* The capture record event flags.
@@ -239,6 +254,24 @@ typedef enum rtems_capture_trigger_e
typedef void (*rtems_capture_timestamp)(rtems_capture_time_t* time);
/**
+ * @brief Capture record lock context.
+ *
+ * This structure is used to lock a per CPU buffer when opeining recording. The
+ * per CPU buffer is held locked until the record close is called. Locking
+ * masks interrupts so use this lock only when needed and do not hold it for
+ * long.
+ *
+ * The lock first masks the CPU interrupt before taking the interrupt
+ * lock. This stops a thread context taking the lock and then an interrupt on
+ * the same CPU attempting to take the lock so creating a deadlock.
+ *
+ */
+typedef struct {
+ rtems_interrupt_lock_context lock_context;
+ rtems_interrupt_lock* lock;
+} rtems_capture_record_lock_context;
+
+/**
* @brief Capture open
*
* This function initialises the realtime trace manager allocating the
@@ -254,9 +287,8 @@ typedef void (*rtems_capture_timestamp)(rtems_capture_time_t* time);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_open (uint32_t size,
- rtems_capture_timestamp timestamp);
+rtems_status_code rtems_capture_open (uint32_t size,
+ rtems_capture_timestamp timestamp);
/**
* @brief Capture close
@@ -268,8 +300,7 @@ rtems_capture_open (uint32_t size,
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_close (void);
+rtems_status_code rtems_capture_close (void);
/**
* @brief Capture control trace enable/disable.
@@ -282,8 +313,7 @@ rtems_capture_close (void);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_control (bool enable);
+rtems_status_code rtems_capture_control (bool enable);
/**
* @brief Capture monitor enable/disable.
@@ -298,8 +328,7 @@ rtems_capture_control (bool enable);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_monitor (bool enable);
+rtems_status_code rtems_capture_monitor (bool enable);
/*
* @brief Capture flush trace buffer.
@@ -313,8 +342,7 @@ rtems_capture_monitor (bool enable);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_flush (bool prime);
+rtems_status_code rtems_capture_flush (bool prime);
/**
* @brief Capture add watch
@@ -331,8 +359,7 @@ rtems_capture_flush (bool prime);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_watch_add (rtems_name name, rtems_id id);
+rtems_status_code rtems_capture_watch_add (rtems_name name, rtems_id id);
/**
* @brief Capture delete watch.
@@ -348,8 +375,7 @@ rtems_capture_watch_add (rtems_name name, rtems_id id);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_watch_del (rtems_name name, rtems_id id);
+rtems_status_code rtems_capture_watch_del (rtems_name name, rtems_id id);
/**
* @brief Capture enable/disable watch.
@@ -365,10 +391,9 @@ rtems_capture_watch_del (rtems_name name, rtems_id id);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_watch_ctrl (rtems_name name,
- rtems_id id,
- bool enable);
+rtems_status_code rtems_capture_watch_ctrl (rtems_name name,
+ rtems_id id,
+ bool enable);
/**
* @brief Capture enable/disable global watch.
@@ -383,8 +408,7 @@ rtems_capture_watch_ctrl (rtems_name name,
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_watch_global (bool enable);
+rtems_status_code rtems_capture_watch_global (bool enable);
/**
* @brief Get global watch state
@@ -394,8 +418,7 @@ rtems_capture_watch_global (bool enable);
* @retval This method returns true if the global watch
* is on. Otherwise, it returns false.
*/
-bool
-rtems_capture_watch_global_on (void);
+bool rtems_capture_watch_global_on (void);
/**
* @brief Set watch ceiling.
@@ -412,8 +435,7 @@ rtems_capture_watch_global_on (void);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_watch_ceiling (rtems_task_priority ceiling);
+rtems_status_code rtems_capture_watch_ceiling (rtems_task_priority ceiling);
/**
* @brief Get watch ceiling.
@@ -423,8 +445,7 @@ rtems_capture_watch_ceiling (rtems_task_priority ceiling);
* @retval The priority level immediately above that at which events
* from tasks are not captured.
*/
-rtems_task_priority
-rtems_capture_watch_get_ceiling (void);
+rtems_task_priority rtems_capture_watch_get_ceiling (void);
/**
* @brief Capture set watch floor.
@@ -441,8 +462,7 @@ rtems_capture_watch_get_ceiling (void);
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_watch_floor (rtems_task_priority floor);
+rtems_status_code rtems_capture_watch_floor (rtems_task_priority floor);
/**
* @brief Capture set watch floor
@@ -452,8 +472,7 @@ rtems_capture_watch_floor (rtems_task_priority floor);
* @retval The priority level immediately below
* that at which events from tasks are not captured.
*/
-rtems_task_priority
-rtems_capture_watch_get_floor (void);
+rtems_task_priority rtems_capture_watch_get_floor (void);
/**
* @brief Capture set trigger
@@ -541,10 +560,9 @@ rtems_capture_clear_trigger (rtems_name from_name,
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_read (uint32_t cpu,
- uint32_t* read,
- rtems_capture_record_t** recs);
+rtems_status_code rtems_capture_read (uint32_t cpu,
+ size_t* read,
+ const void** recs);
/**
* @brief Capture release records.
@@ -558,8 +576,7 @@ rtems_capture_read (uint32_t cpu,
* error. Otherwise, a status code is returned indicating the
* source of the error.
*/
-rtems_status_code
-rtems_capture_release (uint32_t cpu, uint32_t count);
+rtems_status_code rtems_capture_release (uint32_t cpu, uint32_t count);
/*
* @brief Capture nano-second time period.
@@ -568,8 +585,34 @@ rtems_capture_release (uint32_t cpu, uint32_t count);
*
* @param[out] uptime The nano-second time period.
*/
-void
-rtems_capture_time (rtems_capture_time_t* uptime);
+void rtems_capture_time (rtems_capture_time_t* uptime);
+
+/**
+ * @brief Capture filter
+ *
+ * This function this function specifies if the given task and events should be
+ * logged.
+ *
+ * @param[in] task specifies the capture task control block
+ * @param[in] events specifies the events
+ *
+ * @retval This method returns true if this data should be filtered from the
+ * log. It returns false if this data should be logged.
+ */
+bool rtems_capture_filter (rtems_tcb* task, uint32_t events);
+
+/**
+ * @brief Capture returns the current time.
+ *
+ * This function returns the current time. If a handler is provided
+ * by the user the time is gotten from that.
+ *
+ * @param[in] time specifies the capture time
+ *
+ * @retval This method returns a nano-second time if no user handler
+ * is provided. Otherwise, it returns a resolution defined by the handler.
+ */
+void rtems_capture_get_time (rtems_capture_time_t* time);
/**
* @brief Capture get event text.
@@ -582,8 +625,7 @@ rtems_capture_time (rtems_capture_time_t* uptime);
*
* @retval This method returns a string description of the given event.
*/
-const char*
-rtems_capture_event_text (int event);
+const char* rtems_capture_event_text (int event);
/**
* @brief Capture initialize task
@@ -604,6 +646,92 @@ void rtems_capture_initialize_task( rtems_tcb* tcb );
void rtems_capture_record_task( rtems_tcb* tcb );
/**
+ * @brief Capture record lock.
+ *
+ * This does a lock acquire which will remain in effect until
+ * rtems_capture_record_unlock is called.
+ *
+ * @param[out] context specifies the record context
+ */
+void rtems_capture_record_lock (rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture record unlock.
+ *
+ * This unlocks the record lock.
+ *
+ * @param[in] context specifies the record context
+ */
+void rtems_capture_record_unlock (rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture record open.
+ *
+ * This function allocates a record and fills in the header information. It
+ * does a lock acquire which will remain in effect until
+ * rtems_capture_record_close is called. The size is the amount of user data
+ * being recorded. The record header is internally managed.
+ *
+ * @param[in] task specifies the caputre task block
+ * @param[in] events specifies the events
+ * @param[in] size specifies the user's capture data size
+ * @param[out] context specifies the record context
+ *
+ * @retval This method returns a pointer to the next location in
+ * the capture record to store data.
+ */
+void* rtems_capture_record_open (rtems_tcb* task,
+ uint32_t events,
+ size_t size,
+ rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture record close.
+ *
+ * This function closes writing to capure record and releases the lock that was
+ * held on the per CPU buffer.
+ *
+ * @param[out] context specifies the record context
+ */
+void rtems_capture_record_close (rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture append to record to the per CPU buffer.
+ *
+ * This function appends data of a specifed size into a capture buffer.
+ *
+ * @param[in] rec specifies the next write point in the capture record
+ * @param[in] data specifies the data to write
+ * @param[in] size specifies the size of the data
+ *
+ * @retval This method returns the next write point in the capture record.
+ */
+static inline void*
+rtems_capture_record_append (void* rec, const void* data, size_t size)
+{
+ memcpy (rec, data, size);
+ return ((uint8_t*) rec) + size;
+}
+
+/**
+ * @brief Capture read a record from the per CPU buffer.
+ *
+ * This function reads data of a specifed size from a capture buffer.
+ *
+ * @param[in] rec specifies the next read point in the capture record
+ * @param[in] data specifies where to write the data
+ * @param[in] size specifies the size of the data
+ *
+ * @retval This method returns the next write point in the capture record.
+ */
+static inline void*
+rtems_capture_record_extract (const void* rec, void* data, size_t size)
+{
+ memcpy (data, rec, size);
+ return ((uint8_t*) rec) + size;
+}
+
+/**
* @brief Capture task recorded
*
* This function returns true if this task information has been
@@ -643,6 +771,21 @@ rtems_capture_task_id (rtems_tcb* tcb)
}
/**
+ * @brief Capture get task API.
+ *
+ * This function returns the task API as an int.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task API as an int.
+ */
+static inline int
+rtems_capture_task_api (rtems_id id)
+{
+ return _Objects_Get_API (id);
+}
+
+/**
* @brief Capture get task state.
*
* This function returns the task state.
@@ -738,10 +881,8 @@ rtems_capture_task_control_flags (rtems_tcb* tcb)
static inline rtems_task_priority
rtems_capture_task_start_priority (rtems_tcb* tcb)
{
- return _RTEMS_Priority_From_core(
- _Scheduler_Get_own( tcb ),
- tcb->Start.initial_priority
- );
+ return _RTEMS_Priority_From_core (_Scheduler_Get_own( tcb ),
+ tcb->Start.initial_priority);
}
/**