Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /**
0002  * @file
0003  *
0004  * @brief Capture Engine Component of the RTEMS Measurement and
0005  * Monitoring System
0006  *
0007  * This is the Capture Engine component of the RTEMS Measurement and
0008  * Monitoring system.
0009  */
0010 
0011 /*
0012   ------------------------------------------------------------------------
0013 
0014   Copyright 2002, 2016 Chris Johns <chrisj@rtems.org>.
0015   All rights reserved.
0016 
0017   COPYRIGHT (c) 1989-2014
0018   On-Line Applications Research Corporation (OAR).
0019 
0020   The license and distribution terms for this file may be
0021   found in the file LICENSE in this distribution.
0022 
0023   This software with is provided ``as is'' and with NO WARRANTY.
0024 
0025   ------------------------------------------------------------------------
0026 
0027   RTEMS Performance Monitoring and Measurement Framework.
0028   This is the Capture Engine component.
0029 
0030 */
0031 
0032 #ifndef __CAPTURE_H_
0033 #define __CAPTURE_H_
0034 
0035 #include <rtems.h>
0036 #include <rtems/rtems/tasksimpl.h>
0037 
0038 #include <string.h>
0039 
0040 /**
0041  *  @defgroup libmisc_capture RTEMS Capture Engine
0042  *
0043  *  @ingroup RTEMSAPITracing
0044  *
0045  *  Capture Engine Component of the RTEMS Measurement and Monitoring System
0046  */
0047 /**@{*/
0048 #ifdef __cplusplus
0049 extern "C" {
0050 #endif
0051 
0052 /*
0053  * Global capture flags.
0054  */
0055 #define RTEMS_CAPTURE_INIT           (1u << 0)
0056 #define RTEMS_CAPTURE_ON             (1U << 1)
0057 #define RTEMS_CAPTURE_NO_MEMORY      (1U << 2)
0058 #define RTEMS_CAPTURE_TRIGGERED      (1U << 3)
0059 #define RTEMS_CAPTURE_GLOBAL_WATCH   (1U << 4)
0060 #define RTEMS_CAPTURE_ONLY_MONITOR   (1U << 5)
0061 
0062 /*
0063  * Per-CPU capture flags.
0064  */
0065 #define RTEMS_CAPTURE_OVERFLOW       (1U << 0)
0066 #define RTEMS_CAPTURE_READER_ACTIVE  (1U << 1)
0067 #define RTEMS_CAPTURE_READER_WAITING (1U << 2)
0068 
0069 /**
0070  * The number of tasks in a trigger group.
0071  */
0072 #define RTEMS_CAPTURE_TRIGGER_TASKS (32)
0073 
0074 /**
0075  * @brief A capture timestamp.
0076  *
0077  * This is a nanosecond capture timestamp
0078  */
0079 typedef uint64_t rtems_capture_time;
0080 
0081 /**
0082  * @brief Task id and mask for the from trigger.
0083  *
0084  * A from capture is a task id and a mask for the type of
0085  * from trigger we are interested in. The mask uses the same
0086  * bit maps as the flags field in the control structure. There
0087  * will only be a from type trigger if the flags in the control
0088  * structure has the specific *_BY bit set.
0089  */
0090 typedef struct rtems_capture_from
0091 {
0092   rtems_name name;
0093   rtems_id   id;
0094   uint32_t   trigger;
0095 } rtems_capture_from;
0096 
0097 /**
0098  * @brief Capture control structure for a group of tasks.
0099  *
0100  * RTEMS control holds the trigger and watch configuration for a group of
0101  * tasks with the same name. The flags hold global control flags.
0102  *
0103  * The to_triggers fields holds triggers TO this task. The from_triggers holds
0104  * triggers from this task. The by_triggers is an OR or triggers which are
0105  * caused BY the task listed TO this task. The by_valid flag which entries
0106  * in by are valid.
0107  */
0108 typedef struct rtems_capture_control
0109 {
0110   rtems_name                    name;
0111   rtems_id                      id;
0112   uint32_t                      flags;
0113   uint32_t                      to_triggers;
0114   uint32_t                      from_triggers;
0115   uint32_t                      by_triggers;
0116   uint32_t                      by_valid;
0117   rtems_capture_from            by[RTEMS_CAPTURE_TRIGGER_TASKS];
0118   struct rtems_capture_control* next;
0119 } rtems_capture_control;
0120 
0121 /**
0122  * The from_valid mask.
0123  */
0124 #define RTEMS_CAPTURE_CONTROL_FROM_MASK(_s) \
0125  (UINT32_C(1) << (RTEMS_CAPTURE_TRIGGER_TASKS - ((_s) + 1)))
0126 
0127 /**
0128  * Control flags.
0129  */
0130 #define RTEMS_CAPTURE_WATCH         (1U << 0)
0131 
0132 /**
0133  * Control triggers.
0134  */
0135 #define RTEMS_CAPTURE_SWITCH        (1 << 0)
0136 #define RTEMS_CAPTURE_CREATE        (1 << 1)
0137 #define RTEMS_CAPTURE_START         (1 << 2)
0138 #define RTEMS_CAPTURE_RESTART       (1 << 3)
0139 #define RTEMS_CAPTURE_DELETE        (1 << 4)
0140 #define RTEMS_CAPTURE_BEGIN         (1 << 5)
0141 #define RTEMS_CAPTURE_EXITTED       (1 << 6)
0142 #define RTEMS_CAPTURE_TERMINATED    (1 << 7)
0143 
0144 #define RTEMS_CAPTURE_FROM_TRIGS    (RTEMS_CAPTURE_SWITCH  | \
0145                                      RTEMS_CAPTURE_CREATE | \
0146                                      RTEMS_CAPTURE_START | \
0147                                      RTEMS_CAPTURE_RESTART | \
0148                                      RTEMS_CAPTURE_DELETE)
0149 
0150 #define RTEMS_CAPTURE_TO_TRIGS      (RTEMS_CAPTURE_SWITCH | \
0151                                      RTEMS_CAPTURE_CREATE | \
0152                                      RTEMS_CAPTURE_START | \
0153                                      RTEMS_CAPTURE_RESTART | \
0154                                      RTEMS_CAPTURE_DELETE | \
0155                                      RTEMS_CAPTURE_BEGIN | \
0156                                      RTEMS_CAPTURE_EXITTED)
0157 
0158 /**
0159  * Task flags.
0160  */
0161 #define RTEMS_CAPTURE_TRACED      (1U << 0)
0162 #define RTEMS_CAPTURE_INIT_TASK   (1U << 1)
0163 #define RTEMS_CAPTURE_RECORD_TASK (1U << 2)
0164 
0165 /*
0166  * @brief Capture record.
0167  *
0168  * This is a record that is written into
0169  * the buffer. The events includes the priority of the task
0170  * at the time of the context switch.
0171  */
0172 typedef struct rtems_capture_record
0173 {
0174   size_t             size;
0175   uint32_t           events;
0176   rtems_id           task_id;
0177   rtems_capture_time time;
0178 } RTEMS_PACKED rtems_capture_record;
0179 
0180 /*
0181  * @brief Capture task record.
0182  *
0183  * This is a record that is written into
0184  * the buffer. The events includes the priority of the task
0185  * at the time of the context switch.
0186  */
0187 typedef struct rtems_capture_task_record
0188 {
0189   rtems_name          name;
0190   rtems_task_priority start_priority;
0191   uint32_t            stack_size;
0192 } RTEMS_PACKED rtems_capture_task_record;
0193 
0194 /**
0195  * The capture record event flags.
0196  */
0197 #define RTEMS_CAPTURE_REAL_PRI_EVENT_MASK UINT32_C (0x000000ff)
0198 #define RTEMS_CAPTURE_CURR_PRI_EVENT_MASK UINT32_C (0x0000ff00)
0199 #define RTEMS_CAPTURE_REAL_PRIORITY_EVENT (0)
0200 #define RTEMS_CAPTURE_CURR_PRIORITY_EVENT (8)
0201 #define RTEMS_CAPTURE_EVENT_START         (16)
0202 #define RTEMS_CAPTURE_CREATED_BY_EVENT    UINT32_C (0x00010000)
0203 #define RTEMS_CAPTURE_CREATED_EVENT       UINT32_C (0x00020000)
0204 #define RTEMS_CAPTURE_STARTED_BY_EVENT    UINT32_C (0x00040000)
0205 #define RTEMS_CAPTURE_STARTED_EVENT       UINT32_C (0x00080000)
0206 #define RTEMS_CAPTURE_RESTARTED_BY_EVENT  UINT32_C (0x00100000)
0207 #define RTEMS_CAPTURE_RESTARTED_EVENT     UINT32_C (0x00200000)
0208 #define RTEMS_CAPTURE_DELETED_BY_EVENT    UINT32_C (0x00400000)
0209 #define RTEMS_CAPTURE_DELETED_EVENT       UINT32_C (0x00800000)
0210 #define RTEMS_CAPTURE_TERMINATED_EVENT    UINT32_C (0x01000000)
0211 #define RTEMS_CAPTURE_BEGIN_EVENT         UINT32_C (0x02000000)
0212 #define RTEMS_CAPTURE_EXITTED_EVENT       UINT32_C (0x04000000)
0213 #define RTEMS_CAPTURE_SWITCHED_OUT_EVENT  UINT32_C (0x08000000)
0214 #define RTEMS_CAPTURE_SWITCHED_IN_EVENT   UINT32_C (0x10000000)
0215 #define RTEMS_CAPTURE_TIMESTAMP           UINT32_C (0x20000000)
0216 #define RTEMS_CAPTURE_EVENT_END           (29)
0217 
0218 /**
0219  * @brief Capture trigger modes
0220  *
0221  * The types of trigger modes that exist.
0222  */
0223 typedef enum rtems_capture_trigger_mode
0224 {
0225   rtems_capture_to_any,
0226   rtems_capture_from_any,
0227   rtems_capture_from_to
0228 } rtems_capture_trigger_mode;
0229 
0230 /**
0231  * @brief Capture trigger.
0232  *
0233  * The types of triggers that exist.
0234  */
0235 typedef enum rtems_capture_trigger
0236 {
0237   rtems_capture_switch,
0238   rtems_capture_create,
0239   rtems_capture_start,
0240   rtems_capture_restart,
0241   rtems_capture_delete,
0242   rtems_capture_begin,
0243   rtems_capture_exitted,
0244   rtems_capture_terminated
0245 } rtems_capture_trigger;
0246 
0247 /**
0248  * @brief Capture timestamp callout handler.
0249  *
0250  * This defines the callout handler to obtain a time stamp. The
0251  * value returned is time count since the last read.
0252  *
0253  */
0254 
0255 typedef void (*rtems_capture_timestamp)(rtems_capture_time* time);
0256 
0257 /**
0258  * @brief Capture record lock context.
0259  *
0260  * This structure is used to lock a per CPU buffer when opeining recording. The
0261  * per CPU buffer is held locked until the record close is called. Locking
0262  * masks interrupts so use this lock only when needed and do not hold it for
0263  * long.
0264  *
0265  * The lock first masks the CPU interrupt before taking the interrupt
0266  * lock. This stops a thread context taking the lock and then an interrupt on
0267  * the same CPU attempting to take the lock so creating a deadlock.
0268  *
0269  */
0270 typedef struct {
0271   rtems_interrupt_lock_context lock_context;
0272   rtems_interrupt_lock*        lock;
0273 } rtems_capture_record_lock_context;
0274 
0275 /**
0276  * @brief Capture open
0277  *
0278  * This function initialises the realtime trace manager allocating the
0279  * capture buffer. It is assumed we have a working heap at stage of
0280  * initialisation.
0281  *
0282  * @param[in] size The number of capture records to define.
0283  * @param[in] timestamp The timestamp callout handler to use. If the
0284  *            the handler is NULL a default  nano-second timestamp
0285  *            will be used.
0286  *
0287  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0288  *         error. Otherwise, a status code is returned indicating the
0289  *         source of the error.
0290  */
0291 rtems_status_code rtems_capture_open (uint32_t                size,
0292                                       rtems_capture_timestamp timestamp);
0293 
0294 /**
0295  * @brief Capture close
0296  *
0297  * This function shutdowns the tracer and release any claimed
0298  * resources.
0299  *
0300  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0301  *         error. Otherwise, a status code is returned indicating the
0302  *         source of the error.
0303  */
0304 rtems_status_code rtems_capture_close (void);
0305 
0306 /**
0307  * @brief Capture control trace enable/disable.
0308  *
0309  * This function allows control of tracing at a global level.
0310  *
0311  * @param[in]  enable The trace enable/disable flag.
0312  *
0313  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0314  *         error. Otherwise, a status code is returned indicating the
0315  *         source of the error.
0316  */
0317 rtems_status_code rtems_capture_set_control (bool enable);
0318 
0319 /**
0320  * @brief Capture monitor enable/disable.
0321  *
0322  * This function enable the monitor mode. When in the monitor mode
0323  * the tasks are monitored but no data is saved. This can be used
0324  * to profile the load on a system.
0325  *
0326  * @param[in]  enable The monitor enable/disable flag.
0327  *
0328  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0329  *         error. Otherwise, a status code is returned indicating the
0330  *         source of the error.
0331  */
0332 rtems_status_code rtems_capture_set_monitor (bool enable);
0333 
0334 /*
0335  * @brief Capture flush trace buffer.
0336  *
0337  * This function flushes the trace buffer. The prime parameter allows the
0338  * capture engine to also be primed again.
0339  *
0340  * @param[in]  prime The prime after flush flag.
0341  *
0342  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0343  *         error. Otherwise, a status code is returned indicating the
0344  *         source of the error.
0345  */
0346 rtems_status_code rtems_capture_flush (bool prime);
0347 
0348 /**
0349  * @brief Capture add watch
0350  *
0351  * This function defines a watch for a specific task given a name. A watch
0352  * causes it to be traced either in or out of context. The watch can be
0353  * optionally enabled or disabled with the set routine. It is disabled by
0354  * default.
0355  *
0356  * @param[in]  name The name of the @a capture_controls entry
0357  * @param[in]  id The id of the @a capture_controls entry.
0358  *
0359  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0360  *         error. Otherwise, a status code is returned indicating the
0361  *         source of the error.
0362  */
0363 rtems_status_code rtems_capture_watch_add (rtems_name name, rtems_id id);
0364 
0365 /**
0366  * @brief Capture delete watch.
0367  *
0368  * This function removes a watch for a specific task given a name. The task
0369  * description will still exist if referenced by a trace record in the trace
0370  * buffer or a global watch is defined.
0371  *
0372  * @param[in]  name The name of the @a capture_controls entry
0373  * @param[in]  id The id of the @a capture_controls entry.
0374  *
0375  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0376  *         error. Otherwise, a status code is returned indicating the
0377  *         source of the error.
0378  */
0379 rtems_status_code rtems_capture_watch_del (rtems_name name, rtems_id id);
0380 
0381 /**
0382  * @brief Capture enable/disable watch.
0383  *
0384  * This function allows control of a watch. The watch can be enabled or
0385  * disabled.
0386  *
0387  * @param[in]  name The name of the @a capture_controls entry
0388  * @param[in]  id The id of the @a capture_controls entry.
0389  * @param[in]  enable The enable/disable flag for the watch.
0390  *
0391  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0392  *         error. Otherwise, a status code is returned indicating the
0393  *         source of the error.
0394  */
0395 rtems_status_code rtems_capture_watch_ctrl (rtems_name name,
0396                                             rtems_id   id,
0397                                             bool       enable);
0398 
0399 /**
0400  * @brief Capture enable/disable global watch.
0401  *
0402  * This function allows control of a global watch. The watch can
0403  * be enabled or disabled. A global watch configures all tasks below
0404  * the ceiling and above the floor to be traced.
0405  *
0406  * @param[in]  enable The enable/disable flag for the watch.
0407  *
0408  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0409  *         error. Otherwise, a status code is returned indicating the
0410  *         source of the error.
0411  */
0412 rtems_status_code rtems_capture_watch_global (bool enable);
0413 
0414 /**
0415  * @brief Get global watch state
0416  *
0417  * This function returns the global watch state.
0418  *
0419  * @retval This method returns true  if the global watch
0420  *         is on.  Otherwise, it returns false.
0421  */
0422 bool rtems_capture_watch_global_on (void);
0423 
0424 /**
0425  * @brief Set watch ceiling.
0426  *
0427  * This function sets a watch ceiling. Events from tasks at or greater
0428  * than the ceiling priority are ignored. This is a simple way to
0429  * monitor an application and exclude system tasks running at a higher
0430  * priority level.
0431  *
0432  * @param[in] ceiling specifies the priority level immediately above
0433  *     that at which events from tasks are not captured.
0434  *
0435  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0436  *         error. Otherwise, a status code is returned indicating the
0437  *         source of the error.
0438  */
0439 rtems_status_code rtems_capture_watch_ceiling (rtems_task_priority ceiling);
0440 
0441 /**
0442  * @brief Get watch ceiling.
0443  *
0444  * This function gets the watch ceiling.
0445  *
0446  * @retval The priority level immediately above that at which events
0447  *         from tasks are not captured.
0448  */
0449 rtems_task_priority rtems_capture_watch_get_ceiling (void);
0450 
0451 /**
0452  * @brief Capture set watch floor.
0453  *
0454  * This function sets a watch floor. Tasks at or less than the
0455  * floor priority are not watched. This is a simple way to monitor
0456  * an application and exclude system tasks running at a lower
0457  * priority level.
0458  *
0459  * @param[in] floor specifies the priority level immediately below
0460  *     that at which events from tasks are not captured.
0461  *
0462  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0463  *         error. Otherwise, a status code is returned indicating the
0464  *         source of the error.
0465  */
0466 rtems_status_code rtems_capture_watch_floor (rtems_task_priority floor);
0467 
0468 /**
0469  * @brief Capture set watch floor
0470  *
0471  * This function gets the watch floor.
0472  *
0473  * @retval The priority level immediately below
0474  *     that at which events from tasks are not captured.
0475  */
0476 rtems_task_priority rtems_capture_watch_get_floor (void);
0477 
0478 /**
0479  * @brief Capture set trigger
0480  *
0481  * This function sets a trigger.
0482  *
0483  * This set trigger routine will create a trace control for the
0484  * target task. The task list is searched and any existing tasks
0485  * are linked to the new control.
0486  *
0487  * We can have a number of tasks that have the same name so we
0488  * search using names. This means a number of tasks can be
0489  * linked to single control.
0490  *
0491  * Some events captured such as context switch include two
0492  * tasks. These are referred to as being "from" and "to"
0493  * Some events may only have one task specified.
0494  *
0495  * @param[in] from_name specifies the name of the from task.
0496  * @param[in] from_id specifies the id of the from task.
0497  * @param[in] to_name specifies the name of the to task.
0498  * @param[in] to_id specifies the id of the to task.
0499  * @param[in] mode specifies the trigger mode.
0500  * @param[in] trigger specifies the type of trigger.
0501  *
0502  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0503  *         error. Otherwise, a status code is returned indicating the
0504  *         source of the error.
0505  */
0506 rtems_status_code
0507 rtems_capture_set_trigger (rtems_name                 from_name,
0508                            rtems_id                   from_id,
0509                            rtems_name                 to_name,
0510                            rtems_id                   to_id,
0511                            rtems_capture_trigger_mode mode,
0512                            rtems_capture_trigger      trigger);
0513 
0514 /**
0515  * @brief Capture clear trigger.
0516  *
0517  * This function clears a trigger.
0518  *
0519  * This clear trigger routine will not clear a watch.
0520  *
0521  * @param[in] from_name specifies the name of the from task.
0522  * @param[in] from_id specifies the id of the from task.
0523  * @param[in] to_name specifies the name of the to task.
0524  * @param[in] to_id specifies the id of the to task.
0525  * @param[in] mode specifies the trigger mode.
0526  * @param[in] trigger specifies the type of trigger.
0527  *
0528  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0529  *         error. Otherwise, a status code is returned indicating the
0530  *         source of the error.
0531  */
0532 rtems_status_code
0533 rtems_capture_clear_trigger (rtems_name                 from_name,
0534                              rtems_id                   from_id,
0535                              rtems_name                 to_name,
0536                              rtems_id                   to_id,
0537                              rtems_capture_trigger_mode mode,
0538                              rtems_capture_trigger      trigger);
0539 
0540 /**
0541  * @brief Capture read records from capture buffer
0542  *
0543  * This function reads a number of records from the capture buffer.
0544  *
0545  * The function returns the number of record that is has that are
0546  * in a continous block of memory. If the number of available records
0547  * wrap then only those records are provided. This removes the need for
0548  * caller to be concerned about buffer wrappings. If the number of
0549  * requested records cannot be met due to the wrapping of the records
0550  * less than the specified number will be returned.
0551  *
0552  * The user must release the records. This is achieved with a call to
0553  * rtems_capture_release. Calls this function without a release will
0554  * result in at least the same number of records being released.
0555  *
0556  * @param[in]  cpu The cpu number that the records were recorded on
0557  * @param[out] read will contain the number of records read
0558  * @param[out] recs The capture records that are read.
0559  *
0560  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0561  *         error. Otherwise, a status code is returned indicating the
0562  *         source of the error.
0563  */
0564 rtems_status_code rtems_capture_read (uint32_t     cpu,
0565                                       size_t*      read,
0566                                       const void** recs);
0567 
0568 /**
0569  * @brief Capture release records.
0570  *
0571  * This function releases the requested number of record slots back
0572  * to the capture engine. The count must match the number read.
0573  *
0574  * @param[in] count The number of record slots to release
0575  *
0576  * @retval This method returns RTEMS_SUCCESSFUL if there was not an
0577  *         error. Otherwise, a status code is returned indicating the
0578  *         source of the error.
0579  */
0580 rtems_status_code rtems_capture_release (uint32_t cpu, uint32_t count);
0581 
0582 /**
0583  * @brief Capture filter
0584  *
0585  * This function this function specifies if the given task and events should be
0586  * logged.
0587  *
0588  * @param[in] task specifies the capture task control block
0589  * @param[in] events specifies the events
0590  *
0591  * @retval This method returns true if this data should be filtered from the
0592  *         log. It returns false if this data should be logged.
0593  */
0594 bool rtems_capture_filter (rtems_tcb* task, uint32_t events);
0595 
0596 /**
0597  * @brief Capture returns the current time.
0598  *
0599  * This function returns the current time. If a handler is provided
0600  * by the user the time is gotten from that.
0601  *
0602  * @param[in] time specifies the capture time
0603  *
0604  * @retval This method returns a nano-second time if no user handler
0605  * is provided.  Otherwise, it returns a resolution defined by the handler.
0606  */
0607 void rtems_capture_get_time (rtems_capture_time* time);
0608 
0609 /**
0610  * @brief Capture get event text.
0611  *
0612  * This function returns a string for an event based on the bit in the
0613  * event. The functions takes the bit offset as a number not the bit
0614  * set in a bit map.
0615  *
0616  * @param[in] event specifies the event to describe
0617  *
0618  * @retval This method returns a string description of the given event.
0619  */
0620 const char* rtems_capture_event_text (int event);
0621 
0622 /**
0623  * @brief Capture initialize task
0624  *
0625  * This function initializes capture control in the tcb.
0626  *
0627  * @param[in] tcb is the task control block for the task
0628  */
0629 void rtems_capture_initialize_task (rtems_tcb* tcb);
0630 
0631 /**
0632  * @brief Capture record task.
0633  *
0634  * This function records a new capture task record.
0635  *
0636  * @param[in] tcb is the task control block for the task
0637  */
0638 void rtems_capture_record_task (rtems_tcb* tcb);
0639 
0640 /**
0641  * @brief Capture record lock.
0642  *
0643  * This does a lock acquire which will remain in effect until
0644  * rtems_capture_record_unlock is called.
0645  *
0646  * @param[out] context specifies the record context
0647  */
0648 void rtems_capture_record_lock (rtems_capture_record_lock_context* context);
0649 
0650 /**
0651  * @brief Capture record unlock.
0652  *
0653  * This unlocks the record lock.
0654  *
0655  * @param[in] context specifies the record context
0656  */
0657 void rtems_capture_record_unlock (rtems_capture_record_lock_context* context);
0658 
0659 /**
0660  * @brief Capture record open.
0661  *
0662  * This function allocates a record and fills in the header information. It
0663  * does a lock acquire which will remain in effect until
0664  * rtems_capture_record_close is called. The size is the amount of user data
0665  * being recorded. The record header is internally managed.
0666  *
0667  * @param[in] task specifies the caputre task block
0668  * @param[in] events specifies the events
0669  * @param[in] size specifies the user's capture data size
0670  * @param[out] context specifies the record context
0671  *
0672  * @retval This method returns a pointer to the next location in
0673  * the capture record to store data.
0674  */
0675 void* rtems_capture_record_open (rtems_tcb*                         task,
0676                                  uint32_t                           events,
0677                                  size_t                             size,
0678                                  rtems_capture_record_lock_context* context);
0679 
0680 /**
0681  * @brief Capture record close.
0682  *
0683  * This function closes writing to capure record and releases the lock that was
0684  * held on the per CPU buffer.
0685  *
0686  * @param[out] context specifies the record context
0687  */
0688 void rtems_capture_record_close (rtems_capture_record_lock_context* context);
0689 
0690 /**
0691  * @brief Capture append to record to the per CPU buffer.
0692  *
0693  * This function appends data of a specifed size into a capture buffer.
0694  *
0695  * @param[in] rec specifies the next write point in the capture record
0696  * @param[in] data specifies the data to write
0697  * @param[in] size specifies the size of the data
0698  *
0699  * @retval This method returns the next write point in the capture record.
0700  */
0701 static inline void*
0702 rtems_capture_record_append (void* rec, const void* data, size_t size)
0703 {
0704   memcpy (rec, data, size);
0705   return ((uint8_t*) rec) + size;
0706 }
0707 
0708 /**
0709  * @brief Capture read a record from the per CPU buffer.
0710  *
0711  * This function reads data of a  specifed size from a capture buffer.
0712  *
0713  * @param[in] rec specifies the next read point in the capture record
0714  * @param[in] data specifies where to write the data
0715  * @param[in] size specifies the size of the data
0716  *
0717  * @retval This method returns the next write point in the capture record.
0718  */
0719 static inline void*
0720 rtems_capture_record_extract (const void* rec, void* data, size_t size)
0721 {
0722   memcpy (data, rec, size);
0723   return ((uint8_t*) rec) + size;
0724 }
0725 
0726 /**
0727  * @brief Capture task recorded
0728  *
0729  * This function returns true if this task information has been
0730  * recorded.
0731  *
0732  * @param[in] tcb is the task control block for the task
0733  */
0734 static inline bool rtems_capture_task_recorded (rtems_tcb* tcb) {
0735   return ((tcb->Capture.flags & RTEMS_CAPTURE_RECORD_TASK) != 0);
0736 }
0737 
0738 /**
0739  * @brief Capture task initialized
0740  *
0741  * This function returns true if this task information has been
0742  * initialized.
0743  *
0744  * @param[in] tcb is the task control block for the task
0745  */
0746 static inline bool rtems_capture_task_initialized (rtems_tcb* tcb) {
0747   return ((tcb->Capture.flags & RTEMS_CAPTURE_INIT_TASK) != 0);
0748 }
0749 
0750 /**
0751  * @brief Capture get task id.
0752  *
0753  * This function returns the task id.
0754  *
0755  * @param[in] task The capture task.
0756  *
0757  * @retval This function returns the task id.
0758  */
0759 static inline rtems_id
0760 rtems_capture_task_id (rtems_tcb* tcb)
0761 {
0762   return tcb->Object.id;
0763 }
0764 
0765 /**
0766  * @brief Capture get task API.
0767  *
0768  * This function returns the task API as an int.
0769  *
0770  * @param[in] task The capture task.
0771  *
0772  * @retval This function returns the task API as an int.
0773  */
0774 static inline int
0775 rtems_capture_task_api (rtems_id id)
0776 {
0777   return _Objects_Get_API (id);
0778 }
0779 
0780 /**
0781  * @brief Capture get task state.
0782  *
0783  * This function returns the task state.
0784  *
0785  * @param[in] task The capture task.
0786  *
0787  * @retval This function returns the task state.
0788  */
0789 static inline States_Control
0790 rtems_capture_task_state (rtems_tcb* tcb)
0791 {
0792   if (tcb)
0793     return tcb->current_state;
0794   return 0;
0795 }
0796 
0797 /**
0798  * @brief Capture get task name.
0799  *
0800  * This function returns the task name.
0801  *
0802  * @param[in] task The capture task.
0803  *
0804  * @retval This function returns the task name.
0805  */
0806 static inline rtems_name
0807 rtems_capture_task_name (rtems_tcb* tcb)
0808 {
0809   rtems_name  name;
0810   rtems_object_get_classic_name( tcb->Object.id, &name );
0811   return name;
0812 }
0813 
0814 /**
0815  * @brief Capture get task flags.
0816  *
0817  * This function returns the task flags.
0818  *
0819  * @param[in] task The capture task.
0820  *
0821  * @retval This function returns the task flags.
0822  */
0823 static inline uint32_t
0824 rtems_capture_task_flags (rtems_tcb* tcb)
0825 {
0826   return tcb->Capture.flags;
0827 }
0828 
0829 /**
0830  * @brief Capture get task control
0831  *
0832  * This function returns the task control if present.
0833  *
0834  * @param[in] task The capture task.
0835  *
0836  * @retval This function returns the task control if present.
0837  */
0838 static inline rtems_capture_control*
0839 rtems_capture_task_control (rtems_tcb* tcb)
0840 {
0841   return (rtems_capture_control*) tcb->Capture.control;
0842 }
0843 
0844 /**
0845  * @brief Capture get task control flags.
0846  *
0847  * This function returns the task control flags if a control is present.
0848  *
0849  * @param[in] task The capture task.
0850  *
0851  * @retval This function returns the task control flags if a control is present.
0852  */
0853 static inline uint32_t
0854 rtems_capture_task_control_flags (rtems_tcb* tcb)
0855 {
0856   rtems_capture_control*  control = rtems_capture_task_control (tcb);
0857   if (!control)
0858     return 0;
0859   return control->flags;
0860 }
0861 
0862 /**
0863  * @brief Capture get task start priority.
0864  *
0865  * This function returns the tasks start priority. The tracer needs this
0866  * to track where the task's priority goes.
0867  *
0868  * @param[in] task The capture task.
0869  *
0870  * @retval This function returns the tasks start priority. The tracer needs this
0871  * to track where the task's priority goes.
0872  */
0873 static inline rtems_task_priority
0874 rtems_capture_task_start_priority (rtems_tcb* tcb)
0875 {
0876   return _RTEMS_Priority_From_core (_Thread_Scheduler_get_home( tcb ),
0877                                     tcb->Start.initial_priority);
0878 }
0879 
0880 /**
0881  * @brief Capture get task real priority.
0882  *
0883  * This function returns the tasks real priority.
0884  *
0885  * @param[in] task The capture task.
0886  *
0887  * @retval This function returns the tasks real priority.
0888  */
0889 static inline rtems_task_priority
0890 rtems_capture_task_real_priority (rtems_tcb* tcb)
0891 {
0892   return _Thread_Get_unmapped_real_priority (tcb);
0893 }
0894 
0895 /**
0896  * @brief Capture get task current priority.
0897  *
0898  * This function returns the tasks current priority.
0899  *
0900  * @param[in] task The capture task.
0901  *
0902  * @retval This function returns the tasks current priority.
0903  */
0904 static inline rtems_task_priority
0905 rtems_capture_task_curr_priority (rtems_tcb* tcb)
0906 {
0907   return _Thread_Get_unmapped_priority (tcb);
0908 }
0909 
0910 /**
0911  * @brief Capture get control list.
0912  *
0913  * This function returns the head of the list of controls in the
0914  * capture engine.
0915  *
0916  * @retval This function returns the head of the list of controls in the
0917  * capture engine.
0918  */
0919 rtems_capture_control*
0920 rtems_capture_get_control_list (void);
0921 
0922 /**
0923  * @brief Capture get next capture control.
0924  *
0925  * This function returns the pointer to the next control in the list. The
0926  * pointer NULL terminates the list.
0927  *
0928  * @param[in] control the current capture control.
0929  *
0930  * @retval This function returns the pointer to the next control in the list. The
0931  * pointer NULL terminates the list.
0932  */
0933 static inline rtems_capture_control*
0934 rtems_capture_next_control (rtems_capture_control* control)
0935 {
0936   return control->next;
0937 }
0938 
0939 /**
0940  * @brief Capture get capture control id.
0941  *
0942  * This function returns the control id.
0943  *
0944  * @param[in] control the capture control.
0945  *
0946  * @retval This function returns the control id.
0947  */
0948 static inline rtems_id
0949 rtems_capture_control_id (rtems_capture_control* control)
0950 {
0951   return control->id;
0952 }
0953 
0954 /**
0955  * @brief Capture get capture control name.
0956  *
0957  * This function returns the control name.
0958  *
0959  * @param[in] control the capture control.
0960  *
0961  * @retval This function returns the control name.
0962  */
0963 static inline rtems_name
0964 rtems_capture_control_name (rtems_capture_control* control)
0965 {
0966   return control->name;
0967 }
0968 
0969 /**
0970  * @brief Capture get capture control flags.
0971  *
0972  * This function returns the control flags.
0973  *
0974  * @param[in] control the capture control.
0975  *
0976  * @retval This function returns the control flags.
0977  */
0978 static inline uint32_t
0979 rtems_capture_control_flags (rtems_capture_control* control)
0980 {
0981   return control->flags;
0982 }
0983 
0984 /**
0985  * @brief Capture get capture control to triggers.
0986  *
0987  * This function returns the task control to triggers.
0988  *
0989  * @param[in] control the capture control.
0990  *
0991  * @retval This function returns the task control to triggers.
0992  */
0993 static inline uint32_t
0994 rtems_capture_control_to_triggers (rtems_capture_control* control)
0995 {
0996   return control->to_triggers;
0997 }
0998 
0999 /**
1000  * @brief Capture get capture control from triggers.
1001  *
1002  * This function returns the task control from triggers.
1003  *
1004  * @param[in] control the capture control.
1005  *
1006  * @retval This function returns the task control from triggers.
1007  */
1008 static inline uint32_t
1009 rtems_capture_control_from_triggers (rtems_capture_control* control)
1010 {
1011   return control->from_triggers;
1012 }
1013 
1014 /**
1015  * @brief Capture get capture control by triggers.
1016  *
1017  * This function returns the task control by triggers.
1018  *
1019  * @param[in] control the capture control.
1020  *
1021  * @retval This function returns the task control by triggers.
1022  */
1023 static inline uint32_t
1024 rtems_capture_control_all_by_triggers (rtems_capture_control* control)
1025 {
1026   return control->by_triggers;
1027 }
1028 
1029 /**
1030  * @brief Capture get capture control valid by flags.
1031  *
1032  * This function returns the control valid BY flags.
1033  *
1034  * @param[in] control The capture control.
1035  * @param[in] slot The slot.
1036  *
1037  * @retval This function returns the control valid BY flags.
1038  */
1039 static inline int
1040 rtems_capture_control_by_valid (rtems_capture_control* control, int slot)
1041 {
1042   return control->by_valid & RTEMS_CAPTURE_CONTROL_FROM_MASK (slot);
1043 }
1044 
1045 /**
1046  * @brief Capture get capture control by task name.
1047  *
1048  * This function returns the control @a by task name.
1049  *
1050  * @param[in] control The capture control.
1051  * @param[in] by The by index.
1052  *
1053  * @retval This function returns the control @a by task name.
1054  */
1055 static inline rtems_name
1056 rtems_capture_control_by_name (rtems_capture_control* control, int by)
1057 {
1058   if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
1059     return control->by[by].name;
1060   return control->by[0].name;
1061 }
1062 
1063 /**
1064  * @brief Capture get capture control by task id.
1065  *
1066  * This function returns the control @a by task id
1067  *
1068  * @retval This function returns the control @a by task id.
1069  */
1070 static inline rtems_id
1071 rtems_capture_control_by_id (rtems_capture_control* control, int by)
1072 {
1073   if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
1074     return control->by[by].id;
1075   return control->by[0].id;
1076 }
1077 
1078 /**
1079  * @brief Capture get capture control by task triggers.
1080  *
1081  * This function returns the control @a by task triggers.
1082  *
1083  * @retval This function returns the control @a by task triggers.
1084  */
1085 static inline uint32_t
1086 rtems_capture_control_by_triggers (rtems_capture_control* control,
1087                                    int                      by)
1088 {
1089   if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
1090     return control->by[by].trigger;
1091   return control->by[0].trigger;
1092 }
1093 
1094 /**
1095  * @brief Capture get capture control count.
1096  *
1097  * This function returns the number of controls the capture
1098  * engine has.
1099  *
1100  * @retval This function returns the number of controls the capture
1101  * engine has.
1102  */
1103 static inline uint32_t
1104 rtems_capture_control_count (void)
1105 {
1106   rtems_capture_control* control = rtems_capture_get_control_list ();
1107   uint32_t               count = 0;
1108 
1109   while (control)
1110   {
1111     count++;
1112     control = rtems_capture_next_control (control);
1113   }
1114 
1115   return count;
1116 }
1117 
1118 #ifdef __cplusplus
1119 }
1120 #endif
1121 /**@}*/
1122 
1123 #endif