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

📄 programming-concepts-techniques.sgml

📁 开放源码实时操作系统源码.
💻 SGML
📖 第 1 页 / 共 3 页
字号:
  
<CHAPTER id="debugging-techniques">
<TITLE>Debugging Techniques</TITLE>
<PARA><productname>eCos</productname> applications and components can be debugged in
	traditional ways, with printing statements and debugger
	single-stepping, but there are situations in which these
	techniques cannot be used. One example of this is when a
	program is getting data at a high rate from a real-time
	source, and cannot be slowed down or interrupted.</PARA>
<PARA><productname>eCos</productname>&rsquo;s infrastructure module provides a
	<EMPHASIS>tracing</EMPHASIS> formalism, allowing the
	kernel&rsquo;s tracing macros to be configured in many useful
	ways. <productname>eCos</productname>&rsquo;s kernel provides <FIRSTTERM>instrumentation
	  buffers</FIRSTTERM> which also collect specific
	(configurable) data about the system&rsquo;s history and
	performance.</PARA>
<SECT1 id="tracing">
<TITLE>Tracing</TITLE>
<PARA>To use <productname>eCos</productname>&rsquo;s tracing facilities you must first
	  configure your system to use <FIRSTTERM>tracing</FIRSTTERM>.
	  You should enable the Asserts and Tracing component
	  (<OPTION>CYGPKG_INFRA_DEBUG</OPTION>) and the
	  <OPTION>Use tracing</OPTION> component within it
	  (<OPTION>CYGDBG_USE_TRACING</OPTION>). These
	  options can be enabled with the <APPLICATION>Configuration
	    Tool</APPLICATION> or by editing the file
	  <FILENAME><REPLACEABLE>BUILD_DIR</REPLACEABLE>/pkgconf/infra.h 
	  </FILENAME> manually.</PARA>
<PARA>You should then examine all the tracing-related options in
the <citetitle>Package: Infrastructure</citetitle> chapter of the <citetitle><PRODUCTNAME>eCos</PRODUCTNAME> Reference
Manual</citetitle>. One useful set of configuration options are: <literal>CYGDBG_INFRA_DEBUG_FUNCTION_REPORTS</literal> and <literal>CYGDBG_INFRA_DEBUG_TRACE_MESSAGE</literal>,
which are both enabled by default when tracing is enabled.</PARA>
<PARA>The following &ldquo;Hello world with tracing&rdquo; shows
the output from running the hello world program (from <xref linkend="ecos-hello-world">) that was
built with tracing enabled: </PARA>
<EXAMPLE>
<TITLE>Hello world with tracing</TITLE>
<SCREEN>$ mips-tx39-elf-run --board=jmr3904  hello
Hello, eCos world!
ASSERT FAIL: &lt;2&gt;cyg_trac.h          [ 623] Cyg_TraceFunction_Report_::set_exitvoid()                                                            exitvoid used in typed function
TRACE: &lt;1&gt;mlqueue.cxx         [ 395] Cyg_ThreadQueue_Implementation::enqueue()                                                            {{enter
TRACE: &lt;1&gt;mlqueue.cxx         [ 395] Cyg_ThreadQueue_Implementation::enqueue()                                                            }}RETURNING UNSET!
TRACE: &lt;1&gt;mlqueue.cxx         [ 126] Cyg_Scheduler_Implementation::add_thread()                                                           }}RETURNING UNSET!
TRACE: &lt;1&gt;thread.cxx          [ 654] Cyg_Thread::resume()                                                                                 }}return void
TRACE: &lt;1&gt;cstartup.cxx        [ 160] cyg_iso_c_start()                                                                                    }}return void
TRACE: &lt;1&gt;startup.cxx         [ 142] cyg_package_start()                                                                                  }}return void
TRACE: &lt;1&gt;startup.cxx         [ 150] cyg_user_start()                                                                                     {{enter
TRACE: &lt;1&gt;startup.cxx         [ 150] cyg_user_start()                                                                                     (((void)))
TRACE: &lt;1&gt;startup.cxx         [ 153] cyg_user_start()                                                                                     'This is the system default cyg_user_start()'
TRACE: &lt;1&gt;startup.cxx         [ 157] cyg_user_start()                                                                                     }}return void
TRACE: &lt;1&gt;sched.cxx           [ 212] Cyg_Scheduler::start()                                                                               {{enter
TRACE: &lt;1&gt;mlqueue.cxx         [ 102] Cyg_Scheduler_Implementation::schedule()                                                             {{enter
TRACE: &lt;1&gt;mlqueue.cxx         [ 437] Cyg_ThreadQueue_Implementation::highpri()                                                            {{enter
TRACE: &lt;1&gt;mlqueue.cxx         [ 437] Cyg_ThreadQueue_Implementation::highpri()                                                            }}RETURNING UNSET!
TRACE: &lt;1&gt;mlqueue.cxx         [ 102] Cyg_Scheduler_Implementation::schedule()                                                             }}RETURNING UNSET!
TRACE: &lt;2&gt;intr.cxx            [ 450] Cyg_Interrupt::enable_interrupts()                                                                   {{enter
TRACE: &lt;2&gt;intr.cxx            [ 450] Cyg_Interrupt::enable_interrupts()                                                                   }}RETURNING UNSET!
TRACE: &lt;2&gt;thread.cxx          [  69] Cyg_HardwareThread::thread_entry()                                                                   {{enter
TRACE: &lt;2&gt;cstartup.cxx        [ 127] invoke_main()                                                                                        {{enter
TRACE: &lt;2&gt;cstartup.cxx        [ 127] invoke_main()                                                                                        ((argument is ignored))
TRACE: &lt;2&gt;dummyxxmain.cxx     [  60] __main()                                                                                             {{enter
TRACE: &lt;2&gt;dummyxxmain.cxx     [  60] __main()                                                                                             (((void)))
TRACE: &lt;2&gt;dummyxxmain.cxx     [  63] __main()                                                                                             'This is the system default __main()'
TRACE: &lt;2&gt;dummyxxmain.cxx     [  67] __main()                                                                                             }}return void
TRACE: &lt;2&gt;memcpy.c            [ 112] _memcpy()                                                                                            {{enter
TRACE: &lt;2&gt;memcpy.c            [ 112] _memcpy()                                                                                            ((dst=80002804, src=BFC14E58, n=19))
TRACE: &lt;2&gt;memcpy.c            [ 164] _memcpy()                                                                                            }}returning 80002804
TRACE: &lt;2&gt;cstartup.cxx        [ 137] invoke_main()                                                                                        'main() has returned with code 0. Calling exit()'
TRACE: &lt;2&gt;exit.cxx            [  71] __libc_exit()                                                                                        {{enter
TRACE: &lt;2&gt;exit.cxx            [  71] __libc_exit()                                                                                        ((status=0 ))
TRACE: &lt;2&gt;atexit.cxx          [  84] cyg_libc_invoke_atexit_handlers()                                                                    {{enter
TRACE: &lt;2&gt;atexit.cxx          [  84] cyg_libc_invoke_atexit_handlers()                                                                      (((void)))

Scheduler:

Lock:                0
Current Thread:      &lt;null&gt;

Threads:

Idle Thread          pri =  31 state = R      id =   1
                     stack base = 800021F0 ptr = 80002510 size = 00000400
                     sleep reason NONE     wake reason NONE    
                     queue = 80000C54      wait info = 00000000

&lt;null&gt;               pri =   0 state = R      id =   2
                     stack base = 80002A48 ptr = 8000A968 size = 00008000
                     sleep reason NONE     wake reason NONE    
                     queue = 80000BD8      wait info = 00000000
	  </SCREEN>
</EXAMPLE>
</SECT1>
<SECT1 id="kernel-instrumentation">
<TITLE>Kernel Instrumentation</TITLE>
<PARA><FIRSTTERM>Instrument buffers</FIRSTTERM> can be used to
	  find out how many events of a given type happened in the
	  kernel during execution of a program.</PARA>
<PARA>You can monitor a class of several types of events, or
	  you can just look at individual events. </PARA>
<PARA>Examples of <FIRSTTERM>events</FIRSTTERM> that can be
	  monitored are:
	</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>scheduler events </PARA>
</LISTITEM>
<LISTITEM>
<PARA>thread operations</PARA>
</LISTITEM>
<LISTITEM>
<PARA>interrupts </PARA>
</LISTITEM>
<LISTITEM>
<PARA>mutex operations </PARA>
</LISTITEM>
<LISTITEM>
<PARA>binary semaphore operations </PARA>
</LISTITEM>
<LISTITEM>
<PARA>counting semaphore operations </PARA>
</LISTITEM>
<LISTITEM>
<PARA>clock ticks and interrupts </PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>Examples of fine-grained scheduler event types are: </PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>scheduler lock</PARA>
</LISTITEM>
<LISTITEM>
<PARA>scheduler unlock</PARA>
</LISTITEM>
<LISTITEM>
<PARA>rescheduling</PARA>
</LISTITEM>
<LISTITEM>
<PARA>time slicing </PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>Information about the events is stored in an
	  <FIRSTTERM>event record</FIRSTTERM>. The structure that
	  defines this record has type <type>struct
	  Instrument_Record</type>:
</PARA>
<PARA>The list of records is stored in an array called <TYPE>instrument_buffer</TYPE>
which you can let the kernel provide or you can provide yourself
by setting the configuration option <literal>CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER</literal>. </PARA>
<PARA>To write a program that examines the instrumentation
	  buffers: </PARA>
<ORDEREDLIST>
<LISTITEM>
<PARA>Enable instrumentation buffers in the <productname>eCos</productname> kernel configuration.
The component macro is <literal>CYGPKG_KERNEL_INSTRUMENT</literal>.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>To allocate the buffers yourself, enable the configuration
option <literal>CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER</literal>. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>Include the header file 
<FILENAME>cyg/kernel/instrmnt.h</FILENAME>
. 
<PROGRAMLISTING>#include &lt;cyg/kernel/instrmnt.h&gt;</PROGRAMLISTING></PARA>
</LISTITEM>
<LISTITEM>
<PARA>The <STRUCTNAME>Instrumentation_Record</STRUCTNAME> structure
is not published in the kernel header file. In the future there
will be a cleaner mechanism to access it, but for now you should
paste into your code in the following lines: 
	    </para>
<PROGRAMLISTING>struct Instrument_Record
{
 CYG_WORD16 type; // record type
 CYG_WORD16 thread; // current thread id
 CYG_WORD timestamp; // 32 bit timestamp
 CYG_WORD arg1; // first arg
 CYG_WORD arg2; // second arg
};</PROGRAMLISTING>
</LISTITEM>
<LISTITEM>
<PARA>Enable the events you want to record using 
<FUNCTION>cyg_instrument_enable()</FUNCTION>
, and disable them later. Look at 
<filename>cyg/kernel/instrmnt.h</filename>
 and the examples below to see what events can be enabled. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>Place the code you want to debug between the matching
functions  
<FUNCTION>cyg_instrument_enable()</FUNCTION>
 and 
<FUNCTION>cyg_instrument_disable()</FUNCTION>
. </PARA>
</LISTITEM>
<LISTITEM>
<PARA>Examine the buffer. For now you need to look at the data
in there (the example program below shows how to do that), and future
versions of <productname>eCos</productname> will include a host-side tool to help you understand
the data. </PARA>
</LISTITEM>
</ORDEREDLIST>
<EXAMPLE>
<TITLE>Using instrument buffers</TITLE>
<PARA>This program is also provided in the
	    <FILENAME>examples</FILENAME> directory.
	  </PARA>
<PROGRAMLISTING>
/* this is a program which uses <productname>eCos</productname> instrumentation buffers; it needs
 to be linked with a kernel which was compiled with support for
 instrumentation */

#include &lt;stdio.h&gt;
#include &lt;pkgconf/kernel.h&gt;
#include &lt;cyg/kernel/instrmnt.h&gt;
#include &lt;cyg/kernel/kapi.h&gt;

#ifndef CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
# error You must configure eCos with CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
#endif

struct Instrument_Record
{
 CYG_WORD16 type; // record type
 CYG_WORD16 thread; // current thread id
 CYG_WORD timestamp; // 32 bit timestamp
 CYG_WORD arg1; // first arg
 CYG_WORD arg2; // second arg
};

struct Instrument_Record instrument_buffer[20];
cyg_uint32 instrument_buffer_size = 20;

int main(void)
{
 int i;

 cyg_instrument_enable(CYG_INSTRUMENT_CLASS_CLOCK, 0);
 cyg_instrument_enable(CYG_INSTRUMENT_CLASS_THREAD, 0);
 cyg_instrument_enable(CYG_INSTRUMENT_CLASS_ALARM, 0);

 printf("Program to play with instrumentation buffer\n");

 cyg_thread_delay(2);

 cyg_instrument_disable(CYG_INSTRUMENT_CLASS_CLOCK, 0);
 cyg_instrument_disable(CYG_INSTRUMENT_CLASS_THREAD, 0);
 cyg_instrument_disable(CYG_INSTRUMENT_CLASS_ALARM, 0);

 for (i = 0; i &lt; instrument_buffer_size; ++i) {
 printf("Record %02d: type 0x%04x, thread %d, ",
	i, instrument_buffer[i].type, instrument_buffer[i].thread);
 printf("time %5d, arg1 0x%08x, arg2 0x%08x\n",
	instrument_buffer[i].timestamp, instrument_buffer[i].arg1,
	instrument_buffer[i].arg2);
 }
 return 0;
}</PROGRAMLISTING>
</EXAMPLE>
<PARA>Here is how you could compile and run this program in the <filename>examples</filename> directory,
using (for example) the MN10300 simulator target: </PARA>
<SCREEN>
$ make XCC=mn10300-elf-gcc INSTALL_DIR=/tmp/ecos-work-mn10300/install instrument-test
mn10300-elf-gcc -c -o instrument-test.o -g -Wall -I/tmp/ecos-work-mn10300/install/include \
        -ffunction-sections -fdata-sections instrument-test.c
mn10300-elf-gcc -nostartfiles -L/tmp/ecos-work-mn10300/install/lib -W1,--gc-sections -o \
        instrument-test instrument-test.o -Ttarget.ld -nostdlib
$ mn10300-elf-run --board=stdeval1 instrument-test
</SCREEN>
<EXAMPLE>
<TITLE>Instrument buffer output</TITLE>
<PARA>Here is the output of the
	    <COMMAND>instrument-test</COMMAND> program. Notice that in
	    little over 2 seconds, and with very little activity, and
	    with few event types enabled, it gathered 17 records. In
	    larger programs it will be necessary to select very few
	    event types for debugging. </PARA>
<PROGRAMLISTING>Program to play with instrumentation buffer
Record 00: type 0x0207, thread 2, time  6057, arg1 0x48001cd8, arg2 0x00000002
Record 01: type 0x0202, thread 2, time  6153, arg1 0x48001cd8, arg2 0x00000000
Record 02: type 0x0904, thread 2, time  6358, arg1 0x48001d24, arg2 0x00000000
Record 03: type 0x0905, thread 2, time  6424, arg1 0x00000002, arg2 0x00000000
Record 04: type 0x0906, thread 2, time  6490, arg1 0x00000000, arg2 0x00000000
Record 05: type 0x0901, thread 2, time  6608, arg1 0x48009d74, arg2 0x48001d24
Record 06: type 0x0201, thread 2, time  6804, arg1 0x48001cd8, arg2 0x480013e0
Record 07: type 0x0803, thread 1, time    94, arg1 0x00000000, arg2 0x00000000
Record 08: type 0x0801, thread 1, time   361, arg1 0x00000000, arg2 0x00000000
Record 09: type 0x0802, thread 1, time   548, arg1 0x00000001, arg2 0x00000000
Record 10: type 0x0803, thread 1, time    94, arg1 0x00000000, arg2 0x00000000
Record 11: type 0x0801, thread 1, time   361, arg1 0x00000001, arg2 0x00000000
Record 12: type 0x0903, thread 1, time   513, arg1 0x48009d74, arg2 0x48001d24
Record 13: type 0x0208, thread 1, time   588, arg1 0x00000000, arg2 0x00000000
Record 14: type 0x0203, thread 1, time   697, arg1 0x48001cd8, arg2 0x480013e0
Record 15: type 0x0802, thread 1, time   946, arg1 0x00000002, arg2 0x00000000
Record 16: type 0x0201, thread 1, time  1083, arg1 0x480013e0, arg2 0x48001cd8
Record 17: type 0x0000, thread 0, time     0, arg1 0x00000000, arg2 0x00000000
Record 18: type 0x0000, thread 0, time     0, arg1 0x00000000, arg2 0x00000000
Record 19: type 0x0000, thread 0, time     0, arg1 0x00000000, arg2 0x00000000</PROGRAMLISTING>
</EXAMPLE>
</SECT1>
</CHAPTER>
</PART>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-namecase-general:t
sgml-general-insert-case:lower
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:("user-guide.sgml" "book" "part")
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

⌨️ 快捷键说明

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