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

📄 capture.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
  ct = current_task->extensions[capture_extension_index];  rt = restarted_task->extensions[capture_extension_index];  /*   * The task ponters may not be known as the task may have   * been created before the capture engine was open. Add them.   */  if (ct == NULL)    ct = rtems_capture_create_capture_task (current_task);  if (rt == NULL)    rt = rtems_capture_create_capture_task (restarted_task);  rtems_capture_record (ct, RTEMS_CAPTURE_RESTARTED_BY_EVENT);  rtems_capture_record (rt, RTEMS_CAPTURE_RESTARTED_EVENT);  rtems_capture_task_stack_usage (rt);  rtems_capture_init_stack_usage (rt);}/* * rtems_capture_delete_task * *  DESCRIPTION: * * This function is called when a task is deleted. * */static rtems_extensionrtems_capture_delete_task (rtems_tcb* current_task,                           rtems_tcb* deleted_task){  /*   * Get the capture task control block so we can trace this   * event.   */  rtems_capture_task_t* ct;  rtems_capture_task_t* dt;  /*   * The task ponters may not be known as the task may have   * been created before the capture engine was open. Add them.   */  ct = current_task->extensions[capture_extension_index];  dt = deleted_task->extensions[capture_extension_index];  if (ct == NULL)    ct = rtems_capture_create_capture_task (current_task);  if (dt == NULL)    dt = rtems_capture_create_capture_task (deleted_task);  rtems_capture_record (ct, RTEMS_CAPTURE_DELETED_BY_EVENT);  rtems_capture_record (dt, RTEMS_CAPTURE_DELETED_EVENT);  rtems_capture_task_stack_usage (dt);  /*   * This task's tcb will be invalid.   */  dt->tcb = 0;}/* * rtems_capture_begin_task * *  DESCRIPTION: * * This function is called when a task is begun. * */static rtems_extensionrtems_capture_begin_task (rtems_tcb* begin_task){  /*   * Get the capture task control block so we can trace this   * event.   */  rtems_capture_task_t* bt;  bt = begin_task->extensions[capture_extension_index];  /*   * The task ponters may not be known as the task may have   * been created before the capture engine was open. Add them.   */  if (bt == NULL)    bt = rtems_capture_create_capture_task (begin_task);  rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);}/* * rtems_capture_exitted_task * *  DESCRIPTION: * * This function is called when a task is exitted. That is * returned rather than was deleted. * */static rtems_extensionrtems_capture_exitted_task (rtems_tcb* exitted_task){  /*   * Get the capture task control block so we can trace this   * event.   */  rtems_capture_task_t* et;  et = exitted_task->extensions[capture_extension_index];  /*   * The task ponters may not be known as the task may have   * been created before the capture engine was open. Add them.   */  if (et == NULL)    et = rtems_capture_create_capture_task (exitted_task);  rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT);  rtems_capture_task_stack_usage (et);}/* * rtems_capture_switch_task * *  DESCRIPTION: * * This function is called when a context is switched. * */static rtems_extensionrtems_capture_switch_task (rtems_tcb* current_task,                           rtems_tcb* heir_task){  /*   * Only perform context switch trace processing if tracing is   * enabled.   */  if (capture_flags & RTEMS_CAPTURE_ON)  {    rtems_unsigned32 ticks;    rtems_unsigned32 tick_offset;          /*     * Get the cpature task control block so we can update the     * reference anbd perform any watch or trigger functions.     * The task ponters may not be known as the task may have     * been created before the capture engine was open. Add them.     */    rtems_capture_task_t* ct;    rtems_capture_task_t* ht;    if (_States_Is_transient (current_task->current_state))    {      rtems_id ct_id = current_task->Object.id;      for (ct = capture_tasks; ct; ct = ct->next)        if (ct->id == ct_id)          break;    }    else    {      ct = current_task->extensions[capture_extension_index];      if (ct == NULL)        ct = rtems_capture_create_capture_task (current_task);    }    ht = heir_task->extensions[capture_extension_index];    if (ht == NULL)      ht = rtems_capture_create_capture_task (heir_task);    /*     * Update the execution time. Assume the tick will not overflow     * for now. This may need to change.     */    rtems_capture_get_time (&ticks, &tick_offset);    /*     * We could end up with null pointers for both the current task     * and the heir task.     */    if (ht)    {      ht->in++;      ht->ticks_in       = ticks;      ht->tick_offset_in = tick_offset;    }     if (ct)    {      ct->out++;      ct->ticks += ticks - ct->ticks_in;      if (capture_timestamp)      {        tick_offset += capture_tick_period - ct->tick_offset_in;         if (tick_offset < capture_tick_period)          ct->tick_offset = tick_offset;        else        {          ct->ticks++;          ct->tick_offset = tick_offset - capture_tick_period;        }      }      else      {        ct->tick_offset += 100;      }    }    /*     * If we have not triggered then see if this is a trigger condition.     */    if (!(capture_flags & RTEMS_CAPTURE_TRIGGERED))    {      rtems_capture_control_t* cc = NULL;      rtems_capture_control_t* hc = NULL;      if (ct)      {        cc = ct->control;              /*         * Check the current task for a TO_ANY trigger.         */        if (cc && (cc->flags & RTEMS_CAPTURE_TO_ANY))        {          capture_flags |= RTEMS_CAPTURE_TRIGGERED;          goto triggered;        }      }      if (ht)      {        hc = ht->control;        /*         * Check the next task for a FROM_ANY.         */        if (hc && (hc->flags & RTEMS_CAPTURE_FROM_ANY))        {          capture_flags |= RTEMS_CAPTURE_TRIGGERED;          goto triggered;        }      }      /*       * Check is the trigger is from the current task       * to the next task.       */      if (cc && hc && (hc->flags & RTEMS_CAPTURE_FROM_TO))        if (rtems_capture_name_in_group (cc->name, hc->from))        {          capture_flags |= RTEMS_CAPTURE_TRIGGERED;          goto triggered;        }    }    else    {triggered:      rtems_capture_record (ct, RTEMS_CAPTURE_SWITCHED_OUT_EVENT);      rtems_capture_record (ht, RTEMS_CAPTURE_SWITCHED_IN_EVENT);    }  }}/* * rtems_capture_open * *  DESCRIPTION: * * This function initialises the realtime capture engine allocating the trace * buffer. It is assumed we have a working heap at stage of initialisation. * */rtems_status_codertems_capture_open (rtems_unsigned32 size, rtems_capture_timestamp timestamp){  rtems_extensions_table capture_extensions;  rtems_name             name;  rtems_status_code      sc;  /*   * See if the capture engine is already open.   */  if (capture_records)    return RTEMS_RESOURCE_IN_USE;  capture_records = malloc (size * sizeof (rtems_capture_record_t));  if (capture_records == NULL)    return RTEMS_NO_MEMORY;  capture_size    = size;  capture_count   = 0;  capture_in      = capture_records;  capture_out     = 0;  capture_flags   = 0;  capture_tasks   = NULL;  capture_ceiling = 0;  capture_floor   = 255;  /*   * Create the extension table. This is copied so we   * can create it as a local.   */  capture_extensions.thread_create  = rtems_capture_create_task;  capture_extensions.thread_start   = rtems_capture_start_task;  capture_extensions.thread_restart = rtems_capture_restart_task;  capture_extensions.thread_delete  = rtems_capture_delete_task;  capture_extensions.thread_switch  = rtems_capture_switch_task;  capture_extensions.thread_begin   = rtems_capture_begin_task;  capture_extensions.thread_exitted = rtems_capture_exitted_task;  capture_extensions.fatal          = NULL;  /*   * Get the tick period from the BSP Configuration Table.   */  capture_tick_period = _Configuration_Table->microseconds_per_tick;    /*   * Register the user extension handlers for the CAPture Engine.   */  name = rtems_build_name ('C', 'A', 'P', 'E');  sc   = rtems_extension_create (name, &capture_extensions, &capture_id);  if (sc != RTEMS_SUCCESSFUL)  {    capture_id = 0;    free (capture_records);    capture_records = NULL;  }  else  {    capture_extension_index = rtems_get_index (capture_id);;  }  /*   * Iterate over the list of existing tasks.   */  return sc;}/* * rtems_capture_close * *  DESCRIPTION: * * This function shutdowns the capture engine and release any claimed * resources. */rtems_status_codertems_capture_close (){  rtems_interrupt_level    level;  rtems_capture_task_t*    task;  rtems_capture_control_t* control;  rtems_capture_record_t*  records;  rtems_status_code        sc;  rtems_interrupt_disable (level);  if (!capture_records)  {    rtems_interrupt_enable (level);    return RTEMS_SUCCESSFUL;  }  capture_flags &= ~RTEMS_CAPTURE_ON;  records = capture_records;  capture_records = NULL;  rtems_interrupt_enable (level);  /*   * Delete the extension first. This means we are now able to   * release the resources we have without them being used.   */  sc = rtems_extension_delete (capture_id);  if (sc != RTEMS_SUCCESSFUL)    return sc;  task = capture_tasks;    while (task)  {    rtems_capture_task_t* delete = task;    task = task->next;    _Workspace_Free (delete);  }  capture_tasks = NULL;  control = capture_controls;    while (control)  {    rtems_capture_control_t* delete = control;    control = control->next;    _Workspace_Free (delete);  }  capture_controls = NULL;  if (capture_records)  {    free (capture_records);    capture_records = NULL;  }  return RTEMS_SUCCESSFUL;}/* * rtems_capture_control * *  DESCRIPTION: * * This function allows control of tracing at a global level. */rtems_status_codertems_capture_control (rtems_boolean enable){  rtems_interrupt_level level;  rtems_interrupt_disable (level);  if (!capture_records)  {    rtems_interrupt_enable (level);    return RTEMS_UNSATISFIED;  }  if (enable)    capture_flags |= RTEMS_CAPTURE_ON;  else    capture_flags &= ~RTEMS_CAPTURE_ON;  rtems_interrupt_enable (level);  return RTEMS_SUCCESSFUL;}/* * rtems_capture_flush * *  DESCRIPTION: * * This function flushes the capture buffer. The prime parameter allows the * capture engine to also be primed again. */rtems_status_codertems_capture_flush (rtems_boolean prime){  rtems_interrupt_level level;  rtems_capture_task_t* task;  rtems_interrupt_disable (level);  for (task = capture_tasks; task != NULL; task = task->next)    task->flags &= ~RTEMS_CAPTURE_TRACED;  if (prime)    capture_flags &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);  else    capture_flags &= ~RTEMS_CAPTURE_OVERFLOW;  capture_in     = capture_records;  capture_out    = 0;  rtems_interrupt_enable (level);   return RTEMS_SUCCESSFUL;}/* * rtems_capture_watch_add * *  DESCRIPTION: * * This function defines a watch for a specific task given a name. A watch * causes it to be traced either in or out of context. The watch can be * optionally enabled or disabled with the set routine. It is disabled by * default. */rtems_status_codertems_capture_watch_add (rtems_name name, rtems_id id){  rtems_capture_control_t* control;  if ((name == 0) && (id == 0))    return RTEMS_UNSATISFIED;  control = rtems_capture_find_control (name, id);  if (control && !id)    return RTEMS_TOO_MANY;  if (!control)    control = rtems_capture_create_control (name, id);  if (!control)    return RTEMS_NO_MEMORY;  return RTEMS_SUCCESSFUL;}

⌨️ 快捷键说明

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