📄 capture.c
字号:
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 + -