{"id":135884,"date":"2018-08-03T15:07:00","date_gmt":"2018-08-03T12:07:00","guid":{"rendered":"https:\/\/ruuvi.com\/ruuvi-firmware-teil-2-debugging\/"},"modified":"2026-06-11T08:48:58","modified_gmt":"2026-06-11T05:48:58","slug":"ruuvi-firmware-teil-2-debugging","status":"publish","type":"post","link":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/","title":{"rendered":"Ruuvi Firmware \u2013 Teil 2: Debugging"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"536\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging-1024x536.jpeg\" alt=\"Ruuvi Firmware Debugging\" class=\"wp-image-3550\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging-1024x536.jpeg 1024w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging-450x236.jpeg 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging-768x402.jpeg 768w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging-600x314.jpeg 600w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging.jpeg 1400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Dies ist der zweite Teil der Ruuvi-Firmware-Serie, die detailliert beschreibt, wie man eine Sensor-Beacon-Software erstellt, die auf dem RuuviTag mit <a href=\"https:\/\/lab.ruuvi.com\/ses\">Segger Embedded Studio<\/a> l\u00e4uft. Den finalen Code dieses Blogbeitrags kannst du bei <a href=\"https:\/\/github.com\/ruuvi\/ruuvi.firmware.c\">Ruuvi GitHub<\/a> im <em>ruuviblog<\/em>-Branch, Tag <em>3.2.0-alpha<\/em>, herunterladen. Folge bitte <a href=\"https:\/\/ruuvi.com\/ruuvi-firmware-part-1-sleep\/\">Teil 1 der Serie<\/a> f\u00fcr Details zum Klonen des Repositorys und Kompilieren des Codes.  <\/p>\n\n<h2 class=\"wp-block-heading\">Die L\u00fccken f\u00fcllen<\/h2>\n\n<p class=\"wp-block-paragraph\">Im letzten Teil der Serie hatte unsere Codebasis bereits einige Stubs zum Zur\u00fcckgeben von Statuscodes vom Treiber sowie zum Kompilieren des Projekts mit ARMGCC ohne SES. Lass uns diese Abschnitte des Codes ausf\u00fcllen und Logging-Funktionalit\u00e4t hinzuf\u00fcgen. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"414\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-c-architecture-3-2-0.png\" alt=\"Ruuvi Firmware.c Architektur 3.2.0\" class=\"wp-image-3551\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-c-architecture-3-2-0.png 414w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-c-architecture-3-2-0-150x150.png 150w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-c-architecture-3-2-0-300x300.png 300w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-c-architecture-3-2-0-100x100.png 100w\" sizes=\"auto, (max-width: 414px) 100vw, 414px\" \/><figcaption>Teile in Blau wurden bereits zuvor eingef\u00fchrt, wir konzentrieren uns auf die Teile in Gr\u00fcn. Verlaufsbl\u00f6cke werden \u00c4nderungen aufweisen. <\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Logging<\/h2>\n\n<h3 class=\"wp-block-heading\">Logging-Schnittstelle<\/h3>\n\n<p class=\"wp-block-paragraph\">Das Nordic SDK verf\u00fcgt \u00fcber ausgezeichnete Debug-Log-Makros, allerdings ist das \u00dcbergeben von Argumenten an Makros durch Funktionsaufrufe etwas knifflig. Daher machen wir einige Kompromisse und implementieren Logging als Funktionsaufrufe und rufen die Makros in der Plattformimplementierung auf. <\/p>\n\n<p class=\"wp-block-paragraph\">Wir definieren vier Schweregrade: <strong>Error<\/strong>, <strong>Warning<\/strong>, <strong>Info<\/strong> und <strong>Debug<\/strong>. Unsere <em>init<\/em>-Funktion nimmt den gew\u00fcnschten Mindestschweregrad als Parameter. Wir implementieren auch ein <em>flush<\/em>, das die Logs aus allen Puffern schreibt, sowie eine Fehlercode-zu-String-Funktion, die eine menschenlesbare Beschreibung der Fehler liefert.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"687\" height=\"838\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-h.png\" alt=\"ruuvi_interface_log.h\" class=\"wp-image-3552\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-h.png 687w, https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-h-369x450.png 369w, https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-h-600x732.png 600w\" sizes=\"auto, (max-width: 687px) 100vw, 687px\" \/><figcaption>ruuvi_interface_log.h<\/figcaption><\/figure><\/div>\n\n<h3 class=\"wp-block-heading\">Logging-Implementierung<\/h3>\n\n<p class=\"wp-block-paragraph\">Zuerst f\u00fcllen wir die plattformunabh\u00e4ngige Funktion <em>ruuvi_platform_error_to_string<\/em> aus. Ich halte die Implementierung f\u00fcr ziemlich unelegant \u2013 wir haben ein festes Switch-Case von <em>ruuvi_driver_status_t<\/em>-Labels und f\u00fcllen die Werte ein. Falls jemand eine Implementierung entwickeln kann, die die Labels aus der <em>enum<\/em>-Definition liest und sie mit <em>snprintf<\/em> zum Pointer schreibt, lass es mich bitte wissen \u2013 oder noch besser: \u00d6ffne einen Pull Request. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"708\" height=\"391\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-c-beginning.png\" alt=\"ruuvi_interface_log.c &#x2013; Dateianfang\" class=\"wp-image-3553\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-c-beginning.png 708w, https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-c-beginning-450x249.png 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-log-c-beginning-600x331.png 600w\" sizes=\"auto, (max-width: 708px) 100vw, 708px\" \/><figcaption>ruuvi_interface_log.c \u2013 Dateianfang<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Zweitens tauchen wir in die Nordic-SDK-Implementierung der Logging-Funktionen ein. Das Nordic SDK verf\u00fcgt \u00fcber eine ganze Reihe von Makros, die Zeitstempel, Dateinamen, Modulnamen einf\u00fcgen und eine gro\u00dfartige Granularit\u00e4t f\u00fcr die Fehlerberichterstattung bieten k\u00f6nnen. Um die Sache noch besser zu machen, sind sie als Makros implementiert, die nicht kompiliert werden, wenn Logging deaktiviert ist.  <\/p>\n\n<p class=\"wp-block-paragraph\">Unsere Implementierung ist viel einfacher \u2013 wir nehmen einen Funktionsaufruf entgegen und leiten ihn an das Nordic-Makro weiter. Theoretisch k\u00f6nnte unser Compiler bemerken, dass unsere <em>ruuvi_platform_log<\/em>-Funktion nichts zur\u00fcckgibt und keine Seiteneffekte hat, was bedeutet, dass sie als <strong>NOP<\/strong> optimiert werden k\u00f6nnte, wenn wir Logging deaktivieren. In der Praxis w\u00fcrden wir Linking-Fehler bekommen, da unsere Funktionen Funktionen und keine Makros sind. Vielleicht implementieren wir sp\u00e4ter ein Dummy-Logging-Backend, das eine leere Funktion sein wird, um das Deaktivieren des Loggings zu erm\u00f6glichen.   <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"538\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-log-c-nRF5-SDK15.png\" alt=\"ruuvi_platform_log.c der nRF5-SDK15-Plattform\" class=\"wp-image-3554\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-log-c-nRF5-SDK15.png 414w, https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-log-c-nRF5-SDK15-346x450.png 346w\" sizes=\"auto, (max-width: 414px) 100vw, 414px\" \/><figcaption>ruuvi_platform_log.c der nRF5-SDK15-Plattform<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Unsere Logging-Funktion ruft das Nordic-RAW-Makro auf, das keine weitere Pr\u00e4fixierung oder Zeitstempelung der Nachricht vornimmt. Falls die Nachricht aus irgendeinem Grund null war, geben wir eine Warnung aus und lassen den Programmfluss fortsetzen. <\/p>\n\n<h2 class=\"wp-block-heading\">Statuscodes<\/h2>\n\n<h3 class=\"wp-block-heading\">Fehler-Schnittstelle<\/h3>\n\n<p class=\"wp-block-paragraph\">Wir m\u00f6chten Fehler so fr\u00fch wie m\u00f6glich abfangen, sowohl w\u00e4hrend der Entwicklung als auch in der Produktion. Daher geben wir den Status von den Funktionen zur\u00fcck und pr\u00fcfen den Status im Programm. Wir erlauben auch, einige Fehler als nicht-fatal zu definieren: Wenn beispielsweise ein Umgebungssensor nicht gefunden wird, k\u00f6nnen wir den Status akzeptieren und fortfahren. Wenn jedoch ein Umgebungssensor gefunden wird und den Selbsttest nicht besteht, sollten wir den Tag als fehlerhaft betrachten und das Programm stoppen.   <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"873\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-driver-error-h.png\" alt=\"ruuvi_driver_error.h\" class=\"wp-image-3555\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-driver-error-h.png 764w, https:\/\/ruuvi.com\/i\/u\/ruuvi-driver-error-h-394x450.png 394w, https:\/\/ruuvi.com\/i\/u\/ruuvi-driver-error-h-600x686.png 600w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><figcaption>ruuvi_driver_error.h<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Die Fehlercodes sind als Bit-Flags definiert, und wir verwenden int32_t statt uint32_t als Container, um dem h\u00f6chsten Bit eine besondere Bedeutung <em>fatal<\/em> zu geben.<\/p>\n\n<h3 class=\"wp-block-heading\">Fehler-Implementierung<\/h3>\n\n<p class=\"wp-block-paragraph\">Fehlerpr\u00fcfung und -konvertierung haben nichts Komplexes an sich. Wir \u00e4ndern die Werte vom Nordic SDK zu Ruuvi-Werten in der Konvertierungsfunktion. Die Fehlerpr\u00fcfungsfunktion vergleicht den Fehlercode mit der Nicht-Fatal-Maske, und wenn ein Fehler aufgetreten ist, der als fatal betrachtet wird, loggen wir einen Fehler und setzen zur\u00fcck. Wenn ein nicht-fataler Fehler aufgetreten ist, loggen wir eine Warnung und fahren fort. Wenn kein Fehler aufgetreten ist, fahren wir fort, ohne etwas zu loggen.    <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"538\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-log-c-nRF5-SDK15-1.png\" alt=\"ruuvi_platform_error.c in der Nordic-SDK15-Plattformimplementierung\" class=\"wp-image-3556\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-log-c-nRF5-SDK15-1.png 414w, https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-log-c-nRF5-SDK15-1-346x450.png 346w\" sizes=\"auto, (max-width: 414px) 100vw, 414px\" \/><figcaption>ruuvi_platform_error.c in der Nordic-SDK15-Plattformimplementierung<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Konfiguration der Logs<\/h2>\n\n<p class=\"wp-block-paragraph\">Da wir das Nordic-Backend verwenden, m\u00fcssen wir einige Konfigurationen hinzuf\u00fcgen. Wir beginnen damit, die Anwendungskonfiguration application_config.h hinzuzuf\u00fcgen und dort Logging-Konstanten zu definieren. W\u00e4hrend wir dabei sind, f\u00fcgen wir auch die <em>GPIO<\/em>&#8211; und <em>yield<\/em>-Aktivierungen zu unserer Anwendungskonfiguration hinzu und verweisen in ruuvi_platform_nrf5_sdk15_config.h darauf.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"207\" height=\"206\" src=\"https:\/\/ruuvi.com\/i\/u\/application-config-h.png\" alt=\"application_config.h\" class=\"wp-image-3557\" srcset=\"https:\/\/ruuvi.com\/i\/u\/application-config-h.png 207w, https:\/\/ruuvi.com\/i\/u\/application-config-h-150x150.png 150w, https:\/\/ruuvi.com\/i\/u\/application-config-h-100x100.png 100w\" sizes=\"auto, (max-width: 207px) 100vw, 207px\" \/><figcaption>application_config.h<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Dann aktualisieren wir die nrf5_sdk15_application_config.h. Da das Nordic SDK erwartet, dass die Log-Puffergr\u00f6\u00dfe mindestens 128 Bytes und eine Zweierpotenz ist, f\u00fcgen wir eine Plausibilit\u00e4tspr\u00fcfung f\u00fcr die Puffergr\u00f6\u00dfe hinzu. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"855\" height=\"393\" src=\"https:\/\/ruuvi.com\/i\/u\/nrf5-sdk15-application-config-h.png\" alt=\"nrf5_sdk15_application_config.h\" class=\"wp-image-3558\" srcset=\"https:\/\/ruuvi.com\/i\/u\/nrf5-sdk15-application-config-h.png 855w, https:\/\/ruuvi.com\/i\/u\/nrf5-sdk15-application-config-h-450x207.png 450w, https:\/\/ruuvi.com\/i\/u\/nrf5-sdk15-application-config-h-768x353.png 768w, https:\/\/ruuvi.com\/i\/u\/nrf5-sdk15-application-config-h-600x276.png 600w\" sizes=\"auto, (max-width: 855px) 100vw, 855px\" \/><figcaption>nrf5_sdk15_application_config.h<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Logging und Fehlerpr\u00fcfung zur Anwendung hinzuf\u00fcgen<\/h2>\n\n<p class=\"wp-block-paragraph\">Wir integrieren den neuen Code in unsere Hauptanwendung, indem wir den Statuscode von den Initialisierungsfunktionen sammeln. Da unser Statuscode ein Bit-Flag ist, k\u00f6nnen wir neue Fehler mit <strong>OR<\/strong> hinzuf\u00fcgen, w\u00e4hrend wir im Programm fortschreiten. Wir f\u00fcgen auch etwas Logging hinzu, um die Log-Funktionen zu demonstrieren.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"940\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-part2.png\" alt=\"Code von main.c\" class=\"wp-image-3559\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-part2.png 835w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-part2-400x450.png 400w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-part2-768x865.png 768w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-part2-600x675.png 600w\" sizes=\"auto, (max-width: 835px) 100vw, 835px\" \/><figcaption>main.c<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Zeile 57 zeigt, wie man Laufzeitwerte im Log mit <em>snprintf<\/em> ausgibt. Lass uns den Code ausf\u00fchren und sehen, was passiert! <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"966\" height=\"739\" src=\"https:\/\/ruuvi.com\/i\/u\/running-code-fatal-error.png\" alt=\"Code ausf&#xFC;hren &#x2013; fataler Fehler bei der Initialisierung und Neustartzyklus.\" class=\"wp-image-3560\" srcset=\"https:\/\/ruuvi.com\/i\/u\/running-code-fatal-error.png 966w, https:\/\/ruuvi.com\/i\/u\/running-code-fatal-error-450x344.png 450w, https:\/\/ruuvi.com\/i\/u\/running-code-fatal-error-768x588.png 768w, https:\/\/ruuvi.com\/i\/u\/running-code-fatal-error-600x459.png 600w\" sizes=\"auto, (max-width: 966px) 100vw, 966px\" \/><figcaption>Code ausf\u00fchren \u2013 fataler Fehler bei der Initialisierung und Neustartzyklus.<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Die gute Nachricht ist: Unsere Fehlerpr\u00fcfung funktioniert wie beabsichtigt. Die andere gute Nachricht ist, dass wir einen Bug im Code von Teil 1 gefunden haben \u2013 aus irgendeinem Grund gibt die <em>yield<\/em>-Initialisierung <strong>INVALID_STATE<\/strong> zur\u00fcck. <\/p>\n\n<h2 class=\"wp-block-heading\">Tiefer graben, um die Fehlerquelle zu finden<\/h2>\n\n<p class=\"wp-block-paragraph\">Jetzt wissen wir, dass es einen Fehler in unserem <em>yield<\/em>-Code gibt, wir wissen jedoch nicht, was der Fehler ist oder wie er uns betrifft. Schlie\u00dflich hatten wir am Ende von Teil 1 einen perfekt funktionierenden Sleep-Modus. Unser Logging hat den Fehler zwischen den Zeilen 21 und 25 von main.c lokalisiert, und dort gibt es nichts anderes als die Yield-Initialisierung. Setzen wir einen <em>Breakpoint<\/em> bei <em>yield<\/em> und gehen mit <em>Step In<\/em> in die Funktion.   <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"167\" src=\"https:\/\/ruuvi.com\/i\/u\/halted-yield-1024x167.png\" alt=\"\" class=\"wp-image-3561\" srcset=\"https:\/\/ruuvi.com\/i\/u\/halted-yield-1024x167.png 1024w, https:\/\/ruuvi.com\/i\/u\/halted-yield-450x73.png 450w, https:\/\/ruuvi.com\/i\/u\/halted-yield-768x125.png 768w, https:\/\/ruuvi.com\/i\/u\/halted-yield-600x98.png 600w, https:\/\/ruuvi.com\/i\/u\/halted-yield.png 1185w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Unser Programm wurde in yield init angehalten (jetzt Zeile 25) und wir sind bereit, mit F11 \/ Klick auf das erhobene Symbol hineinzugehen.<\/figcaption><\/figure><\/div>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"97\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-yield-c-1024x97.png\" alt=\"\" class=\"wp-image-3562\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-yield-c-1024x97.png 1024w, https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-yield-c-450x43.png 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-yield-c-768x73.png 768w, https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-yield-c-600x57.png 600w, https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-yield-c.png 1184w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>ruuvi_platform_yield.c \u2013 lass uns ins nRF SDK gehen<\/figcaption><\/figure><\/div>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"225\" src=\"https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-1024x225.png\" alt=\"\" class=\"wp-image-3563\" srcset=\"https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-1024x225.png 1024w, https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-450x99.png 450w, https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-768x169.png 768w, https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-600x132.png 600w, https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c.png 1193w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>nrf_pwr_mgmt.c \u2013 Was macht dieses PWR_MGNT_TIMER_CREATE?<\/figcaption><\/figure><\/div>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"398\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-create-timer-1024x398.png\" alt=\"\" class=\"wp-image-3564\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-create-timer-1024x398.png 1024w, https:\/\/ruuvi.com\/i\/u\/ruuvi-create-timer-450x175.png 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-create-timer-768x298.png 768w, https:\/\/ruuvi.com\/i\/u\/ruuvi-create-timer-600x233.png 600w, https:\/\/ruuvi.com\/i\/u\/ruuvi-create-timer.png 1189w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Wie der Name vermuten l\u00e4sst, versuchen wir, einen Timer in der Timer-Erstellungsfunktion zu erstellen.<\/figcaption><\/figure><\/div>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"351\" src=\"https:\/\/ruuvi.com\/i\/u\/app-timer-c-1024x351.png\" alt=\"\" class=\"wp-image-3565\" srcset=\"https:\/\/ruuvi.com\/i\/u\/app-timer-c-1024x351.png 1024w, https:\/\/ruuvi.com\/i\/u\/app-timer-c-450x154.png 450w, https:\/\/ruuvi.com\/i\/u\/app-timer-c-768x264.png 768w, https:\/\/ruuvi.com\/i\/u\/app-timer-c-600x206.png 600w, https:\/\/ruuvi.com\/i\/u\/app-timer-c.png 1183w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>app_timer.c \u2013 wir haben den \u00dcbelt\u00e4ter gefunden.<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">An diesem Punkt haben wir den Fehler lokalisiert. Unsere <em>yield<\/em>-Initialisierung pr\u00fcft, ob wir das <em>timer<\/em>-Modul initialisiert haben, und das haben wir nicht getan. Warum braucht unser Sleep Timer? Kehren wir zu <em>nrf_pwr_mgmt.c<\/em> zur\u00fcck, um das herauszufinden.   <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"644\" src=\"https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-long.png\" alt=\"\" class=\"wp-image-3566\" srcset=\"https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-long.png 414w, https:\/\/ruuvi.com\/i\/u\/nrf-pwr-mgmt-c-long-289x450.png 289w\" sizes=\"auto, (max-width: 414px) 100vw, 414px\" \/><figcaption>nrf_pwr_mgmt.c<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Ein paar Zeilen vor dem Fehler sehen wir eine Pr\u00fcfung f\u00fcr <strong>NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY<\/strong>, die das <strong>PWR_MGMT_TIMER_REQUIRED<\/strong> definiert. Wir haben an diesem Punkt keinen Bedarf f\u00fcr irgendwelche automatischen Shutdown-Wiederholungen, also deaktivieren wir es in <em>nrf5_sdk15_application_config.h<\/em>. Jetzt sind wir bereit f\u00fcr einen weiteren Versuch mit unserer Anwendung.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"745\" height=\"1024\" src=\"https:\/\/ruuvi.com\/i\/u\/final-main-c-745x1024.png\" alt=\"\" class=\"wp-image-3567\" srcset=\"https:\/\/ruuvi.com\/i\/u\/final-main-c-745x1024.png 745w, https:\/\/ruuvi.com\/i\/u\/final-main-c-327x450.png 327w, https:\/\/ruuvi.com\/i\/u\/final-main-c-768x1055.png 768w, https:\/\/ruuvi.com\/i\/u\/final-main-c-600x824.png 600w, https:\/\/ruuvi.com\/i\/u\/final-main-c.png 834w\" sizes=\"auto, (max-width: 745px) 100vw, 745px\" \/><figcaption>Finale main.c<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Jetzt sind wir n\u00e4her an dem, was man erwarten k\u00f6nnte. Unsere Initialisierung endet in <strong>RUUVI_DRIVER_SUCCESS<\/strong> und der Tag geht in den Sleep-Modus. Merkw\u00fcrdigerweise wachen wir einmal auf und gehen dann wieder schlafen. Vielleicht haben wir einen Interrupt, wenn das Log-Printing beendet ist?   <\/p>\n\n<h2 class=\"wp-block-heading\">Letzte Feinheiten<\/h2>\n\n<h3 class=\"wp-block-heading\">Stromverbrauch<\/h3>\n\n<p class=\"wp-block-paragraph\">Wie immer ist der Stromverbrauch der treibende Faktor in unserem Code. Es besteht eine gute Chance, dass wir nach dem Aktivieren der Logging-Peripherie etwas zus\u00e4tzlich verbrauchen, also lass uns den finalen Stromverbrauch \u00fcberpr\u00fcfen. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1021\" height=\"801\" src=\"https:\/\/ruuvi.com\/i\/u\/power-consumption-3-6-ua.png\" alt=\"\" class=\"wp-image-3568\" srcset=\"https:\/\/ruuvi.com\/i\/u\/power-consumption-3-6-ua.png 1021w, https:\/\/ruuvi.com\/i\/u\/power-consumption-3-6-ua-450x353.png 450w, https:\/\/ruuvi.com\/i\/u\/power-consumption-3-6-ua-768x603.png 768w, https:\/\/ruuvi.com\/i\/u\/power-consumption-3-6-ua-600x471.png 600w\" sizes=\"auto, (max-width: 1021px) 100vw, 1021px\" \/><figcaption>Wir verbrauchen 3,6 \u03bcA<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Im vorherigen Teil kamen wir zu dem Schluss, dass unser Stromverbrauch 4,0 \u03bcA betrug, sodass es scheint, dass wir eine Verbesserung von 10 % ohne ersichtlichen Grund haben. Pers\u00f6nlich vermute ich, dass der Unterschied durch die Umgebungstemperatur verursacht wird \u2013 letzte Woche hatten wir eine Hitzewelle in Finnland, w\u00e4hrend die aktuelle Temperatur viel k\u00fchler ist. Nichts im Leistungsprofil gibt uns Anlass zur Sorge, da wir nicht mehr verbrauchen als zuvor.  <\/p>\n\n<h3 class=\"wp-block-heading\">ARMGCC &amp; Jenkins.<\/h3>\n\n<p class=\"wp-block-paragraph\">Wir richten auch ein ARMGCC-Ziel f\u00fcr Continuous Integration mit Jenkins ein. Nach diesem <a href=\"https:\/\/www.youtube.com\/watch?time_continue=12&amp;v=Z3S2gMBUkBo\">Video-Tutorial<\/a> m\u00fcssen wir <a href=\"https:\/\/developer.arm.com\/open-source\/gnu-toolchain\/gnu-rm\/downloads\/6-2017-q2-update\">ARMGCC 6-2017-q2-update<\/a> in <em>\/usr\/local<\/em> unseres Jenkins-Servers installieren, <a href=\"https:\/\/developer.nordicsemi.com\/nRF5_SDK\/nRF5_SDK_v15.x.x\/\">nRF5 SDK15<\/a> herunterladen und nach <em>\/var\/lib\/jenkins\/workspace\/<\/em> entpacken. <\/p>\n\n<p class=\"wp-block-paragraph\">Jetzt wird der Code jedes Mal, wenn ich Code in meinen pers\u00f6nlichen Branch pushe, von GitHub gezogen und kompiliert. Dies stellt sicher, dass jeder Zugriff auf eine funktionierende Version mit allen aktuellen Submodulen hat. Es erm\u00f6glicht auch jedem, den Build-Status auf einen Blick in der README zu sehen. Schlie\u00dflich speichern wir die von ARMGCC erstellte kompilierte .hex-Datei und lassen jeden sie von <a href=\"http:\/\/jenkins.ruuvi.com\/job\/ruuvi.firmware.c\/\">http:\/\/jenkins.ruuvi.com\/job\/ruuvi.firmware.c\/<\/a> herunterladen.<\/p>\n\n<p class=\"wp-block-paragraph\">Wenn du lieber ARMGCC anstelle von SES verwendest, kannst du jetzt \u201emake\u201c im Stammverzeichnis des Projekts ausf\u00fchren, um das Projekt zu kompilieren \u2013 vorausgesetzt, du hast die Build-Umgebung eingerichtet.<\/p>\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n<p class=\"wp-block-paragraph\">Nach diesem Tutorial haben wir eine grundlegende automatisierte und manuelle Qualit\u00e4tskontrolle f\u00fcr unser Projekt implementiert. Unsere Treiber geben Fehlercodes zur\u00fcck, die gepr\u00fcft und geloggt werden, falls es Anomalien gibt, und wir kompilieren den zu GitHub gepushten Code und speichern die resultierenden Ausgaben. Du solltest beachten, dass ARMGCC und SES unterschiedliche Linker-Skripte verwenden, was bedeutet, dass die resultierenden Hexes nicht unbedingt funktional identisch sind. Vielleicht verbessern wir dies in zuk\u00fcnftigen automatisierten Tests.   <\/p>\n\n<p class=\"wp-block-paragraph\"><strong>In der Zwischenzeit bleib dran und folge <\/strong><a href=\"https:\/\/twitter.com\/ojousima\"><strong>@ojousima<\/strong><\/a><strong> und <\/strong><a href=\"https:\/\/twitter.com\/ruuvicom\"><strong>@ruuvicom<\/strong><\/a><strong> auf Twitter f\u00fcr #FirmwareFriday-Posts!<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dies ist der zweite Teil der Ruuvi-Firmware-Serie, die detailliert beschreibt, wie man eine Sensor-Beacon-Software erstellt, die auf dem RuuviTag mit Segger Embedded Studio l\u00e4uft. Den finalen Code dieses Blogbeitrags kannst du bei Ruuvi GitHub im ruuviblog-Branch, Tag 3.2.0-alpha, herunterladen. Folge bitte Teil 1 der Serie f\u00fcr Details zum Klonen des Repositorys und Kompilieren des Codes. [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":135885,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[324],"tags":[],"class_list":["post-135884","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruuvi-software-artikel"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Ruuvi Firmware \u2013 Teil 2: Debugging - Ruuvi<\/title>\n<meta name=\"description\" content=\"Wie du von SDK-Debug-Log-Makros profitierst, wenn du Logging und Fehlerpr\u00fcfung zum Firmware-Code des RuuviTag hinzuf\u00fcgst.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ruuvi Firmware \u2013 Teil 2: Debugging - Ruuvi\" \/>\n<meta property=\"og:description\" content=\"Wie du von SDK-Debug-Log-Makros profitierst, wenn du Logging und Fehlerpr\u00fcfung zum Firmware-Code des RuuviTag hinzuf\u00fcgst.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/\" \/>\n<meta property=\"og:site_name\" content=\"Ruuvi\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ruuvi.cc\" \/>\n<meta property=\"article:published_time\" content=\"2018-08-03T12:07:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-11T05:48:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"1400\" \/>\n\t<meta property=\"og:image:height\" content=\"733\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Otso Jousimaa\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ruuvicom\" \/>\n<meta name=\"twitter:site\" content=\"@ruuvicom\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Otso Jousimaa\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"8\u00a0Minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/\"},\"author\":{\"name\":\"Otso Jousimaa\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\"},\"headline\":\"Ruuvi Firmware \u2013 Teil 2: Debugging\",\"datePublished\":\"2018-08-03T12:07:00+00:00\",\"dateModified\":\"2026-06-11T05:48:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/\"},\"wordCount\":1547,\"image\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-debugging.jpeg\",\"articleSection\":[\"Ruuvi-Software-Artikel\"],\"inLanguage\":\"de\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/\",\"name\":\"Ruuvi Firmware \u2013 Teil 2: Debugging - Ruuvi\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-debugging.jpeg\",\"datePublished\":\"2018-08-03T12:07:00+00:00\",\"dateModified\":\"2026-06-11T05:48:58+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\"},\"description\":\"Wie du von SDK-Debug-Log-Makros profitierst, wenn du Logging und Fehlerpr\u00fcfung zum Firmware-Code des RuuviTag hinzuf\u00fcgst.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/#primaryimage\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-debugging.jpeg\",\"contentUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-debugging.jpeg\",\"width\":1400,\"height\":733,\"caption\":\"Ruuvi Firmware Debugging\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-teil-2-debugging\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/front\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruuvi Firmware \u2013 Teil 2: Debugging\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/\",\"name\":\"Ruuvi\",\"description\":\"Measure Your World\",\"potentialAction\":[],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\",\"name\":\"Otso Jousimaa\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"caption\":\"Otso Jousimaa\"},\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/author\\\/ojousima\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Ruuvi Firmware \u2013 Teil 2: Debugging - Ruuvi","description":"Wie du von SDK-Debug-Log-Makros profitierst, wenn du Logging und Fehlerpr\u00fcfung zum Firmware-Code des RuuviTag hinzuf\u00fcgst.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/","og_locale":"de_DE","og_type":"article","og_title":"Ruuvi Firmware \u2013 Teil 2: Debugging - Ruuvi","og_description":"Wie du von SDK-Debug-Log-Makros profitierst, wenn du Logging und Fehlerpr\u00fcfung zum Firmware-Code des RuuviTag hinzuf\u00fcgst.","og_url":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/","og_site_name":"Ruuvi","article_publisher":"https:\/\/www.facebook.com\/ruuvi.cc","article_published_time":"2018-08-03T12:07:00+00:00","article_modified_time":"2026-06-11T05:48:58+00:00","og_image":[{"width":1400,"height":733,"url":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging.jpeg","type":"image\/jpeg"}],"author":"Otso Jousimaa","twitter_card":"summary_large_image","twitter_creator":"@ruuvicom","twitter_site":"@ruuvicom","twitter_misc":{"Verfasst von":"Otso Jousimaa","Gesch\u00e4tzte Lesezeit":"8\u00a0Minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/#article","isPartOf":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/"},"author":{"name":"Otso Jousimaa","@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00"},"headline":"Ruuvi Firmware \u2013 Teil 2: Debugging","datePublished":"2018-08-03T12:07:00+00:00","dateModified":"2026-06-11T05:48:58+00:00","mainEntityOfPage":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/"},"wordCount":1547,"image":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/#primaryimage"},"thumbnailUrl":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging.jpeg","articleSection":["Ruuvi-Software-Artikel"],"inLanguage":"de"},{"@type":"WebPage","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/","url":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/","name":"Ruuvi Firmware \u2013 Teil 2: Debugging - Ruuvi","isPartOf":{"@id":"https:\/\/ruuvi.com\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/#primaryimage"},"image":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/#primaryimage"},"thumbnailUrl":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging.jpeg","datePublished":"2018-08-03T12:07:00+00:00","dateModified":"2026-06-11T05:48:58+00:00","author":{"@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00"},"description":"Wie du von SDK-Debug-Log-Makros profitierst, wenn du Logging und Fehlerpr\u00fcfung zum Firmware-Code des RuuviTag hinzuf\u00fcgst.","breadcrumb":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/#primaryimage","url":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging.jpeg","contentUrl":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-debugging.jpeg","width":1400,"height":733,"caption":"Ruuvi Firmware Debugging"},{"@type":"BreadcrumbList","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-teil-2-debugging\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ruuvi.com\/de\/front\/"},{"@type":"ListItem","position":2,"name":"Ruuvi Firmware \u2013 Teil 2: Debugging"}]},{"@type":"WebSite","@id":"https:\/\/ruuvi.com\/de\/#website","url":"https:\/\/ruuvi.com\/de\/","name":"Ruuvi","description":"Measure Your World","potentialAction":[],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00","name":"Otso Jousimaa","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","caption":"Otso Jousimaa"},"url":"https:\/\/ruuvi.com\/de\/author\/ojousima\/"}]}},"_links":{"self":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135884","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/comments?post=135884"}],"version-history":[{"count":1,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135884\/revisions"}],"predecessor-version":[{"id":135893,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135884\/revisions\/135893"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/media\/135885"}],"wp:attachment":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/media?parent=135884"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/categories?post=135884"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/tags?post=135884"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}