Senden einer Befehlsfolge und Warten auf Antwort
Problem: So senden Sie eine Befehlsfolge an ein über die serielle Schnittstelle angeschlossenes Gerät Warten Sie auf eine Antwort und behandeln Sie Zeitüberschreitungen und Fehlerbedingungen.
Lösung mithilfe der Zustandsmaschine von Qt Framework:
Vorteile:
- Asynchron, nicht blockierend
- Automatische Timeout-Behandlung
- Klarer und lesbarer Code Struktur
Implementierung:
-
Zustandsmaschine erstellen:
- Erstellen Sie eine QStateMachine und definieren Sie Zustände für jeden Schritt in der Kommunikationssequenz (z. B. Booten, Senden, erwarten).
-
Aktionsgeneratoren definieren:
- Funktionen definieren, die Aktionen beschreiben, die beim Eintritt in jeden Zustand ausgeführt werden sollen, wie das Senden von Befehlen oder das Erwarten von Antworten.
-
Verbinden Signale und Übergänge:
- Verbinden Sie Signale (z. B. readyRead), um von einem Zustand in einen anderen zu wechseln.
- Verwenden Sie GuardedSignalTransition, um Bedingungen zu Übergängen basierend auf empfangenen Daten hinzuzufügen.
-
Erstellen Sie einen Programmierer Objekt:
- Verwenden Sie StatefulObject als Basisklasse, um die Zustandsmaschine und die Signale zu verwalten.
- Umschließen Sie den seriellen Port mit AppPipe (einem nicht blockierenden QIODevice) und definieren Sie Aktionen zum Senden und Erwarten von Befehlen Antworten.
-
Geräteverhalten emulieren (optional):
- Erstellen Sie ein weiteres StatefulObject (Gerät), um die Antworten des Geräts zu simulieren Zu Befehle.
-
In der Hauptfunktion:
- Programmierer- und Geräteobjekte instanziieren.
- Verbinden ihre AppPipes, um die Kommunikation zu ermöglichen.
- Starten Sie das Programmer-Objekt und verfolgen Sie es Zustand.
- Optional das Geräteobjekt starten und seinen Zustand verfolgen.
Beispielcode:
// Programmer object using Qt's State Machine Framework
class Programmer : public StatefulObject {
Q_OBJECT
AppPipe m_port;
QStateMachine m_mach;
State s_boot, s_send;
public:
Programmer() : StatefulObject() {
connectSignals();
m_mach.setInitialState(&s_boot);
send(&s_boot, &m_port, "boot\n");
expect(&s_boot, &m_port, "boot successful", &s_send, 1000, &s_failed);
... // Define other states and actions
}
void start() { m_mach.start(); }
};
// main function
int main() {
QApplication app;
Programmer prog;
Device dev;
dev.pipe().addOther(&prog.pipe());
prog.pipe().addHasOutgoing([](const QByteArray &data){ qDebug() << "> " << data; });
prog.pipe().addHasIncoming([](const QByteArray &data){ qDebug() << "< " << data; });
prog.start();
return app.exec();
}
Nach dem Login kopieren
Vorteile:
- Sauberer und strukturierter Code, Minimierung des Risikos von Race Conditions oder verpassten Antworten.
- Möglichkeit zum Hinzufügen komplexer Zustandsübergänge und Fehlerbehandlungsszenarien.
- Erweiterbarkeit zur Unterstützung verschiedener Kommunikationsprotokolle mit unterschiedlichen Befehlssequenzen.
Das obige ist der detaillierte Inhalt vonWie sende ich eine Folge serieller Befehle und verarbeite Antworten mit der Zustandsmaschine von Qt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!