Haftungsausschluss. Der Autor befürwortet nicht die Verwendung von Multitasking-Betriebssystemen für Mikrocontroller.
Das Leben erzwingt gnadenlos die Verwendung von Betriebssystemen (OS) für Mikrocontroller. Es gibt eine immense Anzahl solcher Systeme auf dem Markt. Betriebssystementwickler, die miteinander konkurrieren, versuchen, die Funktionalität ihrer Produkte zu maximieren. Dies führt häufig zu einer Erhöhung der „Schwere“ des Systems und erhöht auch die „Eintrittsschwelle“ für einen Programmierer, der Software für eingebettete Systeme entwickelt, erheblich.
Um nicht mit der Wahl des Betriebssystems für unsere Projekte gequält zu werden, den Geist nicht durch das Studium des Produkts eines anderen zu trüben, die Technik des Schreibens eingebetteter Anwendungen für Betriebssysteme zu beherrschen und herauszufinden, worum es geht, habe ich beschlossen, mein Betriebssystem zu schreiben. Es riecht nicht.
Das vorgeschlagene Betriebssystem (Betriebssystem, die Sprache wagt es nicht, ihr Betriebssystem und insbesondere OSRV aufzurufen) kooperiert mit statischen Aufgaben. Wie oben erwähnt, bin ich kein Befürworter der Verwendung des Betriebssystems für Mikrocontroller, aber noch mehr bin ich kein Befürworter der Verwendung von präventiven Betriebssystemen in Mikrocontrollern. Präventives Multitasking ist im Vergleich zu kooperativ nicht nur eine komplexe Kontextumschaltung, sondern auch eine ressourcenintensive Thread-Synchronisation. Die Verwendung dynamischer Aufgaben verkompliziert auch das Betriebssystem erheblich.
Das Betriebssystem wurde für den Prozessor der Cortex-M0-Familie entwickelt. Mit geringfügigen Änderungen an den Regeln zum Speichern und Wiederherstellen des Kontexts kann es für andere Prozessortypen verwendet werden.
Quellcode
Datei IntorOS.h#ifndef __INTOROS_H #define __INTOROS_H
IntorOS.c-Datei #define _INTOROS_C #include "stm32l0xx.h" #include "IntorOS.h"
Datei IntorOSSleepIAR.s #define SHT_PROGBITS 0x1 EXTERN KolvoTask EXTERN TaskList EXTERN TaskNum PUBLIC Sleep SECTION `.text`:CODE:NOROOT(2) THUMB
Datei IntorOSSleepGCC.s .cpu cortex-m0 .text .cfi_sections .debug_frame .section .text.Sleep,"ax",%progbits .align 1 .global Sleep .syntax unified .thumb .thumb_func .type Sleep, %function .extern KolvoTask .extern TaskList .extern TaskNum .cfi_startproc
OS-Kompilierungskonstanten
#define IntorOSMaxKolvoZadach (2)
Aus religiösen Gründen kann ich die dynamische Speicherzuweisung nicht verwenden, daher muss die erforderliche Speichermenge bei der Kompilierung angegeben werden.
OS OS-Dienste
void InitTask(void (*TaskPointer)(void), unsigned long Stek);
Aufgabeninitialisierung. Die Aufgabe wird in Form einer Funktion ausgeführt, ein Zeiger auf eine Funktion wird an die Initialisierungsprozedur übergeben. Während der Initialisierung müssen Sie die der Aufgabe zugewiesene Stapelgröße angeben. Die Reihenfolge, in der Aufgaben initialisiert werden, bestimmt deren Bezeichner. Die zuerst initialisierte Aufgabe hat den Bezeichner 0. Wenn Sie die Gesamtgröße des Stapels angeben, die größer als die reservierte ist, tritt ein Fehler auf. Wenn die Aufgabe initialisiert wird, wird der Zeiger auf den Aufgabenstapel gesetzt, der Stapel wird vom Aufgabenkontext geladen.
void StartOS(unsigned long Num);
Der Start des Betriebssystems. Als Argument für die Funktion wird die Kennung der Aufgabe übergeben, mit der die Ausführung gestartet werden soll. Wenn das Betriebssystem gestartet wird, wird der System-Timer auf ein Quantum von einer Millisekunde eingestellt. Der Kontext wird vom Stapel der gestarteten Aufgabe abgeschrieben und die Aufgabe aufgerufen.
void Sleep(unsigned long ms);
Planer Wenn diese Funktion von einer Task aufgerufen wird, wird die Steuerung an das Betriebssystem übertragen. Das Betriebssystem wählt eine zur Ausführung bereitstehende Aufgabe aus der Liste aus und überträgt die Kontrolle an sie. Das Argument der Funktion ist die Zeit in Millisekunden, nach der die Steuerung auf die aktuelle Aufgabe zurückgesetzt werden muss. Wenn eine Funktion mit dem Argument 0xFFFFFFFF aufgerufen wird, wird die Steuerung niemals zurückgegeben.
Es ist unmöglich, diese Funktion in C zu schreiben, daher zerstört der Algorithmus ihrer Operation die Logik der Sprache vollständig. Der Quellcode enthält Tests von Assemblersprachenprogrammen für die Programmiersysteme IAR und GCC. Für Betroffene ist der Code in C angegeben. Ich möchte jedoch darauf hinweisen, dass er nur mit bestimmten "Mondphasen" korrekt kompilieren kann. In meinem Fall geschah dies nur, wenn die mittlere Optimierungsebene verwendet wurde. Auf niedriger und hoher Ebene wurde der Code fehlerhaft kompiliert.
Datei Sleep.c extern Task_t TaskList[IntorOSMaxKolvoZadach];
void EndTask(void);
Abschluss der Aufgabe. Wie oben erwähnt, sind Aufgaben statisch, das Entladen von Aufgaben ist nicht möglich. Wenn Sie die Aufgabe erledigen müssen, können Sie diese Funktion verwenden. Die Aufgabe bleibt in der Liste, aber die Kontrolle wird nicht auf sie übertragen.
void StopTask(unsigned long Num); void StartTask(unsigned long Num);
Stoppen oder starten Sie eine Aufgabe. Argument ist die Kennung der Aufgabe. Mit diesen Funktionen können Sie den Task-Manager implementieren. Es ist zu beachten, dass Sie nur eine zuvor gestoppte Aufgabe starten können. Die Zeit bis zu ihrem Start beträgt 0xFFFFFFFF.
Verwenden des Betriebssystems
Zum Beispiel ein traditionelles Mikrocontroller- "Helword" für ein entwickeltes Betriebssystem.
#include "stm32l0xx.h" #include "stm32l0xx_ll_gpio.h" #include "IntorOS.h"
Abschließend möchte ich aufrichtig hoffen, dass dieses zum Spaß entwickelte Betriebssystem für Entwickler von Software für eingebettete Systeme interessant und nützlich sein wird.