Integrieren des OTA-Agents in Ihre Anwendung - FreeRTOS

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Integrieren des OTA-Agents in Ihre Anwendung

Der over-the-air (OTA) Agent wurde entwickelt, um die Menge an Code zu vereinfachen, die Sie schreiben müssen, um Ihrem Produkt OTA-Aktualisierungsfunktionen hinzuzufügen. Dieser Integrationsaufwand besteht hauptsächlich aus der Initialisierung des OTA-Agenten und der Erstellung einer benutzerdefinierten Rückruffunktion für die Reaktion auf die OTA-Agent-Ereignismeldungen. Während der Initialisierung werden OS-, MQTT-, HTTP- (wenn HTTP für das Herunterladen von Dateien verwendet wird) und plattformspezifische Implementierungsschnittstellen (PAL) an den OTA-Agenten übergeben. Puffer können auch initialisiert und an den OTA-Agenten übergeben werden.

Anmerkung

Obwohl die Integration der OTA-Update-Funktion in Ihre Anwendung recht einfach ist, müssen Sie sich für das OTA-Update-System nicht nur mit der Integration von Code auf dem Gerät auskennen. Weitere Informationen zur Konfiguration Ihres AWS Kontos mit AWS IoT Dingen, Anmeldeinformationen, Codesignaturzertifikaten, Bereitstellungsgeräten und OTA-Aktualisierungsaufträgen finden Sie unter FreeRTOS-Voraussetzungen.

Verbindungsverwaltung

Der OTA-Agent verwendet das MQTT-Protokoll für alle Kontrollkommunikationsvorgänge, die AWS IoT Dienste betreffen, verwaltet aber nicht die MQTT-Verbindung. Um sicherzustellen, dass der OTA-Agent nicht gegen die Verbindungsverwaltungsrichtlinie Ihrer Anwendung verstößt, muss die MQTT-Verbindung von der Haupt-Benutzeranwendung verwaltet werden (inkl. Funktionalität für die Trennung und das erneute Verbinden). Die Datei kann über das MQTT- oder HTTP-Protokoll heruntergeladen werden. Sie können das gewünschter Protokoll auswählen, wenn Sie den OTA-Auftrag erstellen. Wenn Sie MQTT wählen, verwendet der OTA-Agent dieselbe Verbindung für Steuervorgänge und zum Herunterladen von Dateien.

Einfache OTA-Demo

Im Folgenden finden Sie einen Auszug aus einer einfachen OTA-Demo. Sie zeigt, wie sich der Agent mit dem MQTT-Broker verbindet und den OTA-Agent initialisiert. In diesem Beispiel konfigurieren wir die Demo so, dass sie den standardmäßigen OTA-Anwendungs-Callback verwendet und einige Statistiken einmal pro Sekunde zurückgibt. Zu Übersicht lassen wir hier einige Details aus dieser Demo weg.

Die OTA-Demo demonstriert auch die MQTT-Verbindungsverwaltung, indem sie den Disconnect-Callback überwacht und die Verbindung wieder herstellt. Wenn die Verbindung unterbrochen wird, unterbricht die Demo zunächst den Betrieb des OTA-Agenten und versucht dann, die MQTT-Verbindung wiederherzustellen. Die MQTT-Wiederverbindungsversuche werden um eine Zeit verzögert, die exponentiell bis zu einem Höchstwert erhöht wird, und ein Jitter wird ebenfalls hinzugefügt. Wenn die Verbindung wieder hergestellt wird, setzt der OTA-Agent seinen Betrieb fort.

Ein funktionierendes Beispiel, das den AWS IoT MQTT-Broker verwendet, finden Sie im OTA-Democode im demos/ota Verzeichnis.

Da der OTA-Agent ein eigener Task ist, betrifft die absichtliche Verzögerung von einer Sekunde in diesem Beispiel nur diese Anwendung. Sie hat keinen Einfluss auf die Leistung des Agents.

static BaseType_t prvRunOTADemo( void ) { /* Status indicating a successful demo or not. */ BaseType_t xStatus = pdFAIL; /* OTA library return status. */ OtaErr_t xOtaError = OtaErrUninitialized; /* OTA event message used for sending event to OTA Agent.*/ OtaEventMsg_t xEventMsg = { 0 }; /* OTA interface context required for library interface functions.*/ OtaInterfaces_t xOtaInterfaces; /* OTA library packet statistics per job.*/ OtaAgentStatistics_t xOtaStatistics = { 0 }; /* OTA Agent state returned from calling OTA_GetState.*/ OtaState_t xOtaState = OtaAgentStateStopped; /* Set OTA Library interfaces.*/ prvSetOtaInterfaces( &xOtaInterfaces ); /*************************** Init OTA Library. ***************************/ if( ( xOtaError = OTA_Init( &xOtaBuffer, &xOtaInterfaces, ( const uint8_t * ) ( democonfigCLIENT_IDENTIFIER ), prvOtaAppCallback ) ) != OtaErrNone ) { LogError( ( "Failed to initialize OTA Agent, exiting = %u.", xOtaError ) ); } else { xStatus = pdPASS; } /************************ Create OTA Agent Task. ************************/ if( xStatus == pdPASS ) { xStatus = xTaskCreate( prvOTAAgentTask, "OTA Agent Task", otaexampleAGENT_TASK_STACK_SIZE, NULL, otaexampleAGENT_TASK_PRIORITY, NULL ); if( xStatus != pdPASS ) { LogError( ( "Failed to create OTA agent task:" ) ); } } /****************************** Start OTA ******************************/ if( xStatus == pdPASS ) { /* Send start event to OTA Agent.*/ xEventMsg.eventId = OtaAgentEventStart; OTA_SignalEvent( &xEventMsg ); } /******************** Loop and display OTA statistics ********************/ if( xStatus == pdPASS ) { while( ( xOtaState = OTA_GetState() ) != OtaAgentStateStopped ) { /* Get OTA statistics for currently executing job. */ if( xOtaState != OtaAgentStateSuspended ) { OTA_GetStatistics( &xOtaStatistics ); LogInfo( ( " Received: %u Queued: %u Processed: %u Dropped: %u", xOtaStatistics.otaPacketsReceived, xOtaStatistics.otaPacketsQueued, xOtaStatistics.otaPacketsProcessed, xOtaStatistics.otaPacketsDropped ) ); } vTaskDelay( pdMS_TO_TICKS( otaexampleEXAMPLE_TASK_DELAY_MS ) ); } } return xStatus; }

Hier ist der High-Level-Ablauf der Demo-Anwendung:

  • Erstellen Sie einen MQTT-Agent-Kontext.

  • Connect zu Ihrem AWS IoT Endpunkt her.

  • Initialisieren Sie den OTA-Agent.

  • Loop, der einen OTA-Aktualisierungsjob ermöglicht und einmal pro Sekunde Statistiken ausgibt.

  • Wenn MQTT die Verbindung trennt, unterbrechen Sie den Betrieb des OTA-Agenten.

  • Versuchen Sie erneut, eine Verbindung mit exponentieller Verzögerung und Jitter herzustellen.

  • Wenn die Verbindung wieder hergestellt ist, setzen Sie den Betrieb des OTA-Agenten fort.

  • Wenn der Agent stoppt, warten Sie eine Sekunde und versuchen Sie dann erneut, die Verbindung herzustellen.

Verwenden Sie den Anwendungsrückruf für OTA-Agent-Ereignisse

Das vorherige Beispiel wurde prvOtaAppCallback als Callback-Handler für OTA-Agent-Ereignisse verwendet. (Siehe den vierten Parameter des OTA_Init API-Aufrufs). Wenn Sie eine benutzerdefinierte Behandlung der Abschlussereignisse implementieren möchten, müssen Sie die Standardbehandlung in der OTA-Demo/Anwendung ändern. Während des OTA-Prozesses kann der OTA-Agent eine der folgenden Ereignisaufzählungen an den Callback-Handler senden. Der Anwendungsentwickler entscheidet, wie und wann er diese Ereignisse verarbeitet.

/** * @ingroup ota_enum_types * @brief OTA Job callback events. * * After an OTA update image is received and authenticated, the agent calls the user * callback (set with the @ref OTA_Init API) with the value OtaJobEventActivate to * signal that the device must be rebooted to activate the new image. When the device * boots, if the OTA job status is in self test mode, the agent calls the user callback * with the value OtaJobEventStartTest, signaling that any additional self tests * should be performed. * * If the OTA receive fails for any reason, the agent calls the user callback with * the value OtaJobEventFail instead to allow the user to log the failure and take * any action deemed appropriate by the user code. * * See the OtaImageState_t type for more information. */ typedef enum OtaJobEvent { OtaJobEventActivate = 0, /*!< @brief OTA receive is authenticated and ready to activate. */ OtaJobEventFail = 1, /*!< @brief OTA receive failed. Unable to use this update. */ OtaJobEventStartTest = 2, /*!< @brief OTA job is now in self test, perform user tests. */ OtaJobEventProcessed = 3, /*!< @brief OTA event queued by OTA_SignalEvent is processed. */ OtaJobEventSelfTestFailed = 4, /*!< @brief OTA self-test failed for current job. */ OtaJobEventParseCustomJob = 5, /*!< @brief OTA event for parsing custom job document. */ OtaJobEventReceivedJob = 6, /*!< @brief OTA event when a new valid AFT-OTA job is received. */ OtaJobEventUpdateComplete = 7, /*!< @brief OTA event when the update is completed. */ OtaLastJobEvent = OtaJobEventStartTest } OtaJobEvent_t;

Der OTA-Agent kann während der aktiven Verarbeitung der Hauptanwendung im Hintergrund ein Update erhalten. Der Zweck der Bereitstellung dieser Ereignisse ist es, der Anwendung eine Entscheidung darüber zu ermöglichen, ob Maßnahmen sofort ergriffen werden können oder ob sie auf den Zeitpunkt nach Abschluss einer anderen anwendungsspezifischen Verarbeitung verschoben werden sollen. Dadurch wird eine unvorhergesehene Unterbrechung Ihres Gerätes während der aktiven Verarbeitung verhindert, die durch einen Reset nach einem Firmware-Update verursacht würde. Hier sind die Jobereignisse, die der Callback-Handler erhält:

OtaJobEventActivate

Wenn der Callback-Handler dieses Ereignis empfängt, können Sie das Gerät entweder sofort zurücksetzen oder einen Anruf planen, um das Gerät zu einem späteren Zeitpunkt zurückzusetzen. Hierdurch können Sie die Gerätezurücksetzung und die Selbsttestphase verschieben, wenn notwendig.

OtaJobEventFail

Wenn der Callback-Handler dieses Ereignis empfängt, ist die Aktualisierung fehlgeschlagen. In diesem Fall brauchen Sie nichts zu tun. Möglicherweise möchten Sie eine Protokollnachricht ausgeben oder etwas Anwendungsspezifisches tun.

OtaJobEventStartTest

Die Selbsttestphase soll es der neu aktualisierten Firmware ermöglichen, sich selbst auszuführen und zu testen, bevor sie feststellt, ob sie ordnungsgemäß funktioniert, und sich als aktuelles permanentes Anwendungs-Image festlegt. Wenn ein neues Update empfangen und authentifiziert wird und das Gerät zurückgesetzt wurde, sendet der OTA-Agent das Ereignis OtaJobEventStartTest an die Callback-Funktion, wenn das Update für den Test bereit ist. Der Entwickler kann alle erforderlichen Tests hinzufügen, um zu ermitteln, ob die Gerätefirmware nach der Aktualisierung korrekt funktioniert. Wenn die Gerätefirmware aufgrund der Selbsttests als zuverlässig identifiziert wird, muss der Code die Firmware durch Aufruf der Funktion OTA_SetImageState( OtaImageStateAccepted ) als neues permanentes Image übergeben.

OtaJobEventProcessed

Das OTA-Ereignis in der Warteschlange OTA_SignalEvent wird verarbeitet, sodass Bereinigungsvorgänge wie das Freigeben der OTA-Puffer durchgeführt werden können.

OtaJobEventSelfTestFailed

Der OTA-Selbsttest ist für den aktuellen Job fehlgeschlagen. Die Standardbehandlung für dieses Ereignis besteht darin, den OTA-Agenten herunterzufahren und neu zu starten, sodass das Gerät zum vorherigen Image zurückkehrt.

OtaJobEventUpdateComplete

Das Benachrichtigungsereignis für den Abschluss der Aktualisierung des OTA-Jobs.