📄 c-bkend4.html
字号:
<font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85698">Testing</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85700"> </a>The <i class="title">Back-End Developer's Kit</i> provides example test scripts which are located in <i class="textVariable">installDir</i><b class="file">/host/src/tgtsvr/backend/bedk/tests</b>. You can use these scripts as a basis for your own test scripts.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="85703">2.4.3 Getting Started</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85704"> </a>The first task is to get the basic skeleton of the back end operating. This means the target server should be able to start up, load the back-end DLL, and initialize, connect, and disconnect the back end.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85705">Creating a Framework</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85707"> </a>In order to create the skeleton back end, carry out the following steps:</p></dl><dl class="margin"><p class="listspace"><ul class="Bullet" type="disc"><li><a name="85708"> </a>Write <b class="file">acecpu32.cpp</b>, which contains the routine <b class="routine"><i class="routine">acecpu32Init</i></b><b>( )</b>. This file is the "main" of the back-end DLL.</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="85709"> </a>Declare your vendor-specific back-end class, <b>Ace_T</b>, writing stubs for the mandatory methods. This code belongs in the modules that implement the back end, <b class="file">acecpu32Backend.h</b> and <b class="file">acecpu32Backend.cpp</b>. The methods are not yet supported, but it is convenient to have them log a message to the console and return a value indicating that they were successfully invoked.</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="85710"> </a>Modify the example makefile to compile your back end.</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="85711"> </a>Use <b class="keyword">wtxtcl</b> to test that the skeleton back end loads, and that you can execute back-end methods.</li></ul></p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85712">Implementation</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85713"> </a>To implement the skeleton back end, write the "main" back-end module, <b class="file">acecpu32.cpp</b>, which initializes the back end by creating a vendor-specific back-end object, an instance of <b class="symbol_lc">Ace_T</b>. </p></dl></dl><dl class="margin"><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85714">Writing<b class="routine"><i class="routine"> acecpu32Initialize</i></b><b>( )</b></a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85716"> </a>First, create <b class="file">acecpu32.cpp</b> and define the routine <b class="routine"><i class="routine">acecpu32Initialize</i></b><b>( )</b>, which initializes the back end. Excerpts from <b class="file">acecpu32.cpp</b> are annotated throughout this section.</p><dd><p class="Body"><a name="85717"> </a>Tornado provides header files for the development of host tools in <i class="textVariable">installDir</i><b class="file">/host/include. </b>The first Tornado header file included must be <b class="file">host.h</b>. Declare the interface for the vendor-specific back end, <b>Ace_T</b>, by including <b class="file">acecpu32Backend.h</b> as shown:</p><dl class="margin"><dd><pre class="Code2"><b><a name="85718">/* acecpu32.cpp - back end for ACE's CPU32 BDM emulator */ ... /* includes */ #ifdef WIN32 /* fix clash between Wind River's ERROR and Microsoft's ERROR macros */ #ifdef ERROR #undef ERROR #endif #include <windows.h> #endif /* #ifdef WIN32 */ #include "host.h" #include "tgtlib.h" #include "wpwrutil.h" #include "windll.h" #include "acecpu32Backend.h"</a></b></pre></dl></dl></dl><dl class="margin"><dd><p class="table" callout><table border="0" cellpadding="0" cellspacing="0"><tr valign="top"><td valign="top" width="40"><br><img border="0" alt="*" src="icons/note.gif"></td><td><hr><div class="CalloutCell"><a name="89336"><b class="symbol_UC"><font face="Helvetica, sans-serif" size="-1" class="sans">NOTE: </font></b></a>Always include <b class="file">windows.h</b> first to avoid clashes with Wind River definitions. Do not use <b class="symbol_UC">ERROR</b>, which Microsoft defines to be (0); always undefine <b class="symbol_UC">ERROR</b>, include system header files next, and include Wind River header files last.</div></td></tr><tr valign="top"><td></td><td><hr></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p callout><dl class="margin"><dd><p class="Body"><a name="85745"> </a>Next, define the back-end initialization routine, <b class="routine"><i class="routine">acecpu32Initialize</i></b><b>( )</b>. For a complete discussion, see <a href="c-bkend2.html#84567"><i class="title">2.2.1 Attachment and Initialization</i></a>. </p><dd><p class="Body"><a name="85749"> </a>The back end must initialize the <b class="symbol_UC">TGT_OPS</b> and <b class="symbol_UC">BKEND_INFO</b> structures with the information needed by the target server to operate the back end; in particular, the addresses of the back-end methods must be stored in <b class="symbol_UC">TGT_OPS</b> and the asynchronous notification method must be stored in <b class="symbol_UC">BKEND_INFO</b>. In order for the target server, which is a C application, to call the back-end methods, the <b class="symbol_lc">Backend_T</b> class uses static member functions to provide an interface that supports C calling conventions; these static functions then invoke normal member functions on the actual back end. For more information on the static wrapper and <b class="symbol_lc">Backend_T</b> architecture, see the documentation in provided in <i class="textVariable">installDir</i><b class="file">/host/src/tgtsvr/backend/bedk/backend.h</b>.</p><dl class="margin"><dd><pre class="Code2"><b><a name="89181">STATUS acecpu32Initialize ( char * tgtName, /* network unique target name to connect */ TGT_OPS * pTgtOps /* vector of back end functions to fill */ BKEND_INFO * pBkendInfo /* Backend notification method */ )</a></b></pre></dl></dl><dd><p class="table" callout><table border="0" cellpadding="0" cellspacing="0"><tr valign="top"><td valign="top" width="40"><br><img border="0" alt="*" src="icons/note.gif"></td><td><hr><div class="CalloutCell"><a name="89352"><b class="symbol_UC"><font face="Helvetica, sans-serif" size="-1" class="sans">NOTE: </font></b></a>For Windows hosts, it is important to use default calling conventions and not <b class="symbol_UC">WINAPI</b>.</div></td></tr><tr valign="top"><td></td><td><hr></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p callout><dl class="margin"><dd><p class="Body"><a name="85771"> </a>The final step is to allocate the actual back end by calling <b>new</b> and to perform error logging. The constructor of <b class="symbol_lc">Backend_T</b>, the back-end abstract base class, will initialize the back-end function pointers in the <b class="symbol_UC">TGT_OPS</b> structure. <b class="symbol_lc">Ace_T</b>'s constructor initializes the back-end-specific part of the <b class="symbol_UC">TGT_OPS</b> structure. </p><dd><p class="Body"><a name="85772"> </a>The initialization routine must return <b class="symbol_UC">OK</b> on success or <b class="symbol_UC">ERROR </b>on failure, as defined in <b class="file">host.h</b>. The Tornado' <b class="library">wpwrutil</b> library provides several functions for error logging, including the function <b class="symbol_UC">WPWR_LOG_MSG</b> used in our example. Message logging is enabled by starting the target server with the option <b class="symbol_lc">-V</b>. For more information on the <b class="library">wpwrutil</b> library, see the online reference material under <b class="guiLabel"><font face="Helvetica, sans-serif" size="-1" class="sans">Tornado API Reference>Target Server Back End Interface</font></b>.</p><dl class="margin"><dd><pre class="Code2"><b><a name="85779">// Create Backend pTheBkEnd = new Ace_T (tgtName, timeout, recallNum, pTtyDevName, baudRate, pTgtOps); if (pTheBkEnd == NULL) { WPWR_LOG_MSG ("acecpu32Init(): new() failed.\n"); return (ERROR); } if (! pTheBkEnd->isValid_m()) { WPWR_LOG_MSG ("acecpu32Init(): back end initialization failed.\n") return (ERROR); } return (OK); }</a></b></pre></dl></dl><dd><p class="table" callout><table border="0" cellpadding="0" cellspacing="0"><tr valign="top"><td valign="top" width="40"><br><img border="0" alt="*" src="icons/note.gif"></td><td><hr><div class="CalloutCell"><a name="89368"><b class="symbol_UC"><font face="Helvetica, sans-serif" size="-1" class="sans">NOTE: </font></b></a>Constructors can fail, but most compilers lack exception support. For this reason, the <b>Backend_T</b> class provides a pair of protected members. <b class="routine"><i class="routine">Backend_T::isNotValid_m</i></b><b>( )</b> should be called if vendor-specific constructors fail. Call <b class="routine"><i class="routine">Backend_T::isValid_m</i></b><b>( )</b> to see if the back end has been successfully initialized.</div></td></tr><tr valign="top"><td></td><td><hr></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p callout><dl class="margin"><dd><p class="Body"><a name="85806"> </a>Add any other routines to <b class="file">acecpu32.cpp</b><b class="routine"><i class="routine"> </i></b>that are needed to support the initialization of the back end.</p></dl></dl><dl class="margin"><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85809">Declaring the Vendor-Specific Back-End Class Skeleton</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85811"> </a>Next, declare the skeleton of the vendor-specific back-end class, <b class="symbol_lc">Ace_T</b>. Derive <b class="symbol_lc">Ace_T</b> from <b class="symbol_lc">Backend_T</b> and declare all the mandatory methods in <b class="file">acecpu32Backend.h</b>. The examples in this section show the declaration of the <b class="symbol_lc">Ace_T</b> class in <b class="file">acecpu32Backend.h</b>. </p><dd><p class="Body"><a name="85812"> </a>After the usual preamble of comments and modification history, give the header file the standard macro <b>#ifndef/#define</b> construction to prevent multiple inclusions of the header file. Next, provide the<b> </b><b>#include</b> statements for the other necessary header files. </p><dl class="margin"><dd><pre class="Code2"><b><a name="85813">/* acecpu32Backend.h - header file for ACE SuperBDM BDM back end */ ... #ifndef __INCacecpu32Backendh #define __INCacecpu32Backendh /* includes */</a></b></pre></dl><dd><p class="Body"><a name="85819"> </a>First, include the Rogue Wave header file.</p><dl class="margin">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -