Entwurf und Implementierung einer Multitasking ?· Entwurf und Implementierung einer Multitasking-Umgebung…

Download Entwurf und Implementierung einer Multitasking ?· Entwurf und Implementierung einer Multitasking-Umgebung…

Post on 14-Jul-2018

212 views

Category:

Documents

0 download

TRANSCRIPT

  • Entwurf und Implementierung einerMultitasking-Umgebung fr den Arduino

    Due

    Bachelorarbeit

    InfB-BA/Inf Abschlussmodul B.Sc. Informatik

    Autor: Enno Kster 5953573Erstgutachter: Norman HendrichZweitgutachter: Kai JanderZeitraum:Beginn: 16.12.2015, Abgabe: 3.6.2015Universitt Hamburg

    Fakultt fr Mathematik, Informatik und NaturwissenschaftenFachbereich InformatikBachelor of Science Informatik

    Juni 2015

  • Inhaltsverzeichnis1 Einleitung 1

    2 Grundlagen 22.1 Begriffsdefinitionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.2 Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

    2.2.1 Zeitpunkt eines Kontextwechsels . . . . . . . . . . . . . . . . . . . 42.2.2 Reihenfolge der Ausfhrung . . . . . . . . . . . . . . . . . . . . . 5

    2.3 Notwendigkeiten beim Einsatz mehrerer Tasks . . . . . . . . . . . . . . . 62.3.1 Interprozess-Kommunikation . . . . . . . . . . . . . . . . . . . . . 62.3.2 Threadsicherheit . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

    3 bersicht bestehender Projekte 83.1 Timing Bibliotheken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.2 Vollstndige Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

    3.2.1 bersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.2.2 Einzelbetrachtungen . . . . . . . . . . . . . . . . . . . . . . . . . 113.2.3 Auswahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

    4 Integration mit der Arduino-Bibliothek 144.1 Probleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144.2 Lsungsmglichkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

    4.2.1 Arduino-Bibliothek erweitern . . . . . . . . . . . . . . . . . . . . 154.2.2 Arduino-Funktionen ersetzen . . . . . . . . . . . . . . . . . . . . . 154.2.3 Nutzer verantwortlich machen . . . . . . . . . . . . . . . . . . . . 17

    4.3 Einzelbetrachtungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.3.1 malloc()-Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.3.2 delay()- und yield()-Funktionen . . . . . . . . . . . . . . . . . . . 214.3.3 Serial-Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

    5 Fazit 25

    6 Anhang 26

    i

  • 1 EinleitungDer Name Arduino steht fr die einfache, gnstige, plattformbergreifende Entwicklungvon eingebetteten Systemen auf Basis von offener Hardware und Software.Bei Systemen mit geringer Leistung und sehr beschrnkten Ressourcen wie den AVR-

    Prozessor basierten alten Arduinos werden meist nur wenige oder eine einzige Aufgabebearbeitet. Wie in allen anderen Bereichen wird auch die Leistung eingebetteter Systemestetig grer. Der Arduino Due erhht im Vergleich zu seinen Vorgngermodellen dieTaktrate des Prozessors um das sechfache und die Gre des Arbeitsspeichers um das48-fache. Durch diese Leistungssteigerung ist der Gedanke naheliegend ein System freine Vielzahl von Aufgaben zu nutzen.Mehrere Aufgaben ganz einfach in einem Kontrollfluss (Task) zu erledigen macht den

    Quelltext recht schnell unbersichtlich, insbesondere wenn hufig zwischen den Aufga-ben gewechselt werden muss. Die Entwicklung wird fehleranfllig und kompliziert. Demkann man entgegenwirken, indem man logisch trennbare Teile in verschiedene Tasksaufteilt. Die einzelnen Tasks mssen sich den Prozessor teilen. Damit sie ihre Funktionerfllen knnen, mssen sie abwechselnd auf dem Prozessor ausgefhrt werden. Um dieszu gewhrleisten, muss es ein System, genannt Scheduler, geben, dass die Verteilung derRechenzeit kontrolliert.Diese Arbeit zielt auf ein mglichst einfach zu nutzendes System im Geiste der Ardui-

    nophilosophie ab. Es soll mit wenigen Befehlen die Implementation mehrerer nebenein-ander ausgefhrter Funktionen ermglichen, sodass auch Einsteiger schnell und ohne vielVorwissen anfangen knnen das System zu nutzen. Die Hauptzielplattform ist der Ar-duino Due. Die Untersttzung lterer Arduino Systeme besitzt allerdings ebenfalls einenhohen Stellenwert, weil sie die Lsung einer greren Zahl von Entwicklern zugnglichmacht.Mit der Ausfhrung mehrerer Funktionen nebeneinander ist es allerdings nicht ge-

    tan. Durch den Einsatz mehrerer Tasks ergeben sich zustzliche Anforderungen an dieArduino-Bibliothek, welche Anpassungen notwendig machen. Die Funktionalitten derBibliothek und des Multitaskingsystems berschneiden sich. Es soll anhand einiger Bei-spiele aufgezeigt werden, wie diese Konflikte gelst werden knnen.Auch auf den Nutzer des Multitaskingsystems kommen zustzliche Anforderungen

    zu. Zum Beispiel knnen Abhngigkeiten zwischen den verschiedenen Teilen seines Pro-gramms bestehen, die eine Kommunikation und/oder Synchronisation erfordern. DieseProbleme muss der Nutzer selbst lsen. Das Multitaskingsystem kann ihm dabei al-lerdings mit einigen zustzlichen Funktionalitten unter die Arme greifen. Neben derHauptaufgabe des Schedulings soll das System nach Mglichkeit auch fr die Kommu-nikation und Synchronisation Funktionen bereithalten.

    1

  • 2 Grundlagen

    2.1 BegriffsdefinitionenIn der Literatur sind viele der in dieser Arbeit genutzten Grundbegriffe verschiedendefiniert oder aber gleiche Begriffe meinen unterschiedliche Dinge. Dieses kurze Kapitelsoll Missverstndnissen vorbeugen, indem die wichtigsten Ausdrcke festgelegt werden.Ihre Definitionen basieren auf denen aus Moderne Betriebssysteme[Tan09] von AndrewS. Tanenbaum.

    Prozesse, Threads und Tasks

    Ein Prozess ist die Instanz eines Programms in Ausfhrung, inklusive des aktuellenWertes des Befehlszhlers, der Registerinhalte und der Belegungen der Variablen. Kon-zeptionell besitzt jeder Prozess seine eigene virtuelle CPU. Jeder Prozess hat seineneigenen Speicherbereich, der vor Zugriffen durch andere Prozesse geschtzt ist. Er kanndrei Zustnde haben, rechnend(die Befehle werden in diesem Moment auf der CPU aus-gefhrt), rechenbereit(kurzzeitig gestoppt, um einen anderen Prozess rechnen zu lassen)und blockiert(nicht lauffhig bis ein bestimmtes externes Ereignis eintritt). [Tan09]In traditionellen Betriebssystemen hat jeder Prozess einen eigenen Adressraum und

    einen einzigen Ausfhrungsfaden(thread of control). [Tan09] Threads sind also einemProzess untergeordnet. Sie besitzen einen eigenen Befehlszhler und Registerinhalte. Siehaben Zugriff auf auf den kompletten Speicherbereich des Prozesses. Die Belegungenvon Variablen sind abhngig von der Art ihrer Allokation zwischen den Threads geteiltoder unabhngig voneinander. Mehr dazu unter Stack und Heap.

    Exkurs Arduino: Die Prozessoren lterer Arduino-Boards besitzen keine hardware-seitige Untersttzung fr Speicherschutz, um die Trennung der Speicherbereiche verschie-dener Prozesse zu erzwingen. Erst der Arduino Due hat eine Memory-Protection-Unit.Entsprechend ist die softwareseitige Untersttzung des Prozesskonzepts ebenfalls in denmeisten Systemen non-existent, in Zukunft aber vielleicht realisierbar. Im folgenden solldeswegen nur noch die Rede von Tasks sein, wenn Aussagen sowohl auf Prozesse alsauch auf Threads zutreffen, und angenommen werden, dass damit immer Threads mitgeteiltem Speicher gemeint sind. Falls fr das Thema wichtige Unterschiede bestehen,werden diese erwhnt.

    3

  • Stack und Heap

    Der Speicher wird blicherweise in drei Teile aufgeteilt, den Stack, den Heap und einenBereich fr globale Variablen. Wenn der Arduino regulr mit einem einzelnen Task pro-grammiert wird, ist die Unterscheidung der Abschnitte grtenteils unerheblich, da derOrt und die Gre des Stacks und des globalen Bereichs vorher bekannt sind. Sobaldallerdings mehrere Tasks laufen sollen, muss die Speicherverwaltung sich auch um diedynamisch erzeugten Stacks kmmern.Fr jeden Task wird bei seinem Start eine gewisse feste Menge Speicher fr seinen

    Stack voralloziert. Der Stack enthlt Rcksprungadressen fr Funktionen und alle lokalenVariablen in Funktionen, die normal (z.B. int a=0;) deklariert werden. Zustzlich kannein Task z.b. ber die Funktion malloc() in C oder den operator new in C++ dynamischzustzlichen Speicher allozieren. In den globalen Bereich fallen zum einen Variablen,die auerhalb aller Funktionen deklariert sind, und zum anderen als static deklarierteVariablen, die zwar innerhalb einer Funktion deklariert werden, aber trotzdem globalsind.

    Multitasking

    Multitasking bedeutet die Ausfhrung mehrerer Tasks auf einem Prozessor. Fr einefehlerfreie Funktion muss klar definiert sein, wie ein laufender Task die Kontrolle abgibt,wie ein anderer sie wieder aufnimmt und welcher der gestarteten Tasks als nchstes ander Reihe ist. Die Bestimmung der Reihenfolge ist Aufgabe des Schedulers, der weiterunten beschrieben wird.Ein Wechsel der Kontrolle von einem Task zum anderen wird Kontextwechsel genannt.

    Als Kontext wird hier der Inhalt der Register betrachtet. Es wird zunchst der Kontextdes abgebenden Tasks im Speicher gesichert. Dann bestimmt der Scheduler, welcher Taskals nchstes ausgefhrt werden soll. Danach werden die zu einem frheren Zeitpunktgesicherten Kontextinformationen des folgenden Tasks wiederhergestellt.

    Interrupts

    Interrupts sind, wie der Name schon suggeriert, Unterbrechungen des normalen Kon-trollflusses. Diese knnen von verschiedenen Ereignissen ausgelst werden.Das wichtigste fr diese Arbeit ist der Ablauf eines Timers, denn darauf basieren die

    spter beschriebenen preemptiven Scheduler. Fehler im derzeit ausgefhrten Programmwie zum Beispiel unzulssige Speicherzugriffe oder Berechnungsfehler knnen ebenfallsInterrupts auslsen. Auerdem knnen im Bereich der eingebetten Systeme besonderswichtige uere Ereignisse, wie Flankenwechsel an digitalen Pins des Prozessors, dennormalen Ablauf unterbrechen.Wenn ein Interrupt ausgelst wird, arbeitet der Prozessor eine vorher fr dieses Er-

    eignis festgelegte Prozedur ab. Die Adresse dieser Prozedur ist in einer Tabelle abgelegt,die Interrupt Vector genannt wird.

    4

  • 2.2 Scheduler

    Der Scheduler ist das zentrale Element des Systems. Er bestimmt, welcher Task alsnchstes ausgefhrt wird.Scheduler lassen sich anhand zwei verschiedener Merkmale voneinander unterscheiden

    und in Kategorien einordnen. Das erste ist der Zeitpunkt eines Kontextwechsels, welcherentweder vom gerade ausgefhrten Task selbst gewhlt oder vom System vorgegebenwerden kann. Das zweite Merkmal ist die Reihenfolge und Hufigkeit, in der die Tasksausgefhrt werden.

    2.2.1 Zeitpunkt eines Kontextwechsels

    Kooperative Scheduler

    Dieser Schedulertyp zeichnet sich dadurch aus, dass die Kontrolle vom aktuell laufendenTask selbststndig an den Scheduler zurckgegeben wird. Ein Kontextwechsel passiertnur, wenn der Task eine in den meisten Systemen yield()(englisch: hergeben) genannteFunktion aufruft, welche den Task unterbricht und den Scheduler aufruft.Kooperative haben gegenber preemptiven Schedulern einige kleine Vorteile. Diese

    werden jedoch durch einen signifikanten Nachteil erkauft.Ein Vorteil dieses Ansatzes ist, dass im Gegensatz zu dem spter erklrten preemptiven

    Ansatz keine hardwareseitige Untersttzung fr Timer-Interrupts bentigt wird. AlleArduino Systeme haben diese Untersttzung. Daher ist dieser Punkt hchstens in demFall von Interesse, dass man eine Portierung des Systems auf andere Prozessoren plant,welche keine Timer-Hardware besitzen.Auerdem spricht im Falle von sehr wenigen Kontextwechseln der geringe Verlust an

    Rechenzeit fr das Scheduling fr kooperative Scheduler. Dies fllt allerdings nur beisehr niedrig getakteten Prozessoren ins Gewicht.Ein weiterer Pluspunkt ist, dass der Programmierer selbst bestimmt, wann ein Task

    unterbrochen wird. Wenn der Zeitpunkt bestimmter Vorgnge innerhalb einer Sequenzbesonders wichtig ist, um zum Beispiel die Spezifikationen eines Protokolls exakt ein-halten zu knnen, dann ist dies ganz einfach dadaurch zu gewhrleisten, dass man imbetreffenden Task die Kontrolle nicht abgibt bevor die komplette Sequenz durchlaufenist. Beim preemptiven Ansatz muss man zustzliche Manahmen ergreifen, um dies zugewhrleisten.Der groe Nachteil des kooperativen Ansatzes ist allerdings genau dieses mgliche

    Verhalten eines Tasks, den Prozessor fr lngere Zeit belegen zu knnen. Dies kann durcheinen Programmierfehler auch unabsichtlich zu beliebig langen Wartezeiten fhren. EinFehler in einem Task kann das ganze System gefhrden. Der Programmierer muss selbstdafr Sorge tragen, dass keiner seiner Tasks den Prozessor zu lange belegt und damiteventuell andere Tasks in ihrer Funktion behindert.

    5

  • Preemptive Scheduler

    Dieser Schedulertyp wartet nicht wie kooperative Scheduler darauf, dass ein Task frei-willig den Prozessor freigibt. Dies ist zwar generell mglich, aber nicht notwendig. Einpreemptiver Scheduler erzwingt die Unterbrechung der Ausfhrung eines Tasks nacheinem festen Intervall. Ein Timer lst periodisch einen Interrupt aus, woraufhin derScheduler seine Arbeit aufnimmt.Der groe Vorteil preemptiver Scheduler im Vergleich zu ihren kooperativen Pendants

    ist, dass sie ihren groen Nachteil korrigieren. Ein Task kann nicht alle anderen blockie-ren, weil ihm nach Ablauf seines Intervalls garantiert die Kontrolle ber den Prozessorentzogen wird.Erkauft wird das durch die entsprechenden kleinen Nachteile.Wenn der Scheduler zum Beispiel auf ein Intervall von einer Millisekunde eingestellt

    ist, dann wird 1000 mal pro Sekunde ein Kontextwechsel vorgenommen, ganz egal, obdas aus Sicht der beteiligten Tasks notwendig ist oder nicht.Wenn man einen Ablauf im Programm hat, dessen Elemente zwingend zueinander

    zeitnah abgearbeitet werden mssen, dann muss dieser Teil als sogenannter kritischerBereich markiert werden, um eine Unterbrechung durch den Scheduler zu unterbinden.

    2.2.2 Reihenfolge der AusfhrungRound Robin

    Die Grundidee dieser Variante ist sehr einfach. Der Prozessor, soll den Tasks zu gleichenTeilen zur Verfgung gestellt werden. In der Frage , wie gleich definiert sein soll,unterscheiden sich die Implementationen.Eine Mglichkeit ist, dass man einfach die Tasks der Reihe nach einmal ausfhren

    lsst. Beim kooperativen Ansatz, wrde das bedeuten, dass Tasks, die erst nach lngererZeit die Kontrolle zurckgeben, gleich oft laufen aber mehr Zeit bekommen wrden.Beim preemptiven Ansatz tritt dieses Problem nicht auf, da jeder Task sptestens nachAblauf des vom Scheduler festgelegten Intervalls unterbrochen wird.Der Ansatz, das Ausfhrungsrecht reihum zu verteilen, kann noch etwas verfeinert

    werden, indem man es ermglicht den Tasks eine Prioritt zuzuordnen. Je nach Systemknnen diese verschieden genutzt werden. In Desktop-Systemen werden hher priorisierteTasks einfach hufiger ausgefhrt. In Echtzeitbetriebssystemen hat die hhere Priorittblicherweise immer Vorrang. Mehrere niedrig priorisierte Tasks wechseln sich nur so-lange untereinander ab, bis ein Task hherer Prioritt lauffhig wird. Dieser belegt denProzessor dann solange, bis er mit seiner Arbeit fertig ist. [Tha12]

    Deadline

    Bei dieser Schedulerart bestimmt die am nchsten liegende Deadline der Tasks, welchervon ihnen als nchstes ausgefhrt werden soll. Die verschiedenen Implementationen un-terscheiden sich darin, wie diese die Deadline bestimmen. blicherweise wird diese beiErstellung des Tasks als Parameter angegeben.

    6

  • 2.3 Notwendigkeiten beim Einsatz mehrerer TasksDurch den Einsatz mehrerer Tasks, ergeben sich je nach ihren Aufgaben verschiede-ne Probleme. Dieser Abschnitt erklrt kurz die gngigen Methoden, mit denen ihnenbegegnet wird.

    2.3.1 Interprozess-Kommunikation

    Wenn mehrere Tasks auf dem selben eingebetteten System ausgefhrt werden, ist dieWahrscheinlichkeit, dass ihre Aufgaben voneinander abhngen recht hoch. Um korrektarbeiten zu knnen, brauchen sie einen Weg um miteinander kommunizieren und sichsynchronisieren zu knnen.Eine Mglichkeit dies zu realisieren ist ber eine Variable, die beschrieben wird bevor

    eine Ressource genutzt wird, sodass andere Tasks anhand ihres Inhalts sehen knnen, obdie Ressource frei ist. Dies setzt voraus, dass die beteiligten Tasks Zugriff darauf haben.Prozesse haben normalerweise komplett getrennte Speicherbereiche. Diese Restriktionkann unter manchen Systemen durch spezielle geteilte Speicherbereiche(Shared Memo-ry) umgangen werden. Im Falle von Threads kann das durch den gemeinsam genutztenHauptspeicher direkt passieren.Die einfachste Umsetzung der Kommunikation ber diesen geteilten Speicher wre wie

    in Listing 2.1 zu verfahren. Einer globalen Variablen belegt wird ein Wert zugewiesen,um den anderen Tasks zu signalisieren, dass man eine Ressource belegt hat.

    Listing 2.1: Einfache Shared Memory Kommunikationi f ( b e l e g t==fa l se ){

    b e l e g t=true ;nutzeRessource ( ) ;

    } else {wait ( ) ;

    }

    Diese klare und einfache Herangehensweise funktioniert leider nicht richtig, wenn einTask direkt nach der berprfung der Bedingung, also vor dem setzen der globalenVariable, unterbrochen wird. In diesem Fall kann ein anderer Task genau das gleichemachen und die Ressource belegen. Wenn dieser wiederum unterbrochen wird bevor erdie Ressource wieder freigegeben hat, dann kann der erste Task, der ja schon berprfthat, ob die Ressource frei ist, anfangen sie zu nutzen, obwohl sie ja nun belegt ist.Dieses Problem kann man dadurch Lsen, dass der entsprechende Task vorher in eine

    sogenannte kritische Region eintritt und sie spter wieder verlsst. Das verhindert dieUnterbrechung durch andere Threads und damit das Fehlverhalten. Eine solche Funk-tion, die von mehreren Threads zur gleichen Zeit aufgerufen werden knnen ohne ihrVerhalten zu ndern, nennt man threadsichere Funktion. Der Vorteil fr den Nutzer ist,dass er bei der Programmierung nicht unterscheiden muss, ob eine Funktion auch vonanderen genutzt wird oder nicht.

    7

  • 2.3.2 ThreadsicherheitEs ist auf verschiedene Arten mglich, die Threadsicherheit zu gewhrleisten. Eine istdas Schreiben von reinen Funktionen wie in Listing 2.2.

    Listing 2.2: Beispiel einer reinen Funktionint add ( int a , int b){

    return a+b ;}

    Fr reine Funktionen muss folgendes gelten: Sie muss fr gleiche Parameter auchimmer das gleiche zurckgeben und sie darf keine Seiteneffekte haben. Das heit, ihrErgebnis darf nicht von externen Informationen abhngen. Darunter knnen zum Bei-spiel globale Variablen, static deklarierte Variablen, oder per Pointer an andere Tasksweitergegebene Variablen fallen.

    Eine andere Art die Threadsicherheit zu gewhrleisten ist, den Teil der Funktion alskritischen Bereich zu markieren, in dem sich nie mehr als ein Task befinden darf. DiesenTeil zu identifizieren ist aber oft eine schwere Aufgabe. Da die Korrektheit wichtiger istals die Geschwindigkeit, ist es ratsam diesen Bereich eher etwas zu gro also zu kleinzu fassen. Dies hat allerdings zur Folge, dass ein Task, der in diesem Bereich ist, alleanderen Tasks blockiert, bis er ihn wieder verlsst. Ob dies ein Problem darstellt, hngtnatrlich von den Aufgaben der anderen Tasks und der Auslastung des Systems ab.Wenn der Task im kritischen Bereich der einzige ist, der eine knappe zeitliche Vorgabeeinzuhalten hat, dann leidet nur die Performance der anderen Tasks darunter. Wennallerdings auch andere Tasks eine Deadline einzuhalten haben, dann kann die Blockadedurch den Task im kritischen Bereich, ihre korrekte Funktion beeintrchtigen.Aufgrund dieser potentiellen Probleme ist sinnvoll den Einsatz von kritischen Berei-

    chen auf ein Minimum zu reduzieren. Einige der spter behandelten Systeme bieteneinfacher zu nutzende Konstrukte als das simple betreten eines kritischen Bereichs, diedem Programmierer helfen, diese Minimierung zu erreichen.

    8

  • 3 bersicht bestehender ProjekteIm Internet sind viele Systeme zu finden, die zum Ziel haben auf schwacher Hardwa-re wie den Arduino Mikrocontrollern mehrere Funktionen nebeneinander auszufhren.Die Implementierungen unterscheiden sich sehr stark in ihrem Funktionsumfang, ihrerAktualitt und Lebensdauer, ihrer Kompatibilitt mit Hardware und Bibliotheken undihrer verfgbaren Dokumentation.Einige Systeme sind lediglich ein bequemes Frontend fr die Timer-Funktionen der

    Arduino-Hardware. Sie Arbeiten intern nicht mit getrennten Tasks. Andere beinhalteneinen vollstndigen Scheduler, in den meisten Fllen mit dem Round Robin Algorithmus,und eine durch den Einsatz mehrerer Tasks notwendige Speicherverwaltung. Ein paarSysteme bringen neben den Grundfunktionen eines Betriebssystems auch noch weitereBibliotheken mit, um zustzliche Funktionen bereitzustellen.Im Punkt Aktualitt und Lebensdauer gibt es ebenfalls groe Unterschiede. Viele

    Projekte sind erst in den letzten drei Jahren entstanden. Die meisten jngeren Projektewaren allerdings auch recht kurzlebig. An der Commit-Historie ihrer Repositorys war zuerkennen, dass an diesen nur fr ein halbes bis ganzes Jahr gearbeitet wurde und danndie Entwicklung zum Stillstand kam. ltere Systemen wie FreeRTOS oder ChibiOShingegen werden nach wie vor aktiv weiterentwickelt.Bei der Kompatibilitt gilt im Allgemeinen, dass alle jungen Projekte nur sehr spezifi-

    sche Hardware untersttzen, wie z.B. nur bestimmte AVR-basierte Arduino-Controller.Diese Einschrnkungen ergeben sich dadurch, dass in einem Projekt ausschlielich frdiese Controller ein Assembler-Makro zur Sicherung der Registerinhalte geschrieben wur-de. Auerdem knnen fest kodierte Vorgaben im Quelltext im Konflikt mit Vorgabeneiner Bibliothek stehen, weil zum Beispiel beide den gleichen Hardware-Timer fr ihreAufgabe nutzen wollen. ltere Systeme bieten oft mehr Funktionen und Konfigurations-mglichkeiten, um Inkompatibilitten entgegenzuwirken.Auch die Dokumentation ist sehr unterschiedlich und reicht von ein paar Kommentar-

    zeilen im Code bis hin zu einer vollstndigen sauberen API-Dokumentation. MancheProjekte ergnzen dies mit Beispielen fr den einfacheren Einstieg. Diese unterscheidensich aber ebenfalls sowohl in Qualitt also auch Quantitt sehr.Im Folgenden soll zunchst kurz auf die einfachen Timing-Bibliotheken und danach

    auf die vollstndigen Scheduler eingegangen werden.

    9

  • 3.1 Timing BibliothekenDie einfacheren Lsungen kann man als Timing-Bibliotheken bezeichen. Sie ermg-lichen nicht das Ausfhren mehrerer nebeneinander laufender Threads sondern rufennur zu bestimmten Zeitpunkten bestimmte Funktionen auf. Ein Nutzungsbeispiel frdiese Bibliotheken ist das Steuern von LEDs. Drei Funktionen werden auf ein Wiederho-lungsintervall von 500ms, 1000ms und 1300ms eingestellt. Die Bibliothek ruft nun dieFunktionen zu den entsprechenden Zeitpunkten auf. Wenn gerade keine der Funktionenauszufhren ist, wartet die Bibliothek.Bis zu diesem Punkt sind die verschiedenen Implementationen gleich. Manche von

    ihnen verfeinern das einfache Grundprinzip etwas, indem sie es ermglichen einen klei-nen zeitlichen Offset oder eine Prioritt fr die Funktionen festzulegen. Dies dient dazuKonflikte, die im oben beschriebenen Beispiel zwangslufig resultieren, auf eine determi-nistische Art zu lsen. Anhand des obigen Beispiels lassen sich die potentiell auftretendenProbleme leicht veranschaulichen:Die erste Funktion mit 500ms Intervall soll nach 1000ms wieder ausgefhrt werden.

    Die zweite Funktion soll ebenfalls nach 1000ms ausgefhrt werden. An diesem Punktentsteht ein Konflikt und es muss entschieden werden, welche der beiden Funktionen alserstes ausgefhrt wird.Zwei einfache Lsungen sind, die Reihenfolge der Ausfhrung von der Reihenfolge der

    Definition der Intervalle abhngig zu machen oder den Nutzer selbst bei der DefinitionPrioritten festlegen zu lassen. Beides wrde allerdings bedeuten, dass der Startzeitpunktfr die zweite Funktion von der Ausfhrungsdauer der ersten abhngig ist. In manchenAnwendungsfllen ist dies vielleicht unerwnscht.Die Dritte Lsung versucht dem Problem der ersten beiden entgegenzuwirken, indem

    jeder Funktion ein Offset hinzugefgt wird. Verschieden festgelegte Offsets sorgen dafr,dass der Konflikt beim Start gar nicht erst entstehen kann. Zu jedem Intervall wirdnoch ein fr jedes Intervall unterschiedlicher zeitlicher Versatz hinzugefgt. Statt denZeitpunkt der Ausfhrung der ersten Funktion als n 500ms zu berechnen wird z.B.n 500ms + 200s berechnet. Auf alle Aufrufe angewendet knnen die Startzeitpunktenicht mehr zusammenfallen. Unter der Voraussetzung, dass die zuerst gestartete Funk-tion bis zum Startzeitpunkt der zweiten ihre Aufgabe erledigt hat, ist mit dem Offsetgewhrleistet, dass die Abstnde zwischen den Ausfhrungen der Funktionen immer ex-akt gleich ist. Wenn jedoch eine Funktion lnger braucht als bis zum Startzeitpunkt dernchsten Funktion, dann wird das System wieder nichtdeterministisch.Als Basis fr komplexere Projekte sind diese Bibliotheken ungeeignet, aber fr einfache

    Programme vielleicht genau das richtige, daher sollen sie an dieser Stelle nicht ganzunerwhnt bleiben. Im Prinzip sind sie eine einfache Form eines Deadline-Schedulersmit zwei Nachteilen. Sie sind nicht in der Lage, die Lcken zwischen den einzelnenaufgerufenen Funktionen mit der Ausfhrung anderer Funktionen zu fllen. Und laufendeFunktionen knnen, z.B. nach einem Interrupt, nicht zu Gunsten anderer Funktionenunterbrochen werden. Wenn dies kein Hindernis darstellt, sind diese Bibliotheken einakzeptabler Ersatz fr einen vollwertigen Deadline-Scheduler. Im Anhang ist eine Listemit Namen und Internet-Adressen zu finden.

    10

  • 3.2 Vollstndige Scheduler3.2.1 bersichtEs gibt eine Vielzahl von verfgbaren Systemen. Sie alle lckenlos zu erfassen ist nurschwer mglich. Hier soll nur eine grobe bersicht der Systeme gegeben werden. Ta-belle 3.1 zeigt die im Internet gefundenen Systeme, die auf kleine eingebettete Systemeausgerichtet sind. Als letzte Aktivitt wurde entweder das letzte Release oder, wennzugnglich, der letzte Commit im Sourcecode-Repository angenommen. Die Lebenszeitist die aufgerundete Differenz zwischen erstem und letztem Release bzw. Commit.

    Name Lizenz Letzte Aktivitt LebenszeitarduOS LGPL 2014-09-26 1avr-os Apache 2013-05-27 1ArDOS LGPL 2013-10-31 1Erika Enterprise GPL1 2015-04-22 7BeRTOS GPL1 2014-11-11 7+2DuinOS GPL 2013-04-03 3Nut/OS BSD kompatible 2015-04-17 12ScmRTOS MIT 2015-04-24 9TinyOS BSD 2015-04-19 9ChibiOS GPL1 2015-04-24 8FreeRTOS GPL1 2015-03-24 12NilRTOS GPL 2014-08-16 1os47 v1.01 MIT 2014-09-05 11 mit Linking-Exception; Kommerzielle Lizenz auch mglich2 genaues Alter mangels Informationen unbekannt

    Tabelle 3.1: Scheduler-bersicht

    Jedes dieser Systeme kme prinzipiell in Frage als Basis fr ein Multitaskingsystem,dass mit der Arduino-Bibliothek zusammen funktioniert. Allerdings haben einige vonihnen, wie am Anfang des Kapitels schon erwhnt, grere Vor- oder Nachteile.Die erste Gruppe hat den Nachteil, dass an ihnen scheinbar nicht mehr aktiv wei-

    terentwickelt wird. Dadurch ist es notwendig alle zuknftigen Anforderungen selbst zuerfllen und Fehlerkorrekturen selbst vorzunehmen. Da es andere Systeme mit mehrAktivitt gibt, muss man sich diese zustzliche Last nicht auferlegen.Die zweite Gruppe bilden die Projekte die zwar noch aktiv sind, aber aus anderen

    Grnden weniger attraktiv sind als die darauf folgenden der dritten Gruppe. Einige vonihnen haben sehr spezifische Zielsetzungen, die mit der eher allgemeinen Ausrichtungder Arduino-Plattform in Konflikt stehen knnten. Andere haben eine weniger guteHardwareuntersttzung und/oder Dokumentation.Die Systeme der dritten Gruppe haben den zustzlichen Vorteil schon fertig als in der

    Arduino-IDE verwendbare Bibliothek verpackt worden zu sein. Dadurch sind sie sofortohne zustzlichen Portierungsaufwand Einsatzbereit.

    11

  • 3.2.2 EinzelbetrachtungenErika Enterprise

    Erika Enterprise ist ein System aus dem Automotive-Bereich. Es ist das nach eigenerAussage erste kostenlose offene Echtzeitbetriebssystem mit einer OSEK/VDX-Zertifizierung.[Srl14b] Es liefert nicht nur eine eigene Bibliothek sondern verpackt diese gleich in einekomplette Eclipse-IDE mit diversen zustzlichen Features. Die Dokumentation ist onlineals PDF verfgbar. Offiziell untersttzt dieses System nur den Arduino Uno. [Srl14a]Fr das Ziel dieser Arbeit ist das System ungeeignet, weil das System als Bibliothek

    fr die Arduino-IDE verpackt werden soll und den Arduino Due untersttzen soll. ImFall von Erika Enterprise wre dies mit sehr hohem Aufwand verbunden.

    BeRTOS

    BeRTOS bringt wie Erika Enterprise eine eigene IDE mit. Allerdings sind hier die IDEund das System in der Ordnerstruktur einfacher voneinander zu trennen, da das Projekteine relativ gute Dokumentation hat. Auerdem sind einige zustzliche Bibliotheken frexterne Hardware und grafische Oberflchen im Paket enthalten. Diese enthlt ebenfallseine Anleitung zur Portierung des Systems auf andere Mirkrocontroller, sodass das Feh-len einer Untersttzung fr die meisten Arduino-Boards ausgebessert werden knnte.[Srl11]

    DuinOS

    DuinOS ist die Kombination der Arduino-Bibliothek mit FreeRTOS. Es erfllt also imPrinzip die Anforderungen dieser Arbeit. Allerdings wurde FreeRTOS nicht als Biblio-thek fr die Arduino-IDE verpackt, sodass man es mit einer include-Direktive einbindenkann, sondern direkt mit der Arduino-Bibliothek verwoben. Wenn Wert auf aktuelleVersionen gelegt wird, muss jedes Update der IDE oder des Betriebssystems direkt vonden Entwicklern in DuinOS integriert werden. Tun sie dies nicht, hat man den Nachteileiner veralteten Komponente. Auerdem wurde FreeRTOS so eingebunden, dass in derIDE jedes Board doppelt auftaucht, einmal mit und einmal ohne DuinOS. All dies machtden Einsatz des Systems mhsamer und komplizierter als es sein muss. Darber hinauswird DuinOS nur noch inklusive der angepassten IDE verteilt.

    Nut/OS

    Nut/OS legt besonderen Wert auf die Kommunikation ber TCP/IP und untersttztDHCP, DNS und HTTP. Es hat nur einen kooperativen Scheduler. Eine offizielle Un-tersttzung fr Arduino-Boards gibt es nicht, wre allerdings durch eine Anleitung zumPortieren des Systems auf andere Controller machbar. Das Projekt hat ein Wiki, dass inenglischer Sprache recht umfangreich ist. Es hat auch einen deutschen Teil, welcher sehrviel kleiner ausfllt und viele Punkte unbeantwortet lsst. Allerdings ist es das einzigeder hier gelisteten Projekte, dass berhaupt eine deutsche Dokumentation hat. [eG10]

    12

  • ScmRTOS

    ScmRTOS ist eines der wenigen Systeme, die in C++ geschrieben sind. ber die Ziel-setzung des Projekts sagt die Webseite des Projekts leider nichts aus. Eine offizielle Un-tersttzung der Arduino-Boards gibt es nicht, hnliche Boards werden aber untersttzt.Statt einer detaillierten Portierungsanleitung wie bei vielen anderen Projekten gibt eshier nur eine Auflistung der einzelnen Bestandteile eines Ports. Die Portierung diesesSystems wre wahrscheinlich etwas aufwendiger im Vergleich zu den anderen Systemen.Die Dokumentation ist in Form eines PDFs vorhanden, welches alle Themen abdeckt.[sT12]

    ChibiOS

    ChibiOS hat einen besonderen Fokus auf Effizienz. Nach eigenen Angaben hat es die bes-ten Kontextwechselzeiten in seiner Klasse. [Sir15] Das System hat neben den Grundfunk-tionen eines Echtzeitbetriebssystems auch einen Hardware Abstraction Layer, der Unter-sttzung fr verschiedene externe Hardware bereitstellt. Es hat eine Online-Dokumentation,die smtliche Komponenten des Systems detailliert erklrt. Das projekteigene Wiki ent-hlt Artikel zu vielen Themen rund um die Benutzung des Systems und auch ber allge-meines wie die Grundkonzepte von Echtzeitbetriebssystemen oder das Optimieren vonProgrammen fr eingebettete Systeme. Eine offizielle Untersttzung fr die Arduino-Boards gibt es nicht, aber es existiert eine Portierungsanleitung und hnliche Boardswerden untersttzt. Allerdings ist die Portierung gar nicht notwendig.Dieses System ist schon fertig als Bibliothek fr die Arduino-IDE von Bill Greiman

    verpackt worden und steht zum Download bereit. Die enthaltene Version 2.6.5 ist zwarnicht mehr ganz aktuell, sollte aber bei Bedarf unkompliziert durch die derzeit aktuelleVersion zu ersetzen sein. Laut der Github-Seite ist es sowohl zu den alten Arduino-Boardsals auch zum Due kompatibel. [Gre14a]

    FreeRTOS

    FreeRTOS zeichnet sich durch eine extrem breite Hardwareuntersttzung und eine Viel-zahl von Beispiel-Applikationen aus. Die Dokumentation ist sehr reichhaltig und detail-liert. Im Vergleich mit den anderen Projekten hat FreeRTOS genausten und umfang-reichsten Anleitungen fr Einsteiger. Auerdem spricht die sehr weite Verbreitung desSystems fr dessen Einsatz. Nach einer Umfrage von EE Times hat FreeRTOS einenMarktanteil von 12%. [PC13] Durch diese weite Verbreitung ist auch das Angebot anMaterial zum Thema FreeRTOS im Internet sehr viel hher als bei den anderen hiergelisteten Systemen.Wie ChibiOS steht dieses System schon als Bibliothek fr die Arduino-IDE verpackt

    zur Verfgung und ist sowohl mit alten Boards als auch mit dem Due kompatibel. Dieverpackte Version 8.0.1 schon ein Jahr alt, aber ein Upgrade sollte auch hier nicht schwersein. [Gre15]

    13

  • NilRTOS

    NilRTOS ist ein Experiment des Entwicklers von ChibiOS, Giovanni Di Sirio, mit demZiel herauszufinden wie klein man ein Echtzeitbetriebssystem machen kann ohne es-senzielle Funktionalitt aufzugeben. Es ist eine Untermenge von ChibiOS und API-kompatibel zu ihm. Der Speicherbedarf im ROM ist mit rund 700 Bytes in etwa einZehntel dessen, was ChibiOS fr sich beansprucht. Die Dokumentation fllt im Gegen-satz zu der von ChibiOS sehr kurz aus. [Sir]Auch dieses System steht schon fertig als Bibliothek fr die Arduino-IDE zur Verf-

    gung. Im Bezug auf die Hardwareuntersttzung werden nur die alten AVR-Controllerbasierten Arduino-Boards erwhnt. Aufgrund der experimentellen Natur des Projektsund der geringen Aktivitt ist unklar, ob dieses System in Zukunft weiter gepflegt wird.[Gre14b]

    os47

    os47 ist ein in C++ fr den Arduino Uno geschriebenes System, dass auch auf anderenAVR-Prozessor basierten Problemlos laufen sollte. Fr einen Betrieb auf dem ArduinoDue msste man es auf dessen ARM-Architektur portieren. Das Projekt hat zwar keineAnleitung dafr, ist aber extrem gut kommentiert, sodass der Aufwand dafr sich trotzallem in Grenzen hlt. Der Funktionsumfang des Systems ist aufgrund des jungen Altersnicht so gro wie bei den anderen Systemen. [Dem14]Leider ist seit der letzten Aktivitt schon fast ein Jahr vergangen, sodass eine Wei-

    terentwicklung durch den ursprnglichen Autor unwahrscheinlich ist. Fr einen kleinenEinblick in den Aufbau eines minimalen Echtzeitbetriebssystems ist dieses Projekt aberdennoch gut geeignet.

    3.2.3 AuswahlDas in dieser Arbeit geplante System soll besonders fr Einsteiger gut geeignet sein. Dasheit, dass es wenig Vorkenntnisse erfordern darf, unkompliziert einzusetzen ist und einemglichst gute Dokumentation haben muss. Es soll in der Arduino-IDE verwendbar seinund mglichst keine zustzlichen externen Abhngigkeiten einfhren. Auerdem soll esneben dem Arduino Due mglichst viele andere Arduino-Boards untersttzen.FreeRTOS ist bereits als Arduino-IDE kompatible Bibliothek verpackt erhltlich und

    hat eine breite Hardwareuntersttzung. Die Dokumentation ist vorbildlich und es gibteine Vielzahl von Beispielen, die den Einstieg erleichtern. Auf ChibiOS treffen diesePunkte generell auch zu. Es ist ebenfalls direkt in der Arduino-IDE einsatzbereit undhat eine gute Dokumentation. Aber die mitgelieferten Beispiele sind sehr viel komplexerund damit schwerer zu verstehen als diejenigen, die FreeRTOS beiligen. Auerdem istdas Finden von Informationen im Internet im Zusammenhang mit FreeRTOS einfacher,weil es weiter verbreitet ist.FreeRTOS ist damit am Ende die bessere Wahl fr die Anforderungen.

    14

  • 4 Integration mit derArduino-Bibliothek

    4.1 Probleme

    Dieser Abschnitt geht auf Probleme ein, die bei der Nutzung eines Multitaskingsystemszusammen mit der Arduino-Bibliothek entstehen knnen. Die Funktionen der Arduino-Bibliothek sind nicht auf die gleichzeitige Nutzung durch mehrere Tasks ausgelegt. Inmanchen Fllen kann dies zu Problemen fhren.Wenn Funktionen geteilte Ressourcen nutzen, kann ein gleichzeitiger Aufruf zu fehler-

    haftem Verhalten fhren. Ein Beispiel dafr ist die malloc-Funktion, die der Speicher-allokation dient. Wenn zwei Tasks sie gleichzeitig aufrufen, fhrt dies im schlimmstenFall dazu, dass an beide der gleiche Speicherbereich herausgegeben wird, sodass die bei-den Tasks gegenseitig ihre Daten berschreiben wrden. Ein weiteres Beispiel ist dieFunktion zum Senden ber die serielle Schnittstelle. Wenn zwei Funktionen diese gleich-zeitig nutzen, wrden die Nachrichten der beiden vermischt werden. Mehr dazu in denEinzelbetrachtungen in den Abschnitten 4.3.1 und 4.3.3.Funktionen mit strikten zeitlichen Anforderungen knnen selbst ohne gleichzeitigen

    Aufruf fehlerhaftes Verhalten verursachen, wenn ein anderer Thread ihre Ausfhrungfr eine kurze Zeit unterbricht. Es konnte kein Beispiel fr diese Problematik gefundenwerden. Es wre allerdings denkbar, dass in einer der zahllosen externen Bibliothekenein solcher Fall auftritt, wenn z.B. ein Kommunikationsprotokoll nach einer bestimmtenZeit eine Antwort erwartet.Mehr oder weniger ein Spezialfall der oben beschriebenen Probleme sind Funktiona-

    litten, die sowohl in der Arduino-Bibliothek als auch im Multitaskingsystem enthaltensind. Dabei handelt es sich im Allgemeinen um Funktionen aus zwei Bereichen.Der erste ist die Zeiteinteilung, welche die zentrale Aufgabe des Multitaskingsystems

    ist. Ein Beispiel dafr ist die delay-Funktion, welche spter in Abschnitt 4.3.2 genauerbetrachtet wird. Diese Funktion dient dem Warten um eine bestimmte Zeit. Sie kanneffizienter implementiert werden, indem man die zustzlichen Randbedingungen durchden Einsatz mehrerer Tasks bercksichtigt.Der zweite Bereich ist die Speicherverwaltung, welche das System ebenfalls berneh-

    men muss, weil die mitgelieferten Funktionen des AVR-GCC, den die Arduino-IDE nutzt,nicht fr den gleichzeitigen Aufruf aus mehreren Tasks ausgelegt ist. Ein Beispiel dafrist das weiter oben schon angesprochene malloc.

    15

  • 4.2 Lsungsmglichkeiten

    Man kann den Integrationsproblemen auf mehrere Arten begegnen, welche sich darinunterscheiden, an welcher Stelle man die Probleme angeht und wer fr die Lsung ver-antwortlich ist. Keine der Optionen ist allerdings ein Allheilmittel. Je nach Funktion isteine besser geeignet als die anderen.

    4.2.1 Arduino-Bibliothek erweitern

    Eine Variante ist die Behandlung der besonderen Anforderungen beim Einsatz mehre-rer Threads in der Arduino-Bibliothek. Da die Bibliothek auch weiterhin auf den altenArduinos und ohne Threads sinnvoll Einsetzbar bleiben soll, muss aber darauf geachtetwerden, dass der Ressourcenverbrauch nicht, oder zumindest nur sehr begrenzt, an-wchst. Das gilt fr die bentigten Takte zur Abarbeitung, fr den Arbeitsspeicher undauch fr den persistenten Speicher, in dem das Programm liegt. Eine Mglichkeit dieszu gewhrleisten wre die Bereitstellung von zwei Funktionsvarianten. Wenn ein Multi-taskingsystem genutzt wird, kommt die angepasste threadsichere Variante zum Einsatz,sonst die einfache.Auf lange Sicht ist der Weg die Bibliothek zu erweitern fr viele Funktionen wahr-

    scheinlich die beste Lsung. Ein Fall davon ist die spter in 4.3.3 betrachtete Serial-Klasse. Allerdings ist der Umfang der Arduino-Bibliothek gro genug, dass eine ber-arbeitung der gesamten Bibliothek einen groen Zeitraum in Anspruch nehmen wrde.

    4.2.2 Arduino-Funktionen ersetzen

    Eine weitere Mglichkeit den Problemen zu begegnen ist das berschreiben von Funktio-nen der Arduino-Bibliothek mit angepassten Varianten durch das Multitaskingsystem.Dies kann auf zwei Arten geschehen.

    Multitaskingsystem ersetzt Funktionen

    Um die Ersetzung von Seiten des Multitaskingsystems zu realisieren, muss man in derArduino-Bibliothek alle Funktionen, fr die ein berschreiben ermglicht werden sollen,als schwach deklarieren. Dies teilt dem Compiler mit, dass bei einem Namenskonflikt,also zwei Funktionen mit gleichem Namen, kein Fehler ausgegeben werden soll, sonderndass stattdessen die schwache Funktion ignoriert werden soll.Beim von der Arduino-IDE genutzen AVR-GCC geht dies durch das Hinzufgen

    von __attribute__((weak)) vor dem Funktionsnamen oder nach der Parameterliste derFunktion oder durch das Hinzufgen von #pragma weak in der Zei-le vor der Funktionsdefinition. Ein Beispiel dafr kann man in Listing 4.6 sehen. dieyield-Funktion ist als schwach deklariert.

    16

  • Arduino-Bibliothek ersetzt Funktionen

    Eine Alternative zur Deklarartion von schwachen Funktionen, die auch jetzt schon inmanchen Teilen der Arduino-Bibliothek zu finden ist, ist in Listing 4.1 zu sehen. Inder Bibliothek fr ein WiFi-Shield wird eine Funktion delay_ms definiert, die je nachgenutztem System verschiedene Wartefunktionen aufruft. Wenn FreeRTOS genutzt wird,ruft sie vTaskDelay auf. Diese Funktion teilt gibt die Kontrolle an den Scheduler vonFreeRTOS ab und teilt ihm mit, dass dieser Task die nchsten delay Millisekunden nichtaktiviert werden soll. Fr den Fall, dass NutOS verwendet wird, geschieht in etwa dasgleiche mit er entsprechenden Funktion von NutOS. Wenn keines der beiden Systemeverwendet wird, dann wird stattdessen die Bibliothekseigene cpu_delay_ms-Funktionaufgerufen, die wiederum, hnlich der Wartefunktion aus Listing 4.7 per Busy-Waitingdie gewnschte Zeit verstreichen lsst.

    Listing 4.1: Ausschnitt der delay.c(wifiHD) der Arduino-Bibliothekvoid delay_ms ( unsigned long delay ){#i f ( de f i ned FREERTOS_USED)

    vTaskDelay ( ( portTickType )TASK_DELAY_MS( delay ) ) ;#e l i f ( de f i ned NUTOS_USED)

    NutSleep ( de lay ) ;#else

    cpu_delay_ms ( delay , s_fcpu_hz ) ;#endif

    }

    Diese Herangehensweise hat den Nachteil, dass die entsprechenden Funktionen der ver-schiedenen Multitaskingsysteme alle nach dem oben zu sehenden Muster in der Arduino-Bibliothek eingetragen werden mssen, damit sie verwendet werden knnen. Jedes Sys-tem msste sich fr die Aufnahme in die Liste an die Arduino-Entwickler wenden. DieEntwickler des Multitaskingsystems wren von denen der Arduino-Bibliothek abhngig.Die Liste wrde langsam aber stetig anwachsen.Solche nderungen auf der anderen Seite in allen Multitaskingsystemen vorzunehmen

    erscheint allerdings auch nicht sinnvoll. Dies wrde nur den die Positionen umdrehenund den Entwicklern des Systems auferlegen eine solche Liste zu fhren.Auf beiden Seiten wrde der Code durch solche Anpassungen unbersichtlich wer-

    den und die eigentliche Funktionalitt verbergen. Deswegen sollten die Probleme wennmglich in ein externes Paket ausgelagert werden, damit beide Seiten sich auf ihre Kern-aufgaben konzentrieren knnen.

    17

  • Erstellung einer Zwischenschicht

    Der Mittelweg zwischen der Ersetzung nur auf der einen oder der anderen Seite, und einewahrscheinlich fr alle sauberere Lsung, wre die Erstellung einer Zwischenschicht, wel-che die Brcke zwischen Arduino-Bibliothek und Multitaskingsystem schlgt. So knnteman die Quelltexte der beiden Komponenten weitestgehend unangetastet lassen und dienotwendigen Modifikationen in die Zwischenschicht auslagern. Wie dies aussehen knntezeigt Abschnitt 4.3.1, der sich mit der malloc-Funktion beschftigt.

    4.2.3 Nutzer verantwortlich machenDie dritte Alternative ist das Abschieben der Verantwortung auf den Programmierer,der basierend auf dem System und der Bibliothek versucht ein eigenes Programm zuschreiben. Man knnte in der Dokumentation der Arduino-Bibliothek ganz einfach dengefhrdeten Funktionen einen Hinweis hinzufgen, der den Nutzer darauf aufmerksammacht, dass sie nicht threadsicher ist. Dies erfordert auf Seiten des Programmierers eintiefes Verstndnis aller Ablufe in den Funktionen, um mit dem System und der Biblio-thek zu arbeiten. Er muss die Nebeneffekte in seinem Gesamtsystem abschtzen knnenund anhand dessen entscheiden, ob beziehungsweise welche Manahmen zu ergreifensind.So zu verfahren wrde im krassen Widerspruch zur Arduino-Philosophie der Einfach-

    heit stehen. Im allgemeinen kann diese Lsung deshalb nur eine temporre Hilfsmanah-me sein, um die Zeit zu berbrcken, bis eine saubere Lsung auerhalb des Verantwort-lichkeitsbereichs des Nutzers des Systems gefunden wurde. Dies setzt selbstverstndlichvoraus, dass es eine solche gibt.Es gibt allerdings Flle, in denen es schwer bis gar nicht mglich ist, dem Nutzer

    die Arbeit abzunehmen, weil die auftretenden Probleme nicht unbedingt ein Fehler derFunktion sind. Ein Beispiel dafr ist das Lesen von der seriellen Schnittstelle. Wennzwei Tasks gleichzeitig von ihr lesen, dann bekommen beide nur jeweils einen Teil derankommenden Daten. Auf Hardware- oder Betriebssystemseite ist es aber nicht mglichzu wissen, welche Teile der Daten einem bestimmten Task zugeordnet werden mssen.Der Programmierer muss hier selbst sorge dafr tragen, dass sein System sich korrektverhlt und dass die Eingaben ber die serielle Schnittstelle richtig zugeordnet werden.

    18

  • 4.3 Einzelbetrachtungen4.3.1 malloc()-FunktionDie Arduino-IDE nutzt fr die alten Boards den AVR-GCC und fr den Due einen ange-passten gcc. Beide haben liefern eine libc-Implementation mit, welche auch die Funktionmalloc enthlt. Die malloc-Funktion dient der dynamischen Allokation von Speicher.Eine Freelist genannte Liste enthlt die Startadressen der freien Speicherstellen imArbeitsspeicher. Listing 4.2 zeigt einen Ausschnitt aus der malloc-Funktion der avr-libc.In diesem sieht man den Teil der Funktion, der ber der Liste iteriert, um fr eineSpeicheranforderung eine mglichst geeignete Stelle zu finden.

    Listing 4.2: Ausschnitt aus malloc.c (avr-libc)for ( s = 0 , fp1 = __flp , fp2 = 0 ;fp1 ;fp2 = fp1 , fp1 = fp1>nx ) {

    i f ( fp1>sz < len )continue ;

    > i f ( fp1>sz == len ) {/ Found i t . Disconnect the chunk from the f r e e l i s t , and re turn i t ./i f ( fp2 )fp2>nx = fp1>nx ;else__flp = fp1>nx ;return &(fp1>nx ) ;

    }else {

    i f ( s == 0 | | fp1>sz < s ) {/ t h i s i s the s m a l l e s t chunk found so f a r /s = fp1>sz ;s fp1 = fp1 ;s fp2 = fp2 ;

    }}

    >}

    An diesem Ausschnitt kann man erkennen, dass die Implementation nicht threadsicherist. Es gibt zwei Zeilen, hervorgehoben durch einen Pfeil, an denen die Unterbrechungeines Tasks ein fehlerhaftes Verhalten hervorrufen kann.

    19

  • Der Ablauf des Fehlers ist wie folgt:

    Task 1 ruft malloc auf und findet eine geeignete freie Stelle im Speicher.Task 1 befindet sich in diesem Moment an der ersten oder der zweiten markiertenZeile, je nach dem, ob die Stelle exakt so gro ist wie gefordert oder ob sie grerist und in zwei Teile aufgeteilt werden muss.

    Task 1 wird unterbrochen.

    Task 2 ruft malloc auf und findet die selbe Stelle im Speicher wie Task 1.

    Beide Tasks werden die gefundene Stelle im Folgenden fr sich beanspruchen.

    Bei genauerer Betrachtung des Rests der Funktion knnte man mglicherweise nochmehr Fehlerquellen im Zusammenhang mit gleichzeitigen Aufrufen finden. Dieses Beispielsoll jedoch gengen, um das Problem aufzuzeigen.FreeRTOS stellt fnf Implementationen zur Speicherallokation zur Verfgung, die je-

    weils auf bestimmte Anwendungsflle angepasst sind. Um das System zu betreiben, mussman sich fr eine von ihnen entscheiden, denn FreeRTOS nutzt ausschlielich diese in-terne Funktion zur Verwaltung seines Speichers und setzt voraus, dass sie definiert ist.[Ltdb] Im von Bill Greiman bereitgestellten Paket FreeRTOS-Arduino wird die Varian-te genutzt, die auf eine schon definierte malloc-Funktion zurckgreift, diese aber gegengleichzeitigen Aufruf zu schtzen versucht. Listing 4.3 zeigt die Funktion.

    Listing 4.3: Ausschnitt aus heap_3.c (FreeRTOS)void pvPortMalloc ( s i z e_t xWantedSize ){void pvReturn ;

    vTaskSuspendAll ( ) ;{

    pvReturn = mal loc ( xWantedSize ) ;traceMALLOC( pvReturn , xWantedSize ) ;

    }( void ) xTaskResumeAll ( ) ;

    #i f ( configUSE_MALLOC_FAILED_HOOK == 1 ){

    i f ( pvReturn == NULL ){

    extern void vAppl icat ionMal locFai ledHook ( void ) ;vAppl icat ionMal locFai ledHook ( ) ;

    }}#e n d i f

    return pvReturn ;}

    20

  • Vor dem Aufruf von malloc werden hier alle Tasks pausiert. Nach dem Aufruf wer-den sie wieder freigegeben. Wenn alle Tasks pvPortMalloc nutzen statt direkt mallocaufzurufen, dann ist hiermit das Problem gelst, denn es wird zwischen dem Pausierenund der Freigabe kein anderer Task ausgefhrt. Ein einzelner Task, der den direktenAufruf nutzt, kann diese Lsung allerdings aushebeln. Wenn der Ablauf wie oben beidem einfachen malloc ist und nur Task 2 pvPortMalloc benutzt, dann kann der Konfliktwieder auftreten.Im eigenen Code kann man eventuell noch berschauen, wo Speicher alloziert wird

    und die entsprechenden Aufrufe ersetzen. Problematischer wird es allerdings, wenn einegenutzte Bibliothek Speicher alloziert. Man msste jede genutzte Bibliothek berprfenund gegebenenfalls die malloc-Aufrufe ersetzen. Das htte aber zur Folge, dass die Bi-bliothek nur noch in Kombination mit FreeRTOS nutzbar wre. Wenn man ein einfachesProjekt hat, bei dem der Einsatz eines Betriebssystems nicht gewnscht ist, msste mandie Anpassungen wieder entfernen. Das gleiche Problem entstnde auch, wenn man einProjekt htte, bei dem ein anderes System als FreeRTOS eingesetzt werden soll.Auf lange Sicht kann das manuelle Ersetzen der malloc-Aufrufe also keine Lsung sein.

    Besser wre es, wenn man wie in Kapitel 4.2.2 beschrieben die Funktion als schwach de-klarieren wrde und in einer Zwischenschicht die Zuordnung des malloc-Namens zurFunktion pvPortMalloc. Listing 4.4 zeigt die kleine notwendige nderung, um die Funk-tion schwach zu deklarieren und Listing 4.5 zeigt die Zuordnung der spezialisierten mal-loc-Implementation zum allgemeinen Namen.

    Listing 4.4: malloc-Deklaration in der libcOr ig ina l : void malloc ( s i z e_t l en ) { . . . }

    Neu : void malloc ( s i z e_t l en ) __attribute__ ( ( weak ) ) { . . . }

    Listing 4.5: Zuordnung der alternativen malloc-Implementationvoid malloc ( s i z e_t l en ) __attribute__ ( ( a l i a s ( " pvPortMalloc " ) ) ) ;

    Bei dieser Herangehensweise wre es beliebigen anderen Systemen mglich das gleichezu tun, ohne dass von Seiten der Arduino-Entwickler ein weiteres Eingreifen ntig wre.

    21

  • 4.3.2 delay()- und yield()-FunktionenListing 4.6 zeigt die schwach deklarierte Funktion yield. Diese Funktion dient der Abgabeder Kontrolle eines Threads an einen anderen und ist an dieser Stelle vorerst leer definiert.Ein externer Scheduler kann nun diese leere Funktion durch eine eigene ersetzen.

    Listing 4.6: Ausschnitt aus hooks.c der Arduino-Bibliothek/

    Empty y i e l d ( ) hook . This func t i on i s in tended to be used by l i b r a r y w r i t e r s to b u i l d l i b r a r i e s or s k e t c h e s t h a t suppor t s coope ra t i v e th reads . I t s de f ined as a weak symbol and i t can be r e de f i n ed to implement a r e a l coope ra t i v e s chedu l e r ./

    stat ic void __empty( ) {// Empty

    }void y i e l d ( void ) __attribute__ ( ( weak , a l i a s ( "__empty" ) ) ) ;

    Welchen Zweck die Ersetzung hat, kann man in Listing 4.7 sehen. Die delay-Funktionder Arduino-Bibliothek wartet ms Millisekunden. Mit der leeren yield-Funktion luftdiese Schleife immer wieder in schneller Folge ab bis die entsprechende Zeit abgelaufenist. Dieses Verfahren ist auch als Busy-Waiting bekannt. Mit einer berschriebenenyield-Funktion von einem Scheduler ist es mglich an dieser Stelle anderen Tasks dieKontrolle zu bergeben, whrend der aktuelle Task wartet. Dadurch wird die Zeit stattmit hufigen Abfragen der Bedingungen von while und if mit der Ausfhrung andererTasks, und damit sinnvoller, gefllt.

    Listing 4.7: Ausschnitt aus wiring.c der Arduino-Bibliothekvoid delay ( unsigned long ms){

    uint16_t s t a r t = ( uint16_t ) micros ( ) ;while (ms > 0) {

    y i e l d ( ) ;i f ( ( ( uint16_t ) micros ( ) s t a r t ) >= 1000) {

    ms;s t a r t += 1000 ;

    }}

    }

    Die Grundidee yield in delay zu nutzen ist sehr gut, denn so knnen bestehendeFunktionen mit Wartezeiten mit einem einfachen Scheduler unkompliziert nebeneinan-der ausgefhrt werden. Das MultipleBlink-Tutorial von arduino.cc [ard] ist ein schnesBeispiel, wie dies angewendet werden kann. Die Implementation der delay-Funktion istallerdings schlecht, da sie nur unter bestimmten Bedingungen korrekt funktioniert.In jedem Durchlauf der while-Schleife wird am Anfang die Kontrolle abgegeben. Wenn

    spter die Ausfhrung fortgesetzt wird, wird einmal berprft, ob mehr als 1000svergangen sind. Falls ja, wird der ms-Zhler dekrementiert.

    22

  • Diese Logik setzt voraus, dass bei einem Aufruf mit 100ms die Kontrolle mindestens100 mal innerhalb der zu wartenden Zeit wiedererlangt wird. Wenn dies nicht der Fall ist,dann kann der Zhler noch nicht bei Null angekommen sein. Wenn der Task zum Beispielin der Zeit nur 50 mal ausgefhrt wurde, dann ist der Zhler erst auf 50 reduziert worden.Das hat zur Folge, dass mehr als die angeforderte Zeit gewartet wird. Wie lange diesgenau ist, hngt einzig vom Verhalten der anderen Tasks ab. Dieses Problem entsteht,weil nur berprft wird, ob mehr als 1000s vergangen sind, nicht aber, wieviel mehr.Das Fehlverhalten kann einfach korrigiert werden, indem man das if -Statement durchein while-Statement ersetzt. In dem Fall wrde der Zhler immer so oft dekrementiert,bis die Differenz kleiner als 1000 ist. Danach entsprche der Zhler wieder dem zu diesemZeitpunkt passenden Wert. Erst dann wrde die Kontrolle wieder abgegeben werden.Neben diesem Fehler in der Logik der Funktion ist allerdings auch die Tatsache ein

    Nachteil, dass sie nicht als schwach deklariert ist und damit nicht ersetzt werden kannwie yield. In dieser Form ist fr die berprfung, ob die Zeit abgelaufen ist, sehr viel Auf-wand notwendig. Es muss einen Kontextwechsel in den Task geben, dann die Bedingunggeprft werden und danach wieder aus ihm heraus gewechselt werden. Mit der aktuellenFassung der Funktion muss dies im oben skizzierten Beispiel mindestens 100 mal pas-sieren. Selbst mit der empfohlenen Anpassung knnte dies noch beliebig oft passieren,wenn die anderen Tasks oft die Kontrolle zurckgeben.Deswegen wre es weit aus effizienter die Zeiterfassung in den Scheduler zu verlagern.

    Dieser knnte die gleichen Berechnungen und berprfungen ohne die Kontextwechseldavor und danach anstellen.

    23

  • 4.3.3 Serial-KlasseDas in vielen Beispielen der Arduino-Bibliothek genutzte Serial-Objekt ist vom TypHardwareSerial. Es dient der einfachen Benutzung der seriellen Schnittstelle.Listing 4.8 zeigt die Definition der Klasse in gekrzter Form. Hier ist zu sehen, dass

    alle direkt in der Klasse definierten Methoden ihren Parameter an die write-Methodefr den Typ uint8_t weitergeben. Die Varianten fr die Behandlung von Strings werdenaus der Print-Klasse bernommen. Listing lst:print-write zeigt ihre Implementation. Dieerste Methode reicht ihren Parameter, einen String, und die Lnge des Strings weiteran die zweite Methode. Die zweite Methode ruft wiederum fr jedes Zeichen des Stringsdie write-Methode fr den Typ uint8_t auf. Die Methode fr uint8_t-Werte wird alsofr alle Sendeoperationen verwendet.

    Listing 4.8: Gekrzter Ausschnitt aus HardwareSerial.h der Arduino-Bibliothekclass HardwareSer ia l : public Stream{ . . . .

    virtual s i z e_t wr i t e ( uint8_t ) ;inl ine s i z e_t wr i t e ( unsigned long n) { return wr i t e ( ( uint8_t )n ) ; }inl ine s i z e_t wr i t e ( long n) { return wr i t e ( ( uint8_t )n ) ; }inl ine s i z e_t wr i t e ( unsigned int n) { return wr i t e ( ( uint8_t )n ) ; }inl ine s i z e_t wr i t e ( int n) { return wr i t e ( ( uint8_t )n ) ; }using Print : : wr i t e ; // p u l l in wr i t e ( s t r ) and wr i t e ( buf , s i z e ) from Print. . . .

    } ;

    Listing 4.9: Ausschnitte aus Print.h und Print.cpp der Arduino-Bibliotheks i z e_t wr i t e ( const char s t r ) {

    i f ( s t r == NULL) return 0 ;return wr i t e ( ( const uint8_t ) s t r , s t r l e n ( s t r ) ) ;

    }

    s i z e_t Pr int : : wr i t e ( const uint8_t bu f f e r , s i z e_t s i z e ){s i z e_t n = 0 ;while ( s i z e ) {

    n += wr i t e ( b u f f e r ++);}return n ;

    }

    Die in Listing 4.9 gezeigte Methode Print::write(const uint8_t *buffer, size_t size)ist nicht threadsicher. Dies kann man leicht an einem Beispiel erkennen. Ein Task, dersie nutzt, versendet die Zeichen des bergebenen Strings einzeln der Reihe nach. Wenner dabei von einem anderen Task unterbrochen wird und dieser seinerseits Daten berdie serielle Schnittstelle sendet, dann werden die Daten der beiden Tasks vermischt.Der Empfnger erhlt zunchst den ersten Teil der Nachricht des ersten Tasks, danneinen Teil oder die komplette Nachricht des zweiten Tasks und am Ende den Rest derNachricht des ersten Tasks. Damit ist mindestens die erste Nachricht zerstrt. Es ist alsonicht gesichert, dass eine Nachricht korrekt gesendet wird, wenn mehr als ein Task aufdie serielle Schnittstelle zugreift.

    24

  • Die in Listing 4.10 gezeigte write-Methode ist ebenfalls nicht threadsicher. Es kannan mehreren Stellen zu Fehlverhalten kommen.Die erste Bedingung prft, ob sofort gesendet werden kann. Wenn dies der Fall ist,

    dann wird der zu sendende Wert in das Datenregister geschrieben und anschlieendein Bit gesetzt, dass dem Mikrocontroller singalisiert, dass er ein Zeichen senden soll.Unterbricht ein anderer Task den Ablauf genau nach dem fllen des Datenregisters undsendet seinerseits etwas ber die Schnittstelle, dann berschreibt er dabei den Wert desersten Tasks. Wenn danach der erste Task seine Ttigkeit fortsetzt und das Sendebitsetzt, dann wird statt seines eigenen Wertes der Wert seines Vorgngers gesetzt. SeineInformation geht also verloren.

    Listing 4.10: Ausschnitt aus HardwareSerial.cpp der Arduino-Bibliotheks i z e_t HardwareSer ia l : : wr i t e ( uint8_t c ){

    // I f the b u f f e r and the data r e g i s t e r i s empty , j u s t wr i t e the by t e// to the data r e g i s t e r and be done . This s h o r t c u t h e l p s// s i g n i f i c a n t l y improve the e f f e c t i v e da ta ra t e at h igh (>// 500 k b i t / s ) b i t r a t e s , where i n t e r r u p t overhead becomes a slowdown .i f ( _tx_buffer_head == _tx_buf fer_tai l && bi t_i s_set ( _ucsra , UDRE0) ) {

    _udr = c ;s b i ( _ucsra , TXC0) ;return 1 ;

    }tx_buffer_index_t i = ( _tx_buffer_head + 1) \% SERIAL_TX_BUFFER_SIZE;

    // I f the output b u f f e r i s f u l l , t h e r e s noth ing f o r i t o ther than to// wai t f o r the i n t e r r u p t hand ler to empty i t a b i twhile ( i == _tx_buf fer_tai l ) {

    i f ( b i t_ i s_c l ea r (SREG, SREG_I) ) {// I n t e r r u p t s are d i s ab l ed , so we l l have to p o l l the data// r e g i s t e r empty f l a g o u r s e l v e s . I f i t i s se t , pre tend an// i n t e r r u p t has happened and c a l l the hand ler to f r e e up// space f o r us .i f ( b i t_i s_set ( _ucsra , UDRE0) )

    _tx_udr_empty_irq ( ) ;} else {

    // nop , the i n t e r r u p t hand ler w i l l f r e e up space f o r us}

    }

    _tx_buffer [ _tx_buffer_head ] = c ;_tx_buffer_head = i ;

    s b i ( _ucsrb , UDRIE0 ) ;_written = true ;

    return 1 ;}

    25

  • 5 FazitDie von Bill Greiman als Bibliothek fr die Arduino-IDE verpackte Version von FreeR-TOS entspricht schon von sich aus in etwa den Anforderungen dieser Arbeit. FreeRTOS-Arduino ist sofort im Lehrbetrieb und im Hobby-Bereich einsetzbar. Die Grundfunktio-nen stehen bereit und das System ist mit allen Arduino-Boards kompatibel. Es geltendabei allerdings einige Einschrnkungen, die bercksichtigt werden mssen, weil mancheFunktionen fehlerhaft oder ungenau arbeiten knnen. Die Arduino-Bibliothek muss nochan einigen Stellen berarbeitet werden, um die problemlose Nutzung zu gewhrleisten.Die fehlende Threadsicherheit der Speicherallokation durch die malloc-Funktion be-

    deutet, dass bei der Benutzung dieser Funktion immer die Gefahr eines Fehlverhaltensbesteht. An dieser Stelle sind die Arduino-Entwickler gefordert ihre mitgelieferten Versio-nen der libc anzupassen, sodass externe Bibliotheken unkompliziert eine sichere Varianteder malloc-Funktion bereitstellen knnen.Gleiches gilt fr die delay-Funktion, deren korrekte Funktion vom Verhalten aller ak-

    tiven Tasks abhngig ist. Statt externen Bibliotheken ein einhngen innerhalb der Funk-tion zu ermglichen sollten sie ein komplettes Ersetzen der Funktion zulassen. Dadurchknnten die Bibliotheken optimierte Versionen anbieten, die je nach Anwendungsfallentweder die Performance erhhen oder den Stromverbrauch verringern knnten.Wenn diese beiden Forderungen erfllt sind, bleibt nur noch die berprfung der

    gesamten Arduino-Bibliothek auf Threadsicherheit und die berarbeitung der dabeigefundenen gefhrdeten Funktionen. Damit wren alle notwendigen Schritte fr einenproduktiven Einsatz ohne Einschrnkungen getan.Neben diesen notwendigen Korrekturen gibt es noch einige kleinere Verbesserungen,

    die ebenfalls in Angriff genommen werden knnen. Diese sind nicht zwingend notwendig,wrden aber die Qualitt des Systems erhhen.Die erste und einfachste Manahme ist ein Upgrade der in FreeRTOS-Arduino ent-

    haltenen Version des Betriebssystems von 8.0.1 auf 8.2.1. Dies wrde ein neues Featuremit sich bringen, welches ein schnelleres Aufwecken von Tasks verspricht. [Ltda]Die zweite Manahme ist das das Zusammenfassen der im Moment getrennten Zweige

    von FreeRTOS-Arduino fr AVR-Prozessoren und ARM-Prozessoren. Die Fusion derbeiden Teile wrde die Benutzung noch ein wenig einfacher machen. Beim Importierender Bibliothek muss nicht mehr darauf geachtet werden, welcher Prozessor eingesetztwird. Und bei einem Prozessorwechsel muss nicht mehr die Bibliothek gewechselt werden.

    27

  • 6 AnhangTiming-Bibliotheken

    DueTimerhttps://github.com/ivanseidel/DueTimer

    Scheduler Library for Arduinohttp://www.codeproject.com/Tips/731031/Scheduler-Library-for-Arduino

    RELIABLE TASK SCHEDULING WITH ARDUINO / AVRhttps://chrisbarlow.wordpress.com/2012/09/13/reliable-task-scheduling-with-arduino-avr/

    A very simple Arduino task managerhttp://bleaklow.com/2010/07/20/a_very_simple_arduino_task_manager.html

    arduOShttp://playground.arduino.cc/Code/ArduOS

    Vollstndige Scheduler

    Name URLarduOS http://playground.arduino.cc/Code/ArduOSavr-os https://github.com/chrismoos/avr-osArDOS https://bitbucket.org/ctank/ardos-ide/wiki/HomeDuinOS https://github.com/DuinOS/DuinOSScmRTOS http://scmrtos.sourceforge.net/ScmRTOSNut/OS http://www.ethernut.deBeRTOS http://dev.bertos.org/TinyOS http://www.tinyos.net/ARTE/ERIKA http://erika.tuxfamily.org/drupal/ChibiOS http://www.chibios.orgFreeRTOS http://www.freertos.orgNilRTOS http://chibios.sourceforge.net/docs3/nil/index.htmlos47 v1.01 http://www.rtos47.com

    29

  • Literaturverzeichnis[ard] arduino.cc. Multiple blink tutorial. http://www.arduino.cc/en/Tutorial/

    MultipleBlinks.

    [Dem14] Yves Demirdjian. os47 homepage. http://www.rtos47.com/, September 2014.

    [eG10] egnite GmbH. Deutschsprachiges nutwiki. http://www.ethernut.de/nutwiki/Deutschsprachiges_NutWiki, September 2010.

    [Gre14a] Bill Greiman. Chibios-arduino. https://github.com/greiman/ChibiOS-Arduino, August 2014.

    [Gre14b] Bill Greiman. Nilrtos-arduino. https://github.com/greiman/NilRTOS-Arduino, August 2014.

    [Gre15] Bill Greiman. Freertos-arduino. https://github.com/greiman/FreeRTOS-Arduino, Januar 2015.

    [Ltda] Real Time Engineers Ltd. Freertos task notifications. http://www.freertos.org/RTOS-task-notifications.html.

    [Ltdb] Real Time Engineers Ltd. Memory management options for the freertos [. . . ]kernel. http://www.freertos.org/a00111.html.

    [PC13] EE Times Peter Clarke. Android, freertos top ee times 2013 embedded survey.http://www.eetimes.com/document.asp?doc_id=1263083, Februar 2013.

    [Sir] Giovanni Di Sirio. Nilrtos dokumentation. http://chibios.sourceforge.net/docs3/nil/index.html.

    [Sir15] Giovanni Di Sirio. Chibios/rt homepage. http://www.chibios.org/dokuwiki/doku.php, April 2015.

    [Srl11] Develer Srl. Portingguide. http://dev.bertos.org/wiki/PortingGuide, Ju-ni 2011.

    [Srl14a] Evidence Srl. Erika enterprise manual for arduino uno board. http://erika.tuxfamily.org/wiki/index.php?title=Arduino, Mai 2014.

    [Srl14b] Evidence Srl. Osek vdx certifications. http://erika.tuxfamily.org/wiki/index.php?title=OSEK_VDX_certifications, Februar 2014.

    31

  • [sT12] scmRTOS Team. Scmrtos homepage. http://scmrtos.sourceforge.net/ScmRTOS, Dezember 2012.

    [Tan09] Andrew S. Tanenbaum. Moderne Betriebssysteme. Pearson/Prentice Hall,Upper Saddle River, NJ, 2009.

    [Tha12] Le Trung Thang. Comparing real-time scheduling on the linux kernel andan rtos. http://www.embedded.com/design/operating-systems/4371651/Comparing-the-real-time-scheduling-policies-of-the-Linux-kernel-and-an-RTOS-,April 2012.

    32

  • Erklrung ( 14 Abs. 8 B.Sc. MIN PO)Ich versichere, dass ich die Bachelorarbeit im Studiengang Informatik selbststndig ver-fasst und keine anderen als die angegebenen Hilfsmittel insbesondere keine im Quellen-verzeichnis nicht benannten Internet-Quellen benutzt habe. Alle Stellen, die wrtlichoder sinngem aus Verffentlichungen entnommen wurden, sind als solche kenntlichgemacht. Ich versichere weiterhin, dass ich die Arbeit vorher nicht in einem anderenPrfungsverfahren eingereicht habe und die eingereichte schriftliche Fassung der aufdem elektronischen Speichermedium entspricht.

    Ort, Datum Unterschrift

  • Erklrung fr die BibliothekIch erklre mein Einverstndnis, dass die von mir erstellte Abschlussarbeit in die Biblio-thek der Uni Hamburg Mnchen eingestellt wird. Ich wurde darauf hingewiesen, dass dieHochschule in keiner Weise fr die missbruchliche Verwendung von Inhalten durch Drit-te infolge der Lektre der Arbeit haftet. Insbesondere ist mir bewusst, dass ich fr dieAnmeldung von Patenten, Warenzeichen oder Geschmacksmustern selbst verantwortlichbin und daraus Ansprche selbst verfolgen muss.

    Erklrung der Studierenden/des Studierenden

    Ort, Datum Unterschrift

    Einverstndniserklrung des/der betreuenden Hochschullehrers/-lehrerin bzw. Lehrbe-auftragten

    Ort, Datum Unterschrift

Recommended

View more >