Domanda

Abbiamo una progettazione vxWorks che richiede un'attività per elaborare sia i messaggi con priorità alta che bassa inviati su due code di messaggi.
I messaggi per una determinata priorità devono essere elaborati in ordine FIFO.

Ad esempio, elabora tutti i messaggi con priorità alta nell'ordine in cui sono stati ricevuti, quindi elabora i messaggi con priorità bassa. Se non è presente alcun messaggio con priorità alta, elaborare immediatamente il messaggio con priorità bassa.

C'è un modo per farlo?

È stato utile?

Soluzione

Se si utilizzano named pipe (pipeDevCreate (), write (), read ()) anziché le code dei messaggi, è possibile utilizzare select () per bloccare fino a quando non ci sono messaggi in entrambe le pipe.

Ogni volta che viene attivato select (), si elaborano tutti i messaggi nella pipe ad alta priorità. Quindi si elabora un singolo messaggio dalla pipe a bassa priorità. Quindi chiama nuovamente select (loop).

Esempio di frammenti di codice:

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

Altri suggerimenti

In vxWorks, non è possibile attendere direttamente su più code. È comunque possibile utilizzare gli eventi del sistema operativo (da eventLib) per ottenere questo risultato. Ecco un semplice frammento di codice:


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

Nota che devi modificare quel codice per assicurarti di svuotare tutte le code nel caso in cui sia stato ricevuto più di un messaggio.

Lo stesso meccanismo può essere applicato anche ai semafori binari utilizzando la funzione semEvStart ().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top