Freigeben über


Vorschläge für den Entwurf allgemeiner Kernanwendungen

Um eine allgemeine Kernanwendung (HL) auf soliden Grundlagen zu erstellen, sollten Sie grundlegende bewährte Methoden verwenden. Dies sind die wichtigsten:

Allgemeine (HL)-Kernanwendungen werden containerisiert auf dem Azure Sphere-Betriebssystem ausgeführt. Bei Code- und Entwurfsüberprüfungen von Kundenlösungen haben wir einige typische Probleme mit HL-Core-Anwendungen festgestellt. In diesem Thema werden Vorschläge für Entwurfsverbesserungen erläutert, um diese Probleme zu beheben.

Allgemeine Grundlagen

Um eine HL-Kernanwendung auf soliden Grundlagen zu erstellen, sollten Sie grundlegende bewährte Methoden verwenden. Dies sind die wichtigsten:

  • Initialisierung und Beendigung: Achten Sie immer darauf, das SIGTERM-Signal des Azure Sphere-Betriebssystems zu behandeln, und initialisieren und zerstören Sie alle Handler (z. B. die für Peripheriegeräte) beim Beenden ordnungsgemäß, entweder bei einem Absturz oder einem Fehler. Weitere Informationen finden Sie unter Initialisierung und Beendigung und in der GNU-Dokumentation zu Terminierungssignalen.
  • Verwenden Sie immer Exitcodes: Die Sicherstellung, dass die HL-Core-Anwendung beim Beenden oder Abstürzen (z. B. mithilfe des SIGTERM-Handlers) immer einen aussagekräftigen Rückgabecode bereitstellt, ist für die ordnungsgemäße Diagnose des Geräteverhaltens unerlässlich, insbesondere aus den Absturzabbildtelemetriedaten des Geräts. Weitere Informationen finden Sie unter Exitcodes und Sammeln und Interpretieren von Fehlerdaten.
  • Stellen Sie sicher, dass Fehlerfälle immer zum Beenden oder Absturz der Anwendung führen und nicht zu einem Deadlockzustand: Eine aufwendige Fehlerwiederherstellungslogik kann kontraproduktiv sein, da sie Zu Fehlern oder Verhaltensweisen führen kann, die zu einem Deadlock oder einem Zustand führen, der schwer zu diagnostizieren ist. Eine gut entworfene Azure Sphere-Anwendung sollte immer das Abstürzen oder Beenden (mit einem Exitcode ungleich Null) einer potenziellen Deadlocksituation vorziehen, da dies zu beidem führt:
    • Fehlertelemetrie, aktivieren Diagnose für dieses Problem
    • Die Möglichkeit einer sofortigen Wiederherstellung in einen funktionierenden Zustand, da das Azure Sphere-Betriebssystem die Anwendung neu startet
  • Fehlerbehandlung und -protokollierung: Eine präzise Fehlerbehandlung und -protokollierung sind der Kern einer qualitativ hochwertigen Anwendungsentwicklung. Schnelle Funktionsimplementierungen können in Codeebenen verborgen bleiben und dann mit der Entwicklung der Anwendung bis zur vollständigen Skalierung überbaut werden. Weitere Informationen zu bewährten Methoden finden Sie unter Fehlerbehandlung und -protokollierung.
  • Verwenden Sie einen Systemtimer als Watchdog: Eine der wichtigsten bewährten Methoden besteht darin, einen "Watchdog-Timer"-Rückruf zu implementieren (ähnlich wie die hardwarebasierten, die in Bare-Metal-MCUs verfügbar sind), der kritische Anwendungszustände nachverfolgt, Deadlocks erkennt und entsprechend handelt (z. B. Beenden und Senden von Telemetriedaten). Weitere Informationen finden Sie unter Verwenden eines Systemtimers als Watchdog.
  • Stellen Sie niemals Produktionsanwendungen bereit, die für ein Beta-Release-Toolset erstellt wurden: Die Verwendung von Beta-Release-Toolsets wird nicht empfohlen, da nicht garantiert werden kann, dass sich die Betateilmenge in nachfolgenden Betriebssystemversionen nicht ändert. Beta-Toolsets werden ausschließlich zum Testen neuer Features vor einem offiziellen SDK-Release veröffentlicht.

Behandeln von Parallelität

  • Verwenden Sie EventLoop wann immer möglich: Threads und Synchronisierungsobjekte (d. h. Mutexe, Semaphore usw.) werden verwendet, um nahezu gleichzeitige Aufgaben auszuführen, aber in eingebetteten Systemen sind diese in Bezug auf die Nutzung von Systemressourcen teuer. Um die Leistung zu verbessern, sollten Sie daher die Verwendung von epolls anstelle von Threads für aufgaben in Betracht ziehen, die nicht unbedingt zeitkritisch sind und nicht empfindlich auf gegenseitiges Blockieren sind. Informationen zum Überwachen und Verteilen von Ereignissen mit EventLoop, einschließlich zugehöriger Beispiele, finden Sie unter Applibs eventloop.h.
  • Suchen Sie nach Effizienz bei gleichzeitigen Aufgaben: Es ist wichtig sicherzustellen, dass blockierende Vorgänge und Timeouts innerhalb von epoll-Rückrufen auf ein Minimum beschränkt werden, da andernfalls alle anderen epoll-Rückrufe betroffen sind.
  • Verwendung von Threads (Pthread): Für bestimmte Szenarien, z. B. wenn das Blockieren von Aufrufen unvermeidlich ist, kann die Verwendung von Threads von Vorteil sein, obwohl diese Szenarien in der Regel eine begrenzte Lebensdauer haben und auf bestimmte Aufgaben beschränkt sein sollten. Da beispielsweise das Azure Sphere-Betriebssystem (unter Linux) IRQs nicht für HL-Kernanwendungen verfügbar macht (dies ist nur für RT-Core-Apps verfügbar), könnte die Verwendung einer Kombination aus epoll- und pthread-Tasks optimal für die Verarbeitung von z. B. einer nachgeschalteten seriellen Kommunikation beim Herunterladen von Daten aus dem Internet sein.

Wichtig

Das Azure Sphere-Betriebssystem kann rechtzeitige Vorgänge unterbrechen, insbesondere wenn es einen Gerätenachweis durchführt, nach Updates sucht oder Telemetriedaten hochlädt. Für zeitkritische Steuerungsaufgaben sollten Sie diese in die M4-Kerne verschieben und mit einem geeigneten Protokoll über das Kernpostfach koordinieren. Weitere Informationen finden Sie im Beispiel für die Kommunikation zwischen Kernen.

Lesen Sie zusätzlich zu diesen Vorschlägen die Azure Sphere-Dokumentation zu asynchronen Ereignissen und Parallelität.

Konnektivitätsüberwachung

Eine gut konzipierte Hl-Kernanwendung muss einen ordnungsgemäßen Task zur Überprüfung der Konnektivitätsintegrität implementieren, der auf einem stabilen Zustandscomputer basieren sollte, der die status der Internetverbindung regelmäßig überprüft (für instance mithilfe eines epoll-Timers), indem die Networking_IsNetworkingReady-API verwendet wird. In einigen Fällen können Sie die Networking_GetInterfaceConnectionStatus-Funktion verwenden, da sie eine ausführlichere status des Konnektivitätszustands im Zusammenhang mit einer bestimmten Netzwerkschnittstelle bereitstellt, die die HL-Core-Anwendung verwenden kann, um ihren Zustand besser zu behandeln, obwohl dies mit Kosten verbunden ist, da es nicht empfohlen wird, sie häufiger als alle 90 Sekunden aufzurufen.

Der Zustandsautomatenrückruf sollte in der Regel die folgenden Attribute aufweisen:

  • Führen Sie so schnell wie möglich aus.
  • Das Abrufintervall muss sorgfältig entworfen werden, basierend auf dem spezifischen Anwendungsszenario und den allgemeinen Lösungsanforderungen (z. B. konstante Zeit, inkrementelle Verzögerung usw.).
  • Sobald eine Trennung erkannt wurde, kann es nützlich sein, Networking_GetInterfaceConnectionStatus einmal aufzurufen, um den Zustand der spezifischen Netzwerkschnittstelle zu protokollieren, der verwendet werden kann, um das Problem zu diagnostizieren und den Benutzer über eine Benutzeroberfläche zu benachrichtigen (z. B. LEDs, Anzeige, Terminal). Ein Beispiel für diesen Ansatz finden Sie im Standard Code des Azure Sphere-DHCP-Beispiels.
  • Aktivieren Sie einen Mechanismus (z. B. über eine globale Variable), der alle anderen Aufgaben in der HL-Core-Anwendung anhält, die Netzwerkkommunikation durchführen (oder daran gebunden sind), um den Ressourcenverbrauch zu optimieren, bis eine Verbindung wiederhergestellt wird.
  • cURL hat kürzlich das Rückrufverhalten und bewährte Methoden aktualisiert. Während Azure Sphere anstrengungen unternommen hat, um sicherzustellen, dass ältere Versionen von cURL Verhalten weiterhin wie erwartet funktionieren, wird empfohlen, bei der Verwendung von curl_multi die neuesten Anleitungen zur Sicherheit und Zuverlässigkeit zu befolgen, da die Verwendung rekursiver Rückrufe zu unerwarteten Abstürzen, Konnektivitätsausfällen und potenziellen Sicherheitsrisiken führen kann. Wenn ein TimerCallback mit einem Timeout von 0 ms ausgelöst wird, behandeln Sie ihn als Timeout von 1 ms, um rekursive Rückrufe zu vermeiden. Achten Sie darauf, dass Sie curl_multi_socket_action nach Aufrufen von curl_multi_add_handle mindestens einmal explizit aufrufen.

Zusätzlich zu den vorherigen Vorschlägen sollten Sie die folgenden Szenarien für die Energieverwaltung berücksichtigen:

  • Schalten Sie den Azure Sphere-Chip nach dem Senden von Daten herunter. Weitere Informationen finden Sie unter Verwalten des Herunterschaltzustands für Azure Sphere-Geräte.
  • Da mehrere Probleme durch lange exponentielle Backofftimeouts verursacht werden können, ist es wichtig, die Gesamtbetriebszeit nachzuverfolgen und einen Timer für das Herunterfahren auf ein angemessenes Limit festzulegen, um den Akku in Bedingungen, in denen die Konnektivität aufgrund externer Ausfälle oder anderer Faktoren außerhalb der Kontrolle der Anwendung nicht mehr möglich ist, nicht mehr zu entleeren.
  • Bei der Steuerung der Konnektivitätsüberwachung bei Ausfällen kann der Wi-Fi Transceiver heruntergefahren werden, indem die wlan0 Netzwerkschnittstelle deaktiviert wird (siehe Networking_SetInterfaceState und warten, bis die nächste Überprüfung der Konnektivität erneut erfolgt, wodurch ungefähr 100 mW eingespart werden.

Speicherverwaltung und -nutzung

Auf Plattformen mit eingeschränktem Arbeitsspeicher könnten Anwendungen, die häufige Speicherbelegungen und -aufhebungen durchführen, dazu führen, dass die Speicherverwaltung des Betriebssystems mit der Effizienz zu kämpfen hat, was zu einer übermäßigen Fragmentierung und Arbeitsspeicherauslastung führt. Insbesondere bei Azure Sphere MT3620 kann dies zu Nicht-Arbeitsspeicher-Bedingungen führen, die den OOM-Killer cgroup des Azure Sphere-Betriebssystems auslösen können.

Verständlicherweise werden Anwendungen häufig aus einem anfänglichen Proof-of-Concept entwickelt, der mit Features, die für progressive Releases erforderlich sind, umfassender wird und schließlich kleinere Features vernachlässigt, die ursprünglich enthalten waren. Im Folgenden sind Vorschläge und Optimierungen aufgeführt, die sich für viele Szenarien bewährt haben, die vor Ort analysiert wurden:

  • Insbesondere in HL-Kernanwendungen, die den Arbeitsspeicher intensiv nutzen, ist es wichtig, die Speicherauslastung der Anwendung über die Azure Sphere-API nachzuverfolgen, die unter Bestimmen der Ram-Auslastung der Laufzeitanwendung beschrieben wird. In der Regel wird dies in einem Epoll-Timer-Watchdog implementiert, und die Anwendung reagiert entsprechend auf eine unerwartete Speicherauslastung, um einen Neustart in angemessener Weise durchzuführen. z. B. das Beenden mit dem entsprechenden Exitcode.

    Mehrere Kunden und Partner haben es als nützlich erachtet, das Speichernachverfolgungs-Hilfsprogramm Heap Tracker zu verwenden, das im Azure Sphere-Katalog veröffentlicht wird. Diese Bibliothek ist transparent mit einer vorhandenen HL-Kernanwendung verknüpft und verfolgt Speicherbelegungen und die zugehörigen Zeiger nach, sodass die meisten Fälle von Speicherverlusten und Zeigermissbrauch vereinfacht erkannt werden können.

Wichtig

Diese Vorgehensweise kann scheinbar unerklärliche Nicht reagierende Geräte oder Fehler reduzieren, die häufig vor Ort gemeldet werden. Solche Fehler werden in der Regel durch Speicherverluste oder Überläufe verursacht, die von der HL-Core-Anwendung nicht ordnungsgemäß behandelt werden und den OOM-Killer dazu veranlassen, den Prozess der Anwendung herunterzufahren. Dies kann zusammen mit einer schlechten Konnektivität, die das Senden von Telemetriedaten durch das Azure Sphere-Betriebssystem verhindert, zu potenziellen Feldvorfällen führen, da die Diagnose nur durch Pullen der Diagnoseprotokolle des Azure Sphere-Betriebssystems erkannt werden kann.

  • Auf Plattformen mit eingeschränktem Arbeitsspeicher ist es im Allgemeinen vorzuziehen, die dynamische Speicherbelegung nach Möglichkeit zu vermeiden, insbesondere innerhalb häufig aufgerufener Funktionen. Dadurch wird die Speicherfragmentierung des Heaps und die Wahrscheinlichkeit weiterer Heapzuordnungsfehler erheblich reduziert. Erwägen Sie auch einen Paradigmenwechsel von der wiederholten Zuweisung temporärer Arbeitspuffer zum direkten Zugriff auf den Stapel (für Variablen mit angemessener Größe) oder global zugewiesenen Puffern, die bei Einem Überlauf (bis realloc) größer werden (siehe Dynamische Container und Puffer). Wenn es eine Anforderung zum Auslagern von Arbeitsspeicher gibt, sollten Sie erwägen, nicht genutzten Arbeitsspeicher auf den M4-Kernen zu nutzen (siehe Verfügbarer Arbeitsspeicher in Azure Sphere), die jeweils 256 KiB haben, mit einer einfachen RT-Core-Anwendung für das Zwischenspeichern von Daten. Sie könnten schließlich externe SD-Karten oder Flash verwenden. Beispiele finden Sie in den folgenden Repositorys:

Das Befolgen der obigen Vorschläge kann auch dazu beitragen, den Arbeitsspeicher zu schätzen und zu reservieren, der benötigt wird, damit die HL-Core-Anwendung während des gesamten Lebenszyklus mit voller Kapazität arbeitet, während Sie den gesamtspeicherbedarf der Anwendung für spätere Entwurfsoptimierungen besser einschätzen können. Weitere Informationen zum Optimieren der Speicherauslastung in HL-Core-Anwendungen, einschließlich Features im Azure Sphere-Betriebssystem und Visual Studio, finden Sie in den folgenden Artikeln: