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

📄 c-smo2.html

📁 vxworks相关论文
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<p class="listspace"><ul class="Bullet" type="disc"><li><a name="84734"> </a>The shared message queue task queueing order specified when a message queue is created must be FIFO. <a href="c-smo2.html#84744">Figure&nbsp;6-2</a> shows two tasks executing on different CPUs, both trying to receive a message from the same shared message queue. Task 1 executes first, and is put at the front of the queue because there are no messages in the message queue. Task 2 (executing on a different CPU) tries to receive a message from the message queue after task 1's attempt and is put on the queue behind task 1.</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="84738"> </a>Messages <i class="emphasis">cannot </i>be sent on a shared message queue at interrupt level. (This is true even in<b class="symbol_UC"> NO_WAIT</b> mode.)</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="84739"> </a>Shared message queues cannot be deleted. Attempts to delete a shared message queue return<b class="symbol_UC"> ERROR</b> and sets <b class="symbol_lc">errno</b> to <b class="symbol_UC">S_smObjLib_NO_OBJECT_DESTROY</b>.</li></ul></p></dl><dl class="margin"><dd><p class="Body"><a name="84740"> </a>To achieve optimum performance with shared message queues, align send and receive buffers on 4-byte boundaries. &nbsp;<div class="frame"><h4 class="EntityTitle"><a name="84744"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 6-2:&nbsp;&nbsp;Shared Message Queues</font></a></h4><dl class="margin"><div class="Anchor"><a name="84792"> </a><img class="figure" border="0" src="images/c-smoa1.gif"></div></dl></div></p><dd><p class="Body"><a name="84794"> </a>To display the status of the shared message queue as well as a list of tasks pended on the queue, select <b class="symbol_UC">INCLUDE_MSG_Q_SHOW</b> for inclusion in the project facility VxWorks view and call <b class="routine"><i class="routine">msgQShow</i></b><b>(</b>&nbsp;<b>)</b>. The following example displays detailed information on the shared message queue 0x7f8c21 as indicated by the second argument (0 = summary display, 1 = detailed display).</p><dl class="margin"><dd><pre class="Code2"><b><a name="84796"></b><tt class="output">-&gt;</tt><b> msgQShow 0x7f8c21, 1 </b><tt class="output">value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="84797"> </a>The output is sent to the standard output device, and looks like the following:</p><dl class="margin"><dd><pre class="Code2"><b><a name="84798"></b><tt class="output">Message&nbsp;Queue&nbsp;Id&nbsp;&nbsp;:&nbsp;0x7f8c21 Task&nbsp;Queuing&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;FIFO Message&nbsp;Byte&nbsp;Len&nbsp;&nbsp;:&nbsp;128 Messages&nbsp;Max&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;10 Messages&nbsp;Queued&nbsp;&nbsp;&nbsp;:&nbsp;0 Receivers&nbsp;Blocked&nbsp;:&nbsp;1 Send&nbsp;timeouts&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;0 Receive&nbsp;timeouts&nbsp;&nbsp;:&nbsp;0 Receivers&nbsp;blocked&nbsp;: TID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CPU Number&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Shared TCB ----------&nbsp;--------------------&nbsp;-------------- 0xd0618&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x1364204</tt><b> </a></b></pre></dl></dl></dl><h4 class="EntityTitle"><a name="84810"><font face="Helvetica, sans-serif" size="-1" class="sans">Example 6-2:&nbsp;&nbsp;Shared Message Queues</font></a></h4><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84812"> </a>In the following code example, two tasks executing on different CPUs use shared message queues to pass data to each other. The server task creates the request message queue, adds it to the name database, and reads a message from the queue. The client task gets the <b class="symbol_lc">smRequestQId</b> from the name database, creates a reply message queue, bundles the ID of the reply queue as part of the message, and sends the message to the server. The server gets the ID of the reply queue and uses it to send a message back to the client. This technique requires the use of the network byte-order conversion macros <b class="routine"><i class="routine">htonl</i></b><b>(&nbsp;)</b> and <b class="routine"><i class="routine">ntohl</i></b><b>(&nbsp;)</b>, because the numeric queue ID is passed over the network in a data field.</p></dl><dl class="margin"><dd><hr class="Line"></dl><dl class="margin"><dd><pre class="Code"><b><a name="85995">/* msgExample.h - shared message queue example header file */</a></b><dd> <b><a name="85997">#define&nbsp;MAX_MSG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(10) #define&nbsp;MAX_MSG_LEN&nbsp;(100) #define&nbsp;REQUEST_Q&nbsp;&nbsp;&nbsp;"requestQue"</a></b><dd> <b><a name="84820">typedef struct message     {     MSG_Q_ID&nbsp;replyQId;     char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clientRequest[MAX_MSG_LEN];     } REQUEST_MSG;</a></b></pre></dl><dl class="margin"><dd><hr class="Line"></dl><dl class="margin"><dd><pre class="Code"><b><a name="84826">/* server.c - shared message queue example server */</a></b><dd> <b><a name="84828">/* This file contains the code for the message queue server task. */</a></b><dd> <b><a name="84830">#include "vxWorks.h" #include "msgQLib.h" #include "msgQSmLib.h" #include "stdio.h" #include "smNameLib.h" #include "msgExample.h" #include "netinet/in.h"</a></b><dd> <b><a name="84838">#define REPLY_TEXT "Server received your request"</a></b><dd> <b><a name="84840">/************************************************************************ * * serverTask - receive and process a request from a shared message queue */</a></b><dd> <b><a name="84845">STATUS serverTask (void)     {     MSG_Q_ID&nbsp;&nbsp;&nbsp;&nbsp;smRequestQId;&nbsp;&nbsp;/* request shared message queue */     REQUEST_MSG&nbsp;request;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* request text */</a></b><dd> <b><a name="84850">    /* create a shared message queue to handle requests */      if ((smRequestQId = msgQSmCreate (MAX_MSG, sizeof (REQUEST_MSG),         MSG_Q_FIFO)) == NULL)         return (ERROR);</a></b><dd> <b><a name="84856">    /* add newly created request message queue to name database */      if (smNameAdd (REQUEST_Q, smRequestQId, T_SM_MSG_Q) == ERROR)         return (ERROR);</a></b><dd> <b><a name="84861">    /* read messages from request queue */      FOREVER         {         if (msgQReceive (smRequestQId, (char *) &amp;request, sizeof (REQUEST_MSG),             WAIT_FOREVER) == ERROR)             return (ERROR);</a></b><dd> <b><a name="84869">        /* process request - in this case simply print it */          printf ("Server received the following message:\n%s\n",             request.clientRequest);</a></b><dd> <b><a name="84874">        /* send a reply using ID specified in client's request message */          if (msgQSend ((MSG_Q_ID) ntohl ((int) request.replyQId),             REPLY_TEXT, sizeof (REPLY_TEXT),             WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)             return (ERROR);         }     }</a></b></pre></dl><dl class="margin"><dd><hr class="Line"></dl><dl class="margin"><dd><pre class="Code"><b><a name="84882">/* client.c - shared message queue example client */</a></b><dd> <b><a name="84884">/* This file contains the code for the message queue client task. */</a></b><dd> <b><a name="84886">#include "vxWorks.h" #include "msgQLib.h" #include "msgQSmLib.h" #include "smNameLib.h" #include "stdio.h" #include "msgExample.h" #include "netinet/in.h"</a></b><dd> <b><a name="84894">/************************************************************************ * * clientTask - sends request to server and reads reply */</a></b><dd> <b><a name="84896">STATUS clientTask     (     char&nbsp;*&nbsp;pRequestToServer&nbsp;&nbsp;/* request to send to the server */     &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;/* limited to 100 chars */     )     {     MSG_Q_ID&nbsp;&nbsp;&nbsp;&nbsp;smRequestQId;&nbsp;/* request message queue */     MSG_Q_ID  smReplyQId;&nbsp;&nbsp;&nbsp;/* reply message queue */     REQUEST_MSG&nbsp;request;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* request text */     int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objType;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* dummy variable for smNameFind */     char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serverReply[MAX_MSG_LEN];&nbsp;/*buffer for server's reply */</a></b><dd> <b><a name="84909">    /* get request queue ID using its name */      if (smNameFind (REQUEST_Q, (void **) &amp;smRequestQId, &amp;objType,         WAIT_FOREVER) == ERROR)         return (ERROR);</a></b><dd> <b><a name="84915">    /* create reply queue, build request and send it to server */      if ((smReplyQId = msgQSmCreate (MAX_MSG, MAX_MSG_LEN,         MSG_Q_FIFO)) == NULL)         return (ERROR);      request.replyQId = (MSG_Q_ID) htonl ((int) smReplyQId);      strcpy (request.clientRequest, pRequestToServer);      if (msgQSend (smRequestQId, (char *) &amp;request, sizeof (REQUEST_MSG),         WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)         return (ERROR);</a></b><dd> <b><a name="84929">    /* read reply and print it */      if (msgQReceive (request.replyQId, serverReply, MAX_MSG_LEN,         WAIT_FOREVER) == ERROR)         return (ERROR);      printf ("Client received the following message:\n%s\n", serverReply);      return (OK);     }</a></b></pre></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="84940">6.2.4  &nbsp;&nbsp;Shared-Memory Allocator</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84942"> </a>The <i class="term">shared-memory allocator</i> allows tasks on different CPUs to allocate and release variable size chunks of memory that are accessible from all CPUs with access to the shared-memory system. Two sets of routines are provided: low-level routines for manipulating user-created shared-memory partitions, and high-level routines for manipulating a shared-memory partition dedicated to the shared-memory system pool. (This organization is similar to that used by the local-memory manager, <b class="library">memPartLib</b>.) </p><dd><p class="Body"><a name="84943"> </a>Shared-memory blocks can be allocated from different partitions. Both a shared-memory system partition and user-created partitions are available. User-created partitions can be created and used for allocating data blocks of a particular size. Memory fragmentation is avoided when fixed-sized blocks are allocated from user-created partitions dedicated to a particular block size.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="84945">Shared-Memory System Partition</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84946"> </a>To use the shared-memory system partition, a task allocates a shared-memory block and advertises its address. One way of advertising the ID is to add the address to the name database. The routine used to allocate a block from the shared-memory system partition returns a local address. Before the address is advertised to tasks on other CPUs, this local address must be converted to a global address. Any task that must use the shared memory must first get the address of the memory block and convert the global address to a local address. When the task has the address, it can use the memory. </p><dd><p class="Body"><a name="84947"> </a>However, to address issues of mutual exclusion, typically a shared semaphore is used to protect the data in the shared memory. Thus in a more common scenario, the task that creates the shared memory (and adds it to the database) also creates a shared semaphore. The shared semaphore ID is typically advertised by storing it in a field in the shared data structure residing in the shared-memory block. The first time a task must access the shared data structure, it looks up the address of the memory in the database and gets the semaphore ID from a field in the shared data structure. Whenever a task must access the shared data, it must first take the semaphore. Whenever a task is finished with the shared data, it must give the semaphore. </p><dd><p class="Body"><a name="84948"> </a>For example, assume two tasks executing on two different CPUs must share data. Task <b class="task">t1</b> executing on CPU 1 allocates a memory block from the shared-memory system partition and converts the local address to a global address. It then adds the global address of the shared data to the name database with the name <b class="symbol_lc">mySharedData</b>. Task <b class="task">t1</b> also creates a shared semaphore and stores the ID in the first field of the data structure residing in the shared memory. Task <b class="task">t2</b> executing on CPU 2 looks up the name <b class="symbol_lc">mySharedData</b> in the name database to get the address of the shared memory. It then converts this address to a local address. Before accessing the data in the shared memory,<b class="task"> t2 </b>gets the shared semaphore ID from the first field of the data structure residing in the shared-memory block. It then takes the semaphore before using the data and gives the semaphore when it is done using the data.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="84949">User-Created Partitions</a></i></h4></font><dl class="margin">

⌨️ 快捷键说明

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