Wie kann wartet eine Aufgabe auf mehr vxworks Warteschlangen?
Frage
Wir haben ein vxWorks Design, das eine Aufgabe erfordert hohe und niedrige Priorität Nachrichten über zwei Nachrichtenwarteschlangen gesendet zu verarbeiten.
Die Meldungen für eine bestimmte Priorität in FIFO-Reihenfolge verarbeitet werden.
Zum Beispiel Prozess aller Meldungen mit hohen Priorität in der Reihenfolge, wie sie empfangen wurden, verarbeiten dann die Nachrichten mit niedriger Priorität. Wenn es keine Nachricht mit hoher Priorität ist, dann die Mitteilung niedriger Priorität verarbeitet sofort.
Gibt es eine Möglichkeit, dies zu tun?
Lösung
Wenn Sie Named Pipes (pipeDevCreate (), write (), read ()) anstelle von Nachrichtenwarteschlangen, können Sie wählen () verwenden zu blockieren, bis es Nachrichten im Rohr.
Wenn select () auslöst, können Sie alle Nachrichten in der hohen Priorität Rohr verarbeiten. Dann bearbeiten Sie eine einzelne Nachricht von dem niedrigen Priorität Rohr. Rufen Sie dann erneut wählen (Loop).
Beispiel-Code-Schnipsel:
// 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
}
}
}
}
Andere Tipps
In VxWorks, können Sie nicht direkt warten auf mehrere Warteschlangen. Sie können jedoch die OS-Ereignisse verwenden (von eventLib) dieses Ergebnis zu erzielen. Hier ist ein einfacher Code-Snippet:
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, ...);
}
}
Beachten Sie, dass Sie diesen Code ändern müssen, um sicherzustellen, dass Sie alle Ihre Warteschlangen abtropfen lassen, falls es mehr als eine Nachricht, die empfangen wurde.
Der gleiche Mechanismus kann auch auf Binary Semaphore angewandt werden, mit der semEvStart () Funktion.