Как задача может ждать в нескольких очередях vxworks? - PullRequest
3 голосов
/ 23 сентября 2008

У нас есть дизайн vxWorks, который требует одной задачи для обработки сообщений с высоким и низким приоритетом, отправленных по двум очередям сообщений.
Сообщения с заданным приоритетом должны обрабатываться в порядке FIFO.

Например, обработать все сообщения с высоким приоритетом в порядке их получения, а затем обработать сообщения с низким приоритетом. Если сообщения с высоким приоритетом нет, немедленно обработайте сообщение с низким приоритетом.

Есть ли способ сделать это?

Ответы [ 2 ]

3 голосов
/ 27 сентября 2008

Если вы используете именованные каналы (pipeDevCreate (), write (), read ()) вместо очередей сообщений, вы можете использовать select () для блокировки до тех пор, пока в каком-либо канале нет сообщений.

Всякий раз, когда срабатывает select (), вы обрабатываете все сообщения в канале с высоким приоритетом. Затем вы обрабатываете одно сообщение из канала с низким приоритетом. Затем снова вызовите select (loop).

Примеры фрагментов кода:

 // Initialization: Create high and low priority named pipes
 pipeDrv(); //initialize pipe driver
 int fdHi = pipeDevCreate("/pipe/high",numMsgs,msgSize);
 int fdLo = pipeDevCreate("/pipe/low",numMsgs,msgSize);

 ...

 // Message sending thread: Add messages to pipe
 write(fdHi, buf, sizeof(buf));

 ...

 // Message processing Thread: select loop
 fd_set rdFdSet;

 while(1)
 {
     FD_ZERO(&rdFdSet);
     FD_SET(fdHi, &rdFdSet);
     FD_SET(fdLo, &rdFdSet;

     if (select(FD_SETSIZE, &rdFdSet, NULL, NULL, NULL) != ERROR)
     {
         if (FD_ISSET(fdHi, &rdFdSet))
         {
             // process all high-priority messages
             while(read(fdHi,buf,size) > 0)
             {
                 //process high-priority
             }
         }

         if (FD_ISSET(fdLo, &rdFdSet))
         {
             // process a single low priority message
             if (read(fdLo,buf,size) > 0)
             {
                 // process low priority
             }
         }
     }
 }
1 голос
/ 23 сентября 2008

В vxWorks вы не можете ожидать сразу нескольких очередей. Однако вы можете использовать события ОС (из eventLib) для достижения этого результата. Вот простой фрагмент кода:


MSG_Q_ID lowQ, hiQ;

void Init() {
// Task Initialization Code.  This should be called from the task that will
// be receiving the messages
...
hiQ = msgQCreate(...);
lowQ = msgQCreate(...);
msgQEvStart(hiQ, VX_EV01);  // Event 1 sent when hiQ receives message
msgQEvStart(loQ, VX_EV02);  // Event 2 sent when loQ receives message
...
}
void RxMessages() {
...
  UINT32 ev;   // Event received

   // Blocks until we receive Event 1 or 2
   eventReceive(VX_EV01 | VX_EV02, EVENT_WAIT_ANY, WAIT_FOREVER, &ev);
   if(ev & VX_EV01) {
      msgQReceive(hiQ, ...);
   }
   if(ev & VX_EV02) {
      msgQReceive(loQ, ...);
   }
}

Обратите внимание, что вам нужно изменить этот код, чтобы обеспечить очистку всех ваших очередей в случае, если было получено более одного сообщения.

Тот же механизм также можно применить к двоичным семафорам с помощью функции semEvStart ().

...