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

📄 c-bkend3.html

📁 vxworks相关论文
💻 HTML
📖 第 1 页 / 共 3 页
字号:
wdbReplyWrapper.errCode&nbsp;&nbsp;&nbsp;&nbsp;= OK; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* just to clear this field&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ ... clntStatus = clnt_call (pWdbClnt, procNum, xdr_WDB_PARAM_WRAPPER, &amp;wdbParamWrapper, xdr_WDB_REPLY_WRAPPER, &amp;wdbReplyWrapper, timeout); check (clntStatus)     {     if (RPC_TIMEDOUT or RPC_CANTDECODERES or RPC_CANTDECODEARGS)         try again     if (RPC_SYSTEMERROR)         if we were previously connected, then target must have rebooted so resync             and reconnect.     if (RPC_PROCUNAVAIL)         procedure not configured into agent. Try to rebuild the agent with that             facility included (e.g., virtual I/O is an optional agent facility).     if (RPC_SUCCESS)         agent tried to execute the routine.          check high order bit of wdbReplyWrapper.errCode to see if events are              pending on the target. If so, execute a WDB_EVENT_GET request after             finishing processing this reply.          mask off the high order bit of wdbReplyWrapper.errCode.         if (wdbReplyWrapper.errCode == 0)             success! In this case wdbReplyWrapper.xdr decoded the reply and put                 it in wdbReplyWrapper.pReply.         else             wdbReplyWrapper.errCode contains the reason for procedure failure.             The error codes are defined in wdb.h.     }</a></b></pre></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85103">Asynchronous Notification Sent By the Agent</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85105"> </a>Asynchronous events can be generated on the target. These include exceptions, breakpoints, and task exiting. These events are queued on the target until the host uploads them with the <b class="symbol_UC">WDB_EVENT_GET</b> service. In order to prevent the host from polling for events, the agent has two ways to notify the host that events are pending: (1) by setting the high order bit in the <b class="symbol_lc">errCode</b> status of the reply wrapper; (2) by sending a <i class="term">notify packet</i>.</p><dd><p class="Body"><a name="85108"> </a>Normally the agent only sends data to the host in response to RPC requests. The convention is that if the host receives data when it is not waiting for a reply, it means that an event is pending on the target. This allows the target server to <b class="routine"><i class="routine">select</i></b><b>(&nbsp;)</b>on file descriptors associated with the host tools which are connected as well as with the target. If the target file descriptor becomes active, the host issues a <b class="symbol_UC">WDB_EVENT_GET</b> request to upload the event (and keeps uploading events until the high order bit in the <b class="symbol_lc">errCode</b> field is clear). The actual notify packet sent by the agent is a packet that can not be confused with an RPC reply (in case it sends the notify packet just as the host issues an RPC request). In fact, it sends a bogus RPC request.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="85110">2.3.3  &nbsp;&nbsp;Host-Side Code</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85112"> </a>To provide the necessary host-side support for a new communication pathway, you must write a new back-end DLL to transport WDB protocol messages. Fortunately, most of the back-end code is generic RPC<sup><a href="#foot"><b class="FootnoteMarker">1</b></a></sup> code to transport WDB protocol messages; thus you can reuse Wind River's <b class="library">rpccore</b> library<sup><a href="#foot"><b class="FootnoteMarker">2</b></a></sup>. Consequently, you can only need to write the back end's initialization code and, if necessary, the client-side RPC implementation.</p><dd><p class="Body"><a name="85120"> </a>A WDB back end consists of three parts: (1) the initialization routine, which initializes the back end; (2) the RPC core which manages WDB RPC requests, including XDR; and (3) the client-side RPC implementation, which sends and receives the RPC messages over the network medium. (See <a href="c-bkend3.html#90478">Figure&nbsp;2-5</a>.)&nbsp;&nbsp;<div class="frame"><h4 class="EntityTitle"><a name="90478"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 2-5:&nbsp;&nbsp;Host-Side Code for WDB Back End</font></a></h4><dl class="margin"><div class="Anchor"><a name="90480"> </a><img class="figure" border="0" src="images/c-bkenda4.gif"></div></dl></div>&nbsp;&nbsp;&nbsp;</p><dd><p class="Body"><a name="85150"> </a>The <b class="routine"><i class="routine">bkendInit</i></b><b>(&nbsp;)</b> routine is the back-end DLL's entry point and must initialize the back end. To do this, it performs the following services:</p></dl><dl class="margin"><p><ol class="List"><li value="1."><a name="85152"> </a>It creates the <b class="symbol_UC">CLIENT</b> data structure, which the RPC core uses to communicate with the WDB agent. The <b class="symbol_UC">CLIENT</b> structure is a standard RPC data structure that contains information needed by the RPC core, such as pointers to buffers and to the functions for sending and receiving data. It is important to create a <b class="symbol_UC">CLIENT </b>structure appropriate to the network medium your back end is using: for example, Wind River's <b class="keyword">wdbrpc</b> back end calls <b class="routine"><i class="routine">clnt_udpcreate</i></b><b>(&nbsp;)</b> so that the back end can send UDP messages over the network; the <b class="keyword">wdbserial</b> back end calls <b class="routine"><i class="routine">clnt_ttycreate</i></b> <b>(&nbsp;)</b>so that the back end can communicate over a serial device.<b class="symbol_UC"></b></li></ol></p><p><ol class="List"><li value="2."><a name="85155"> </a>It initializes the <b class="symbol_UC">TGT_LINK_DESC</b> information in the <b class="symbol_UC">TGT_OPS</b> structure.</li></ol></p><p><ol class="List"><li value="3."><a name="85157"> </a>It calls <b class="routine"><i class="routine">rpcCoreInit</i></b><b>(&nbsp;)</b> to handle the rest of the back-end initialization. This routine is part of the <i class="textVariable">installDir</i><b class="file">/host/src/tgtsvr/backend/share/rpccore.c</b> support library, which handles all the generic parts of the protocol including:</li></ol></p><dl class="margin"><p class="listspace"><ul class="Bullet2" type="disc"><li><a name="85158"> </a>translating back-end requests into WDB-agent requests, including XDR encoding and decoding</li></ul></p><p class="listspace"><ul class="Bullet2" type="disc"><li><a name="85159"> </a>packet sequencing and checksum</li></ul></p><p class="listspace"><ul class="Bullet2" type="disc"><li><a name="85160"> </a>timeout and retransmission</li></ul></p><p class="listspace"><ul class="Bullet2" type="disc"><li><a name="85161"> </a>asynchronous event notification</li></ul></p><p class="listspace"><ul class="Bullet2" type="disc"><li><a name="85163"> </a>back-end logging</li></ul></p></dl></dl><dl class="margin"><dd><p class="Body"><a name="85164"> </a>In the following sections, we examine the <b>wdbserial</b> back end to demonstrate how to write a new WDB back end. The <b>wdbserial</b> back end consists of two main modules, the <b class="file">wdbserial.c</b> module, which implements the back-end initialization routine, and <b class="file">clnt_tty.c</b>, which provides the client-side RPC implementation for a serial device (see <a href="c-bkend3.html#85263"><i class="title">Client-Side RPC Implementation</i></a>).</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85169">Back-End Initialization: <b class="file">wdbserial.c</b></a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85171"> </a>The<b class="file"> wdbserial.c</b> module consists of one routine, <b class="routine"><i class="routine">wdbserialInit</i></b><b>(&nbsp;)</b>. The target server invokes <b class="routine"><i class="routine">wdbserialInit</i></b><b>(&nbsp;)</b>after it loads the back end in order to initialize it. The <b class="routine"><i class="routine">wdbserialInit</i></b><b>(&nbsp;)</b> call creates an RPC <b class="symbol_UC">CLIENT</b> structure for communicating over a serial device and establishes a link, initializes the generic RPC core library to operate the target agent using the WDB (Wind DeBug) protocol, and initializes a data structure describing the back-end link with the agent. The <b class="file">wdbserial.c</b> code shows how these steps are carried out.</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85172">/* wdbserial.c - Remote Procedure Call (RPC) backend library */</a></b></pre></dl><dl class="margin"><dd><p class="Body"><a name="85173"> </a>After the usual preamble of comments, copyright notice, and inclusion of system header files, <b class="file">wdbserial.c</b> includes the Tornado host header files from the <i class="textVariable">installDir</i><b class="file">/host/include </b>directory:</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85174">... /* includes */  /* system header files go here */ ...   #include "tgtlib.h" #include "tgtsvr.h" #include "tssvcmgt.h" #include "host.h" #include "wdb.h" #include "wdbP.h" #include "wpwrutil.h" #include "bkendlib.h" #include "bkendlog.h"</a></b></pre></dl><dl class="margin"><dd><p class="Body"><a name="85189"> </a>Windows `95 and NT hosts must include <b class="file">backend.h</b> by means of the following <b class="command">#ifdef</b>:</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85190">#ifdef WIN32 #include "backend.h" extern int dbg_on; #endif /* WIN32 */</a></b></pre></dl><dl class="margin"><dd><p class="Body"><a name="85195"> </a>Next, <b class="file">wdbserial.c</b> imports the prototypes to <b class="routine"><i class="routine">rpcCoreInit</i></b><b>(&nbsp;)</b>, which initializes the RPC core library, and <b class="routine"><i class="routine">clnttty_creat</i></b> <b>(&nbsp;)</b>, which creates an RPC connection over a serial link.</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85198">extern STATUS rpcCoreInit (CLIENT *, u_int, u_int, TGT_OPS *); extern CLIENT * clnttty_create&nbsp;&nbsp;(char *, int, u_long, u_long,                                   struct timeval);</a></b></pre></dl><dl class="margin"><dd><p class="Body"><a name="85201"> </a>When the target server calls <b class="routine"><i class="routine">wdbserialInitialize</i></b><b>(&nbsp;)</b>, it passes pointers to the <b class="symbol_UC">TGT_OPS</b> and <b class="symbol_UC">BKEND_INFO</b> structures. (For more information on these structures, see <a href="c-bkend2.html#84674"><i class="title">The TGT_OPS Structure</i></a> and <a href="c-bkend2.html#84717"><i class="title">The BKEND_INFO Structure</i></a>.) </p><dl class="margin"><dd><pre class="Code2"><b><a name="89160">STATUS wdbserialInitialize     (     char *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tgtName, &nbsp;&nbsp;&nbsp;/* target name to connect to (unused) */     TGT_OPS *&nbsp;&nbsp;&nbsp;&nbsp;pTgtOps &nbsp;&nbsp;&nbsp;&nbsp;/* back-end function */     BKEND_INFO *&nbsp;pBkendInfo&nbsp;&nbsp;/* Backend notification method */     )</a></b></pre></dl><dd><p class="Body"><a name="85211"> </a>Windows hosts optionally enable logging of debugging messages from the lower-level serial support:</p><dl class="margin"><dd><pre class="Code2"><b><a name="85212">#ifdef WIN32     dbg_on = GetDebugFlag(); #endif /* WIN32 */</a></b></pre></dl><dd><p class="Body"><a name="85216"> </a>Next, the back end must enable RPC communications over a serial link by creating the <b class="symbol_UC">CLIENT</b> data structure. If your back end uses an unsupported link type you will need to implement a <b class="routine"><i class="routine">clnt</i></b><i class="textVariable">XXX</i><b class="routine"><i class="routine">_create</i></b><b>(&nbsp;)</b> call for your communication medium. Wind River implemented <b class="routine"><i class="routine">clnttty_create</i></b><b>(&nbsp;)</b> for the <b class="symbol_lc">wdbserial</b> back end.</p><dd><p class="Body"><a name="85219"> </a>The back end initializes the RPC client-side transport to the WDB agent: first, <b class="symbol_lc">struct timeval</b> is initialized with the user's specified timeout; then <b class="routine"><i class="routine">clnttty_create</i></b><b>(&nbsp;)</b> is called to create the RPC link to the target. Note that the <b class="routine"><i class="routine">clntty_create</i></b><b>(&nbsp;)</b> call is retried until it succeeds or exceeds the user-specified number of retries.</p><dl class="margin"><dd><pre class="Code2"><b><a name="85220">/* set the connection timeout to the current value */  tv.tv_sec  = timeout; tv.tv_usec = 0; ... resendCnt = recallNum;  do {     /* create the backend client and connect the target deamon */  pClnt = clnttty_create (pTtyDevName, baudRate, WDBPROG, WDBVERS, tv);  } while ((pClnt == NULL) &amp;&amp; (--resendCnt &gt; 0)); ...</a></b></pre></dl><dd><p class="Body"><a name="85236"> </a>If the RPC client-side initialization fails, the back end sets <b class="symbol_lc">errno</b> to the appropriate error number, logs an error message, and returns <b class="symbol_UC">ERROR</b> to indicate that the called routine failed.</p><dl class="margin"><dd><pre class="Code2"><b><a name="85237">if (pClnt == NULL) { ... errno = WTX_ERR_SVR_INVALID_DEVICE;  WPWR_LOG_ERR ("%s\n",              clnt_spcreateerror ("wdbserial backend client create")); return (ERROR); }</a></b></pre></dl><dd><p class="Body"><a name="85247"> </a>If the RPC client initialization succeeds, the back end calls <b class="routine"><i class="routine">rpcCoreInit</i></b><b>(&nbsp;)</b> to initialize the <b class="library">rpccore</b> library for use over the serial device. The <b class="library">rpccore</b> library provides all the support necessary to operate the WDB target agent in response to target server requests. In particular, <b class="routine"><i class="routine">rpcCoreInit</i></b><b>(&nbsp;)</b> initializes the <b class="symbol_UC">TGT_OPS</b> structure, specifying that the target server should call <b class="library">rpccore</b> routines to perform the various back-end operations.</p><dl class="margin"><dd><pre class="Code2"><b><a name="85251">rpcCoreInit (pClnt, timeout, recallNum, pTgtOps); ...</a></b></pre></dl><dd><p class="Body"><a name="85254"> </a>Finally, the back end describes the target link type. If your back end uses a new link type, define a <b class="symbol_UC">TGT_LINK_</b><i class="textVariable">XXX</i> macro in <i class="textVariable">installDir</i><b class="file">/host/h/tgtlib.h</b>.</p><dl class="margin"><dd><pre class="Code2"><b><a name="85255">pTgtOps-&gt;tgtLink.name = "WDB Agent across serial line"; pTgtOps-&gt;tgtLink.type = TGT_LINK_SERIAL_RPC; pTgtOps-&gt;tgtLink.speed = baudRate;  return (OK); }</a></b></pre></dl></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85263">Client-Side RPC Implementation</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85265"> </a>If your back end must communicate over an unsupported network medium, you must provide a client-side RPC implementation. As a starting point, you should use the <b class="file">clnt_udp.c</b> which is part of Sun Microsystem's public domain RPC distribution and is provided in <i class="textVariable">installDir</i><b class="file">/target/unsupported/rpc4.0/rpc</b>. </p><dd><p class="Body"><a name="85266"> </a>Your implementation must provide the following services:</p></dl><dl class="margin"><p class="listspace"><ul class="Bullet" type="disc"><li><a name="85267"> </a>A <b class="routine"><i class="routine">clnt</i></b><i class="textVariable">XXX</i><b class="routine"><i class="routine">_create</i></b><b>(&nbsp;)</b> routine (where <i class="textVariable">XXX</i> describes the device type you are using): this routine must open the device for communication and return a pointer to a <b class="symbol_UC">CLIENT</b> data structure. The <b class="symbol_UC">CLIENT</b> structure should contain the information needed to perform RPC, including pointers to the <b class="routine"><i class="routine">clnt_ops</i></b> functions for managing the transmission of data and data such as file descriptors.</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="85270"> </a>The <b class="routine"><i class="routine">clnt_ops</i></b> functions: these functions perform the basic RPC operations over a specific network medium.</li></ul></p></dl></dl><dl class="margin"><dd><p class="table" callout><table border="0" cellpadding="0" cellspacing="0"><tr valign="top">

⌨️ 快捷键说明

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