Pergunta

Nós temos um design vxWorks que requer uma tarefa para processar ambos os altos e baixos mensagens prioritárias enviadas mais de duas filas de mensagens.
As mensagens para uma dada prioridade tem que ser processados ??na ordem FIFO.

Por exemplo, processar todas as mensagens a alta prioridade na ordem em que foram recebidas, em seguida, processar as mensagens de baixa prioridade. Se não houver nenhuma mensagem de alta prioridade, em seguida, processar a mensagem de baixa prioridade imediatamente.

Existe uma maneira de fazer isso?

Foi útil?

Solução

Se você usar pipes nomeados (pipeDevCreate (), write (), read ()) em vez de filas de mensagens, você pode usar select () para bloquear até que há mensagens em qualquer tubulação.

Sempre que seleccionar () gatilhos, você processar todas as mensagens no tubo de alta prioridade. Então você processar uma única mensagem a partir do tubo de baixa prioridade. Em seguida, chamar seleccionar novamente (loop).

snippets de código de exemplo:

 // 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
             }
         }
     }
 }

Outras dicas

Em VxWorks, você não pode esperar diretamente sobre várias filas. No entanto, pode usar os eventos OS (de eventLib) para alcançar este resultado. Aqui está um trecho de código simples:


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, ...);
   }
}

Note que é necessário modificar esse código para ter certeza de drenar todas as suas filas, caso haja mais de uma mensagem que foi recebida.

O mesmo mecanismo pode também ser aplicado para semáforos binárias utilizando a função semEvStart ().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top