⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capture.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * rtems_capture_watch_del * *  DESCRIPTION: * * This function removes a watch for a specific task given a name. The task * description will still exist if referenced by a trace record in the trace * buffer or a global watch is defined. */rtems_status_codertems_capture_watch_del (rtems_name name, rtems_id id){  rtems_interrupt_level     level;  rtems_capture_control_t*  control;  rtems_capture_control_t** prev_control;  rtems_capture_task_t*     task;  rtems_boolean             found = 0;  /*   * Should this test be for wildcards ?   */  for (prev_control = &capture_controls, control = capture_controls;       control != NULL; )  {    if (rtems_capture_match_name_id (name, id, control->name, control->id))    {      rtems_interrupt_disable (level);            for (task = capture_tasks; task != NULL; task = task->next)        if (task->control == control)          task->control = 0;      *prev_control = control->next;      rtems_interrupt_enable (level);      _Workspace_Free (control);      control = *prev_control;      found = 1;    }    else    {      prev_control = &control->next;      control      = control->next;      }  }  if (found)    return RTEMS_SUCCESSFUL;  return RTEMS_INVALID_NAME;}/* * rtems_capture_watch_set * *  DESCRIPTION: * * This function allows control of a watch. The watch can be enabled or * disabled. */rtems_status_codertems_capture_watch_ctrl (rtems_name name, rtems_id id, rtems_boolean enable){  rtems_interrupt_level    level;  rtems_capture_control_t* control;  rtems_boolean            found = 0;    /*   * Find the control and then set the watch. It must exist before it can   * be controlled.   */  for (control = capture_controls; control != NULL; control = control->next)  {    if (rtems_capture_match_name_id (name, id, control->name, control->id))    {      rtems_interrupt_disable (level);      if (enable)        control->flags |= RTEMS_CAPTURE_WATCH;      else        control->flags &= ~RTEMS_CAPTURE_WATCH;      rtems_interrupt_enable (level);      found = 1;    }      }  if (found)    return RTEMS_SUCCESSFUL;  return RTEMS_INVALID_NAME;}/* * rtems_capture_watch_global * *  DESCRIPTION: * * This function allows control of a global watch. The watch can be enabled or * disabled. A global watch configures all tasks below the ceiling and above * the floor to be traced. */rtems_status_codertems_capture_watch_global (rtems_boolean enable){  rtems_interrupt_level level;    rtems_interrupt_disable (level);  /*   * We need to keep specific and global watches separate so   * a global enable/disable does not lose a specific watch.   */  if (enable)    capture_flags |= RTEMS_CAPTURE_GLOBAL_WATCH;  else    capture_flags &= ~RTEMS_CAPTURE_GLOBAL_WATCH;  rtems_interrupt_enable (level);  return RTEMS_SUCCESSFUL;}/* * rtems_capture_watch_global_on * *  DESCRIPTION: * * This function returns the global watch state. */rtems_booleanrtems_capture_watch_global_on (){  return capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH ? 1 : 0;}/* * rtems_capture_watch_ceiling * *  DESCRIPTION: * * This function sets a watch ceiling. Tasks at or greating that the * ceiling priority are not watched. This is a simple way to monitor * an application and exclude system tasks running at a higher * priority level. */rtems_status_codertems_capture_watch_ceiling (rtems_task_priority ceiling){  capture_ceiling = ceiling;  return RTEMS_SUCCESSFUL;}/* * rtems_capture_watch_get_ceiling * *  DESCRIPTION: * * This function gets the watch ceiling. */rtems_task_priorityrtems_capture_watch_get_ceiling (){  return capture_ceiling;}/* * rtems_capture_watch_floor * *  DESCRIPTION: * * This function sets a watch floor. Tasks at or less that the * floor priority are not watched. This is a simple way to monitor * an application and exclude system tasks running at a lower * priority level. */rtems_status_codertems_capture_watch_floor (rtems_task_priority floor){  capture_floor = floor;  return RTEMS_SUCCESSFUL;}/* * rtems_capture_watch_get_floor * *  DESCRIPTION: * * This function gets the watch floor. */rtems_task_priorityrtems_capture_watch_get_floor (){  return capture_floor;}/* * rtems_capture_set_trigger * *  DESCRIPTION: * * This function sets an edge trigger. Left is the left side of * the edge and right is right side of the edge. The trigger type * can be - * *  FROM_ANY : a switch from any task to the right side of the edge. *  TO_ANY   : a switch from the left side of the edge to any task. *  FROM_TO  : a switch from the left side of the edge to the right *             side of the edge. * * This set trigger routine will create a capture control for the * target task. The task list is searched and any existing tasks * are linked to the new control. * * We can have a number of tasks that have the same name so we * search using names. This means a number of tasks can be * linked to single control. */rtems_status_codertems_capture_set_trigger (rtems_name              from,                           rtems_id                from_id,                           rtems_name              to,                           rtems_id                to_id,                           rtems_capture_trigger_t trigger){  rtems_capture_control_t* control;  int                      i;    /*   * Find the capture control blocks for the from and to   * tasks.   */  if (trigger == rtems_capture_to_any)  {    control = rtems_capture_create_control (from, from_id);    if (control == NULL)      return RTEMS_NO_MEMORY;    control->flags |= RTEMS_CAPTURE_TO_ANY;  }  if ((trigger == rtems_capture_from_to) ||      (trigger == rtems_capture_from_any))  {    control = rtems_capture_create_control (to, to_id);    if (control == NULL)      return RTEMS_NO_MEMORY;        if (trigger == rtems_capture_from_any)      control->flags |= RTEMS_CAPTURE_FROM_ANY;    else    {      control->flags |= RTEMS_CAPTURE_FROM_TO;      for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)      {        if (control->from[i] == 0)        {          control->from[i]    = from;          control->from_id[i] = from_id;          break;        }      }    }  }  return RTEMS_SUCCESSFUL;}/* * rtems_capture_read * *  DESCRIPTION: * * This function reads a number of records from the capture buffer. * The user can optionally block and wait until the buffer as a * specific number of records available or a specific time has * elasped. * * The function returns the number of record that is has that are * in a continous block of memory. If the number of available records * wrap then only those records are provided. This removes the need for * caller to be concerned about buffer wrappings. If the number of * requested records cannot be met due to the wrapping of the records * less than the specified number will be returned. * * The user must release the records. This is achieved with a call to * rtems_capture_release. Calls this function without a release will * result in at least the same number of records being released. * * The 'threshold' parameter is the number of records that must be * captured before returning. If a timeout period is specified (non-0) * any captured records will be returned. These parameters stop * thrashing occuring for a small number of records, yet allows * a user configured latiency to be applied for single events. * * The 'timeout' parameter is in micro-seconds. A value of 0 will disable * the timeout. * */rtems_status_codertems_capture_read (rtems_unsigned32         threshold,                    rtems_unsigned32         timeout,                    rtems_unsigned32*        read,                    rtems_capture_record_t** recs){  rtems_interrupt_level level;  rtems_status_code     sc = RTEMS_SUCCESSFUL;  rtems_unsigned32      count;  *read = 0;  *recs = NULL;  rtems_interrupt_disable (level);  /*   * Only one reader is allowed.   */  if (capture_flags & RTEMS_CAPTURE_READER_ACTIVE)  {    rtems_interrupt_enable (level);    return RTEMS_RESOURCE_IN_USE;  }  capture_flags |= RTEMS_CAPTURE_READER_ACTIVE;  *read = count = capture_count;  rtems_interrupt_enable (level);  *recs = &capture_records[capture_out];  for (;;)  {    /*     * See if the count wraps the end of the record buffer.     */    if (count && ((capture_out + count) >= capture_size))      *read = capture_size - capture_out;          /*     * Do we have a threshold and the current count has not wrapped      * around the end of the capture record buffer ?      */    if ((*read == count) && threshold)    {      /*       * Do we have enough records ?       */      if (*read < threshold)      {        rtems_event_set event_out;        rtems_task_ident (RTEMS_SELF, RTEMS_LOCAL, &capture_reader);        rtems_interrupt_disable (level);                  capture_flags |= RTEMS_CAPTURE_READER_WAITING;        rtems_interrupt_enable (level);                  sc = rtems_event_receive (RTEMS_EVENT_0,                                  RTEMS_WAIT | RTEMS_EVENT_ANY,                                  TOD_MICROSECONDS_TO_TICKS (timeout),                                  &event_out);        /*         * Let the user handle all other sorts of errors. This may         * not be the best solution, but oh well, it will do for         * now.         */        if ((sc != RTEMS_SUCCESSFUL) && (sc != RTEMS_TIMEOUT))          break;        rtems_interrupt_disable (level);        *read = count = capture_count;        rtems_interrupt_enable (level);        continue;      }    }    /*     * Always out if we reach here. To loop use continue.     */    break;  }  rtems_interrupt_disable (level);  capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;  rtems_interrupt_enable (level);  return sc;}/* * rtems_capture_release * *  DESCRIPTION: * * This function releases the requested number of record slots back * to the capture engine. The count must match the number read. */rtems_status_codertems_capture_release (rtems_unsigned32 count){  rtems_interrupt_level level;  rtems_interrupt_disable (level);  if (count > capture_count)    count = capture_count;  capture_count -= count;  capture_out = (capture_count + count) % capture_size;  rtems_interrupt_enable (level);  return RTEMS_SUCCESSFUL;}/* * rtems_capture_tick_time * *  DESCRIPTION: * * This function returns the tick period in nano-seconds. */rtems_unsigned32rtems_capture_tick_time (){  return capture_tick_period;}/* * rtems_capture_event_text * *  DESCRIPTION: * * This function returns a string for an event based on the bit in the * event. The functions takes the bit offset as a number not the bit * set in a bit map. */const char*rtems_capture_event_text (int event){  if ((event < RTEMS_CAPTURE_EVENT_START) || (event > RTEMS_CAPTURE_EVENT_END))    return "invalid event id";  return capture_event_text[event - RTEMS_CAPTURE_EVENT_START];}/* * rtems_capture_get_task_list * *  DESCRIPTION: * * This function returns the head of the list of tasks that the * capture engine has detected. */rtems_capture_task_t*rtems_capture_get_task_list (){  return capture_tasks;}/* * rtems_capture_task_stack_usage * *  DESCRIPTION: * * This function updates the stack usage. The task control block * is updated. */rtems_unsigned32rtems_capture_task_stack_usage (rtems_capture_task_t* task){  if (task->tcb)  {    rtems_unsigned32* st;    rtems_unsigned32* s;    /*     * @todo: Assumes all stacks move the same way.     */    st = task->tcb->Start.Initial_stack.area + task->stack_size;    s  = task->tcb->Start.Initial_stack.area;    while (s < st)    {      if (*s != 0xdeaddead)        break;      s++;    }    task->stack_clean =      s - (rtems_unsigned32*) task->tcb->Start.Initial_stack.area;  }  return task->stack_clean;}/* * rtems_capture_get_control_list * *  DESCRIPTION: * * This function returns the head of the list of control in the * capture engine. */rtems_capture_control_t*rtems_capture_get_control_list (){  return capture_controls;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -