{"id":9,"date":"2016-11-07T22:16:49","date_gmt":"2016-11-07T21:16:49","guid":{"rendered":"http:\/\/localhost\/arc\/wordpress\/?page_id=8"},"modified":"2017-04-08T10:03:07","modified_gmt":"2017-04-08T09:03:07","slug":"firmware","status":"publish","type":"page","link":"https:\/\/plauffs.de\/arc\/de\/arc1\/firmware\/","title":{"rendered":"Firmware"},"content":{"rendered":"<p><br \/>\nIm Folgenden sollen der grundlegende Aufbau und insbesondere die DCC-Signalerzeugung der ARC1 Firmware betrachtet werden. Die dargestellten Flussdiagramme sollen dabei zum leichteren Verst\u00e4ndnis der Abl\u00e4ufe dienen. Momentan sind die Flussdiagramme ausschlie\u00dflich auf Englisch verf\u00fcgbar, da auch die Code-Dokumentation rein Englisch gehalten ist.<\/p>\n<h4>Main Program<\/h4>\n<table style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"background-color: white; width: 216px; vertical-align: top;\"><a href=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_main.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_main.png\" alt=\"arc1_firmware_main\" width=\"325\" height=\"893\" \/><\/a><\/td>\n<td style=\"background-color: white; vertical-align: top;\"><a href=\"http:\/\/plauffs.de\/arc\/?page_id=9\/#systick\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_systick.png\" alt=\"arc1_firmware_systick\" width=\"332\" height=\"123\" \/><\/a><\/p>\n<p><a href=\"http:\/\/plauffs.de\/arc\/?page_id=9\/#dccman\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_dccman.png\" alt=\"arc1_firmware_dccman\" width=\"332\" height=\"123\" \/><\/a><\/p>\n<p><a href=\"http:\/\/plauffs.de\/arc\/?page_id=9\/#dccgen\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_dccgen.png\" alt=\"arc1_firmware_dccgen\" width=\"332\" height=\"123\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Nach dem Systemstart werden zun\u00e4chst alle Ger\u00e4tetreiber (z.B. f\u00fcr serielle Kommunikation, digitale Ein- \/ Ausg\u00e4nge, Flash, Timer etc.) und die auf dem Board oder extern befindlichen Komponenten initialisiert (BSP &#8211; Board Support Package). Dies sind bspw. Display, Touchscreen, SDRAM, LED Ring etc. Da die gesamte Firmware auf Basis eines statischen Schedulers und Timer-Interrupts arbeitet, m\u00fcssen auch diese entsprechend initialisiert und gestartet werden. Nach dem Laden aller gespeicherten Einstellungen und Lokomotiven aus dem nichtfl\u00fcchtigen Flash-Speicher des Prozessors geht die Firmware in den Betriebsmodus \u00fcber und der statische Scheduler steuert die zeitliche Ausf\u00fchrung verschiedener Programmteile. Im wesentlichen ist das der 100Hz-Task zur Erfassung der Eingabeger\u00e4te und zur GUI-Ablaufsteuerung.<\/p>\n<p><a name=\"systick\"><\/a><\/p>\n<h4>SysTick Timer 100Hz-Task<\/h4>\n<table style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"background-color: white; width: 468px; vertical-align: top;\"><a href=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_systick_detail.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_systick_detail.png\" alt=\"arc1_firmware_systick_detail\" width=\"703\" height=\"1035\" \/><\/a><\/td>\n<td style=\"background-color: white; vertical-align: top;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Mit 100Hz (also im Abstand von 10ms) werden durch den statischen Scheduler des Hauptprogrammes alle Eingabeger\u00e4te (Touchscreen, Buttons, Fahrtregler) erfasst und enstsprechende Events f\u00fcr die aktuelle GUI-Ansicht in einem dynamischen Event-Buffer angelegt. Die Verwendung des Event-Buffers erm\u00f6glicht ARC1, parallele Events zu erfassen und zu verarbeiten (bspw. die gleichzeitige Bedienung von Touch und Fahrtregler, oder die gleichzeitige Bedienung von Fahrtregler und Buttons). Ein Sonderfall ist hier nur der Nothalt-Button, der direkt zu einer Erzeugung der Nothalt-DCC-Nachricht an die Gleise f\u00fchrt. Nach Erfassung der Eingabeger\u00e4te wird der Event-Buffer abgearbeitet und die entsprechenden Event-Callback Funktionen der aktuellen GUI-Ansicht aufgerufen. Dort findet dann die Verarbeitung und das Aktualisieren des Display-Inhaltes statt.<\/p>\n<p><a name=\"dccman\"><\/a><\/p>\n<h4>DCC Managing Timer IRQ<\/h4>\n<table style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"background-color: white; width: 743px; vertical-align: top;\"><a href=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_dccman_detail.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_dccman_detail.png\" alt=\"arc1_firmware_dccman_detail\" width=\"1115\" height=\"2264\" \/><\/a><\/td>\n<td style=\"background-color: white; vertical-align: top;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Der DCC Manager ist f\u00fcr den bandbreitenoptimierten Parallelbetrieb vieler Loks optimiert und verwaltet mit insgesamt 3 priorit\u00e4tsbasierten DCC-Signalbuffern die Erzeugung und Steuerung der DCC-Kommandos. Um die Verwaltung der Buffer und die Echtzeit-Erzeugung der logischen DCC-Signale sauber zu trennen, kommen zwei sogenannte &#8222;Launchpads&#8220; zum Einsatz &#8211; zwei gesch\u00fctzte Speicherbereiche deren Adressen jeweils im Wechsel dem DCC-Signalgenerator \u00fcbergeben werden. Somit kann eine Nachricht bereits aus einem Buffer in das Standy-Launchpad kopiert werden, w\u00e4hrend die aktuelle Nachricht im Active-Launchpad noch vom Signalgenerator abgearbeitet wird.<\/p>\n<p>Zum Einsatz kommen drei FIFO-Ringbuffer. Einen Buffer hoher Priorit\u00e4t, bspw. f\u00fcr Geschwindigkeits-Kommandos, einen Buffer niedriger Priorit\u00e4t, bspw. f\u00fcr Licht \/ Funktionen, sowie einen Wiederholungs-Buffer. Der Wiederholungs-Buffer hat die niedrigste Priorit\u00e4t und dient zum einen dazu, hohe oder niedrigpriore Nachrichten direkt zu Beginn zu wiederholen, zum anderen werden \u00fcber ihn die aktuellen Lok-Zust\u00e4nde (Geschwindigkeit, Licht, Funktionen) aller Loks in regelm\u00e4\u00dfigen Abst\u00e4nden erneut gesendet. Dies ist notwendig, um nach Kontaktverlust einer Lokomotive zum Gleis und daraus resultierendem Neustart des Lok-Dekoders den Fahrbetrieb aufrecht zu erhalten.<\/p>\n<p>Der DCC Manager ist Interrupt-gesteuert und arbeitet mit 1kHz. Zu Beginn werden die drei DCC-Buffer ihrer Priorit\u00e4t nach durchlaufen und nach DCC-Kommandos gesucht, die zum einen noch nicht durch ein jeweils aktuelleres Kommando an die gleiche Lok-Adresse abgel\u00f6st wurden (obsolete) und deren Lok-Adressen nicht der 5ms Adress-Sperre (vgl. NMRA S-9.2, Frequency Of Packet Transmission) unterliegen. Wird ein g\u00fcltiges Kommando gefunden und ist das Standby-Launchpad noch nicht belegt, wird die Nachricht zum einen dorthin kopiert, zum anderen die Adresse mit der 5ms Adress-Sperre belegt. Wird in allen Buffern keine g\u00fcltige DCC-Nachricht gefunden, wird ein Flag zur Steuerung der Kommando-Wiederholung gesetzt. Nach dem Durchlaufen der Buffer werden alle gespeicherten Lokomotiven auf \u00c4nderungen in ihrem Zustand gepr\u00fcft und entsprechende DCC-Kommandos generiert und den Buffern hinzugef\u00fcgt. Sind keine \u00c4nderungen vorhanden und ist das Flag zur Kommando-Wiederholung gesetzt (waren also auch vorher schon alle Buffer leer) werden die Lokomotiv-Zust\u00e4nde aller Loks der Reihe nach zur Wiederholung freigegeben. Sind keine Lokomotiven auf ARC1 gespeichert, versendet der DCC Manager Idle Messages, um den Wechsel von auf dem Gleis vorhandenen Loks in den Analog-Modus zu vermeiden.<\/p>\n<p><a name=\"dccgen\"><\/a><\/p>\n<h4>DCC Signal Generation<\/h4>\n<table style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"background-color: white; width: 656px; vertical-align: top;\"><a href=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_dccgen_detail.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_dccgen_detail.png\" alt=\"arc1_firmware_dccgen_detail\" width=\"985\" height=\"1520\" \/><\/a><\/td>\n<td style=\"background-color: white; vertical-align: top;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Der DCC Signalgenerator basiert auf einem PWM-Timer-Interrupt, dessen Frequenz durch das DCC Signal selbst gesteuert wird und der die h\u00f6chste Interrupt-Priorit\u00e4t besitzt. Gem\u00e4\u00df NMRA DCC-Spezifikation S-9.1 wird eine logische 1 \u00fcber eine nominelle Pegelbreite von 58us und eine logische 0 \u00fcber eine nominelle Pegelbreite von 100us definiert. Bei 50% Duty-Cycle des PWM-Signals zum Erzeugen des Flankenwechsels zwischen positivem und negativem Pegel, f\u00fchrt das zu Timer Frequenzen von 8,62kHz f\u00fcr eine logische 1 und 5,00kHz f\u00fcr eine logische 0 (f=1\/(0.000058s*2) bzw. f=1\/(0.0001s*2)).<\/p>\n<p>Tritt der Interrupt ein, wurde also 1 Bit der DCC-Nachricht als Pegel ausgegeben, werden zun\u00e4chst alle weiteren Interrupts gesperrt. Mit Hilfe einer State-Machine wird die DCC-Nachricht sektions-, byte- und bitweise durchlaufen und abh\u00e4ngig vom zu verarbeitenden Bit-Zustand das Auto-Reload-Register des PWM-Timers neu gesetzt. Wurde eine Nachricht komplett bearbeitet, werden die Adressreferenzen von Standby- und Active-Launchpad getauscht, um nahtlos und ohne Zeitverzug die Folgenachricht auf das Gleis abzusetzen.<\/p>\n<h4>Buffer<\/h4>\n<table style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"background-color: white; width: 468px; vertical-align: top;\"><a href=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_addbuffer.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"http:\/\/plauffs.de\/arc\/wp-content\/uploads\/arc1_firmware_addbuffer.png\" alt=\"arc1_firmware_addbuffer\" width=\"703\" height=\"800\" \/><\/a><\/td>\n<td style=\"background-color: white; vertical-align: top;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Die Funktion zum Anh\u00e4ngen einer neuen DCC-Nachricht an einen der drei Ringbuffer wird sowohl innerhalb des DCC Managers als auch beim Anlegen einer Nothalt-Nachricht direkt aus dem SysTick 100Hz-Task heraus aufgerufen. Zun\u00e4chst wird gepr\u00fcft, ob sich ein gleiches DCC-Kommando mit derselben Zieladresse bereits im angegebenen Buffer befindet. Ist dies der Fall, wird die alte Nachricht als obsolet markiert. Handelt es sich bei dem Bestimmungsbuffer der Nachricht entweder um den Low- oder High-Priority Buffer, wird die Nachricht zun\u00e4chst dort angeh\u00e4ngt, bevor sie zus\u00e4tzlich 3x in den Wiederholungs-Buffer geladen wird, um die Kommando\u00fcbermittlung auch bei schlechtem Gleiskontakt zu sichern. Handelt es sich bei dem Bestimmungsbuffer gleich um den Wiederholungs-Buffer (etwa wenn Lok-Kommandos zyklisch wiederholt werden), wird die Nachricht ausschlie\u00dflich dem Wiederholungs-Buffer angeh\u00e4ngt.<\/p>","protected":false},"excerpt":{"rendered":"<p>Im Folgenden sollen der grundlegende Aufbau und insbesondere die DCC-Signalerzeugung der ARC1 Firmware betrachtet werden. Die dargestellten Flussdiagramme sollen dabei zum leichteren Verst\u00e4ndnis der Abl\u00e4ufe dienen. Momentan sind die Flussdiagramme ausschlie\u00dflich auf Englisch verf\u00fcgbar, da auch die Code-Dokumentation rein Englisch<span class=\"ellipsis\">&hellip;<\/span><\/p>\n<div class=\"read-more\"><a href=\"https:\/\/plauffs.de\/arc\/de\/arc1\/firmware\/\">Weiterlesen <span class=\"screen-reader-text\">Firmware<\/span><span class=\"meta-nav\"> &#8250;<\/span><\/a><\/div>\n<p><!-- end of .read-more --><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":8,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"tags":[],"_links":{"self":[{"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/pages\/9"}],"collection":[{"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/comments?post=9"}],"version-history":[{"count":4,"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/pages\/9\/revisions"}],"predecessor-version":[{"id":576,"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/pages\/9\/revisions\/576"}],"up":[{"embeddable":true,"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/pages\/8"}],"wp:attachment":[{"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/media?parent=9"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/plauffs.de\/arc\/de\/wp-json\/wp\/v2\/tags?post=9"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}