Ich habe viele Artikel gesehen, die mir sagen, dass ich RTOS für Zeitmanagement und Ressourcenmanagement verwenden sollte. Meine Zeit hat meine eigene Recherche nicht zugelassen, also wende ich mich an Chiphacker, um mich beraten zu lassen.
Ich verwende ressourcenarme Mikrocontroller (MSP430, PIC) und suchte nach RTOSs, die ich verwenden kann.
Auf den Punkt:
Ich verwende keine Systeme wie das Arduino, die Projekte, mit denen ich arbeite, können die Kosten eines solchen Systems nicht tragen.
Ich habe nicht viele persönliche Erfahrungen mit anderen Echtzeitbetriebssystemen als QNX gemacht (was im Großen und Ganzen großartig, aber nicht billig ist, und ich habe eine wirklich schlechte Erfahrung mit einem bestimmten Board-Anbieter und der Uns-egal-Einstellung von QNX für andere Systeme gemacht als ihre gebräuchlichsten), was zu groß für PICs und MSP430 ist.
Wo Sie von einem RTOS profitieren, liegt in Bereichen wie z
Für Peripheriegeräte eines PIC oder MSP430: Für serielle Ports würde ich einen Ringpuffer + Interrupts verwenden ... etwas, das ich einmal pro System schreibe und einfach wiederverwende; Andere Peripheriegeräte Ich glaube nicht, dass Sie von einem RTOS viel Unterstützung finden würden, da sie so herstellerspezifisch sind.
Wenn Sie ein mikrosekundengenaues Timing benötigen, wird ein RTOS wahrscheinlich nicht helfen - RTOS haben ein begrenztes Timing, haben aber normalerweise Timing-Jitter in ihrer Planung aufgrund von Verzögerungen beim Kontextwechsel ... QNX, das auf einem PXA270 ausgeführt wird, hatte Jitter in den typischen zehn Mikrosekunden, maximal 100-200us, also würde ich es nicht für Dinge verwenden, die schneller als etwa 100Hz laufen müssen oder die ein viel genaueres Timing als etwa 500us benötigen. Für solche Dinge müssen Sie wahrscheinlich Ihr eigenes Interrupt-Handling implementieren. Einige RTOSs werden damit gut spielen, andere werden es zu einem königlichen Schmerz machen: Ihr Timing und ihr Timing können möglicherweise nicht gut koexistieren.
Wenn das Timing/Scheduling nicht zu komplex ist, ist es möglicherweise besser, eine gut gestaltete Zustandsmaschine zu verwenden. Ich würde dringend empfehlen, Praktische Zustandsdiagramme in C/C++ zu lesen , falls Sie dies noch nicht getan haben. Wir haben diesen Ansatz in einigen unserer Projekte, in denen ich arbeite, verwendet, und er hat einige echte Vorteile gegenüber herkömmlichen Zustandsmaschinen für die Verwaltung von Komplexität .... das ist wirklich der einzige Grund, warum Sie ein Echtzeitbetriebssystem benötigen.
Hast du FreeRTOS ausprobiert ? Es ist kostenlos (vorbehaltlich der AGB) und wurde sowohl auf den MSP430 als auch auf verschiedene PIC-Varianten portiert.
Es ist klein im Vergleich zu einigen anderen, aber das macht es auch leicht zu erlernen, besonders wenn Sie noch nie ein RTOS verwendet haben.
Eine (nicht kostenlose) kommerzielle Lizenz ist verfügbar, ebenso wie eine IEC 61508/SIL 3-Version.
Ich habe gerade von NuttX RTOS erfahren, das sogar auf einem 8052 (8-Bit)-System funktionieren kann. Es hat nicht viele Ports, aber es sieht interessant aus. POSIX kann ein Plus sein, da es einen Teil Ihres Codes etwas portabler macht, wenn Sie auf einen stärkeren Prozessor umsteigen und Echtzeit-Linux oder QNX ausführen möchten.
Ich habe selbst keine Erfahrung mit kommerziellen RTOS's, aber ich benutze seit Jahren selbstgebaute! Sie sind großartig darin, Ihnen dabei zu helfen, Ihre Codeentwicklung auf viele Programmierer aufzuteilen, da sie im Wesentlichen jeder eine "Aufgabe" oder einen "Thread" bekommen können, um an seiner Seite zu arbeiten. Sie müssen immer noch koordinieren und jemand muss das gesamte Projekt beaufsichtigen, um sicherzustellen, dass jede Aufgabe ihren Termin einhalten kann.
Ich empfehle Ihnen auch, sich bei der Verwendung eines RTOS mit Rate Monotonic Analysis oder RMA zu befassen. Auf diese Weise können Sie sicherstellen, dass Ihre kritischen Aufgaben ihre Fristen einhalten.
Ich würde mir auch das ereignisgesteuerte Programmierframework QP-nano von Miro Samek ansehen , das mit oder ohne RTOS arbeiten kann und Ihnen trotzdem Echtzeitfähigkeit bietet. Damit unterteilen Sie Ihr Design in hierarchische Zustandsmaschinen statt in traditionelle Aufgaben. Jason S erwähnte Miros Buch in seinem Beitrag. Eine hervorragende Lektüre!
Eine Sache, die ich auf einer Reihe von Maschinen als nützlich empfunden habe, ist ein einfacher Stack-Switcher. Ich habe eigentlich keinen für den PIC geschrieben, aber ich würde erwarten, dass der Ansatz auf dem PIC18 gut funktionieren würde, wenn beide/alle Threads insgesamt 31 oder weniger Stapelebenen verwenden. Auf dem 8051 ist die Hauptroutine:
_taskswitch: xch a,SP xch a,_altSP xch a,SP ret
Auf dem PIC vergesse ich den Namen des Stapelzeigers, aber die Routine würde ungefähr so aussehen:
_taskswitch: movlb _altSP >> 8 movf _altSP ,w,b movff _STKPTR,altSP movwf_STKPTR,c Rückkehr
Rufen Sie zu Beginn Ihres Programms eine task2()-Routine auf, die altSP mit der Adresse des alternativen Stacks lädt (16 würde wahrscheinlich gut für einen PIC18Fxx funktionieren) und die task2-Schleife ausführt; diese Routine darf nie wiederkehren, sonst sterben die Dinge einen qualvollen Tod. Stattdessen sollte es _taskswitch immer dann aufrufen, wenn es die Kontrolle an die primäre Aufgabe abgeben möchte; die primäre Task sollte dann _taskswitch aufrufen, wann immer sie der sekundären Task nachgeben möchte. Oft hat man niedliche kleine Routinen wie:
void delay_t1 (unsigned short val) { tun Taskswitch(); while((unsigned short)(millisecond_clock - val) > 0xFF00); }
Beachten Sie, dass der Task-Umschalter keine Möglichkeit hat, eine 'Warten auf Bedingung' auszuführen; alles, was es unterstützt, ist ein Spinwait. Andererseits ist der Aufgabenwechsel so schnell, dass ein Versuch eines taskswitch(), während die andere Aufgabe auf das Ablaufen eines Timers wartet, zu der anderen Aufgabe wechselt, den Timer überprüft und schneller zurückwechselt als ein typischer Aufgabenwechsler würde feststellen, dass es keinen Taskswitch braucht.
Beachten Sie, dass kooperatives Multitasking einige Einschränkungen hat, aber es vermeidet die Notwendigkeit für viele Sperren und anderen Mutex-bezogenen Code in Fällen, in denen vorübergehend gestörte Invarianten schnell wiederhergestellt werden können.
(Bearbeiten): Ein paar Vorbehalte in Bezug auf automatische Variablen und dergleichen:
Kooperatives Multitasking erlaubt es einem nicht, Probleme mit Sperren und dergleichen vollständig zu vermeiden, aber es vereinfacht die Dinge wirklich erheblich. In einem präemptiven RTOS mit einem kompakten Garbage Collector ist es beispielsweise notwendig, das Fixieren von Objekten zuzulassen. Bei Verwendung eines kooperativen Umschalters ist dies nicht erforderlich, vorausgesetzt, der Code geht davon aus, dass sich GC-Objekte jederzeit bewegen können, wenn taskswitch() aufgerufen wird. Ein kompaktierender Kollektor, der sich nicht um gepinnte Objekte kümmern muss, kann viel einfacher sein als einer, der dies tut.
Ich habe Salvo auf dem MSP430 verwendet. Dies war sehr ressourcenschonend und, vorausgesetzt, Sie befolgen die Implementierungsregeln, sehr einfach zu verwenden und zuverlässig. Dies ist ein kooperatives OS und erfordert, dass Aufgabenumschaltungen auf der äußeren Funktionsaufrufebene der Aufgabenfunktionen durchgeführt werden. Diese Einschränkung ermöglicht es dem Betriebssystem, in sehr kleinen Speichergeräten zu arbeiten, ohne große Mengen an Stapelplatz zu verwenden, um Aufgabenkontexte aufrechtzuerhalten.
Auf dem AVR32 verwende ich FreeRTOS. Bisher wieder sehr zuverlässig, aber ich hatte einige Konfigurations-/Versionsabweichungen zwischen der Version, die FreeRTOS veröffentlicht, und der Version, die mit dem Atmel-Framework geliefert wird. Dies hat jedoch den Vorteil, dass es kostenlos ist!
Die Dezember-Ausgabe von Everyday Practical Electronics enthält Teil 3 einer Serie über Echtzeit-Betriebssysteme für PICs (in der PIC n' Mix-Kolumne) und enthält Einzelheiten zum Einrichten von FreeRTOS mit MPLAB und einem PICKit 2. Die beiden vorherigen Artikel (die I noch nicht gesehen) scheinen die Vorzüge verschiedener Echtzeitbetriebssysteme diskutiert und sich für FreeRTOS entschieden zu haben. Sobald der aktuelle Artikel die Entwicklungsumgebung eingerichtet hat, beginnen sie mit dem Entwurf einer binären Digitaluhr. Es scheint, dass es noch mindestens einen weiteren Teil zu diesem Thema geben wird.
Ich bin mir nicht sicher, wie verfügbar EPE in den USA ist, aber es scheint einen US-Shop zu geben, der von ihrer Website aus verlinkt ist, und möglicherweise sind elektronische Kopien verfügbar.
Der CCS-Compiler für den PIC kommt mit einem einfachen RTOS. Ich habe es nicht ausprobiert, aber wenn Sie diesen Compiler haben, wäre es einfach, damit zu experimentieren.
Eng verwandte Frage: https://stackoverflow.com/questions/1624237/multithreading-using-c-on-pic18
Sie haben nicht viel über Ihre Bewerbung gesagt. Ob Sie ein RTOS verwenden, hängt stark davon ab, was Sie im PIC tun müssen. Wenn Sie nicht mehrere verschiedene asynchrone Dinge tun, die strenge Zeitgrenzen erfordern, oder mehrere Threads ausführen, ist ein RTOS möglicherweise übertrieben.
Es gibt viele Möglichkeiten, die Zeit auf einem Mikrocontroller zu organisieren, je nachdem, was am wichtigsten ist:
Konstante Bildrate: Für einen PIC, auf dem ein Servocontroller läuft, der beispielsweise mit 1000 Hz laufen muss. Wenn die Ausführung des PID-Algorithmus weniger als 1 ms dauert, können Sie den Rest der Millisekunde für andere Aufgaben verwenden, z. B. den CAN-Bus überprüfen, Sensoren lesen usw.
Alle Interrupts: Alles, was im PIC passiert, wird durch einen Interrupt ausgelöst. Die Unterbrechungen können entsprechend der Wichtigkeit des Ereignisses priorisiert werden.
Stecke es in eine Schleife und mache alles so schnell du kannst. Möglicherweise stellen Sie fest, dass dies geeignete Zeitgrenzen bietet.
Kortuk
Jason S
Kortuk