Forum: Mikrocontroller und Digitale Elektronik einigermaßen Hardware-unabhängiger Code?


von Matthias U. (smurf)


Lesenswert?

Hi,

mein Problem: ich habe Code, der sowohl auf AVR-ATMega als auch auf 
"kleinen" STM32 und ESP8266 und was weiß ich noch allem laufen soll. 
Neben dem üblichen digitalen I/O-Kram, den zB Arduino problemlos 
plattformübergreifend unterstützt, brauche ich aber noch so Sachen wie 
Timer- und Portinterrupts und die Möglichkeit, die CPU bis zum 
Eintreffen des nächsten Interrupts schlafen zu legen.

Und das kann Arduino schonmal nicht, jedenfalls nicht von Haus aus.

Meine Frage ist nun: gibt es das irgendwo? oder ist das (wiedermal) ein 
Fall von "alles muss man selber machen"?

Das Einzige, was ich auf PlatformIO in der Richtung gefunden habe, ist 
"Simba". Sieht zwar auf den ersten Blick brauchbar aus, aber außer 
Portinterrupts kann das Teil nicht das was ich brauche …

von Stefan F. (Gast)


Lesenswert?

Mikrocontroller und alles was da dran hängt hängt, ist nun einmal 
Hardware.

Mehr Abstraktion, als was Arduino macht, halte ich für nicht hilfreich. 
Wie du an Arduino siehst, musste man sich da schon auf den kleinsten 
gemeinsamen Nenner beschränken und dennoch sind ernsthafte 
Anwendungsprogramme immer mehr oder weniger Hardare spezifisch.

Timer, Interrupts und CPU Features sind zwangsläufig Hardware 
spezifisch, da jede Mikrocontroller Serie anders funktioniert.

Ich denke, darum kommt man nicht herum.

Es gibt aber sicher auch einige Programmteile, die eben nicht 
Hardwareabhängig sein müssen. Es gibt zum Beispiel diese Adafruit GFX 
Bibliothek, die Text, Linien, Kreise ... auf beliebigen grafikfähigen 
Displays ausgibt. 90% des Codes sind dann Hardware unabhängig.

von Matthias U. (smurf)


Lesenswert?

Schon. Andererseits: Wirklich jeder Controller kann das alles. Insofern 
finde ich die Idee, dass diese Funktionen auch von einer Bibliothek mit 
ausreichend plattform-unabhängiger API unterstützt werden sollten, nicht 
so weit hergeholt.

von W.S. (Gast)


Lesenswert?

Matthias U. schrieb:
> Neben dem üblichen digitalen I/O-Kram, den zB Arduino problemlos
> plattformübergreifend unterstützt, brauche ich aber noch so Sachen wie
> Timer- und Portinterrupts und...

..und so weiter. Sowas kann keine hardware-unabhängige Software leisten, 
denn das IST Hardware.

Das, was du tun kannst, ist das Trennen deiner Ideen in 
Hardwareunabhängiges und Hardwareabhängiges. Für letzteres mußt du zu 
jeder Plattform eben einen Lowlevel-Treiber schreiben und deshalb ist es 
auch zwingend notwendig, daß dessen Interface nach oben hin 
hardwareUNabhängig ist. Das kannst du dir verdeutlichen, wenn du mal 
sowas vergleichst:

a)  SetzePin(int Port, int Bit, bool EinAus);
  und dazu
#define MotorPort 7
#define MotorPin  2
und dann SetzePin(MotorPort,MotorPin,true)

b)  SchalteMotorEin(void); und SchalteMotorAus(void);

Natürlich kann man seine Algorithmen mit beiden Varianten zum Erfolg 
führen, aber a) ist idiotisch, weil es keinerlei Plattformunabhängigkeit 
schafft, sondern lediglich die Portpins generalisiert. Kann ja sein, daß 
auf einer anderen Plattform überhaupt nicht per Port und Pin, sondern 
auf andere Weise der Motor gesteuert werden muß. Obendrein vergeigt man 
bei a) sehr oft die Möglichkeit, spezielle Eigenschaften der konkreten 
Plattform benutzen zu können. So haben ARM-Architekturen schon seit 
langem mehrere Zugriffs-Versionen drauf: Port-Zugriff, spezielle Setz- 
und Rücksetz-Register, Portpins als Boolean Array und vieles mehr je 
nach Hersteller und Chip. Da kann eine Funktion SetzePin nur den 
allerkleinsten gemeinsamen Nenner realisieren.

b) hingegen ist sowohl echt hardwareunabhängig (weil das im Treiber 
komplett erledigt wird), als auch sehr einfach im Treiber zu 
realisieren: kein Argument sondern void, also auch keinerlei 
Fallunterscheidung im Treiber, kurzum nix außer der angesagten Funktion.

W.S.

von Johannes S. (Gast)


Lesenswert?

Es gibt OS die auf verschiedenen Plattformen laufen, auf deinen 
genannten wäre eines zB https://www.riot-os.org
Ich benutze Mbed, das ist aber leider nur für ARM Cortex, wahrscheinlich 
weil es von ARM entwickelt und unterstützt wird.
Aber so ein OS fügt schon einiges an Komplexität hinzu, da muss man sich 
intensiv mit beschäftigen.

von Stefan F. (Gast)


Lesenswert?

Matthias U. schrieb:
> Andererseits: Wirklich jeder Controller kann das alles.

Fangen wir mal bei den Timern an.

Einfach nur in regelmäßigen Intervallen hoch zählen, kann jeder 
irgendwie. Auch PWM geht irgendwie, deswegen ist das in Arduno 
standardisiert wirden.

Was soll der generische Code denn machen, wenn du mit dem Timer ADC 
Messungen triggern willst, aber der aktuelle µC das gar nicht kann? Oder 
Totzeiten für H-Brücken im ns Bereich generieren? Das kannst du nicht 
einmal per Software umschiffen.

Was ist, wenn dein DMA Controller einen Interrupt auslösen soll, sobald 
ein gewisser Teil des Buffers gefüllt wurde aber der Mikrocontroller das 
nicht kann?

Wie willst du bei einem Controller aus der 8051 Serie einen Ausgang auf 
Push-Pull konfigurieren, wenn er nur Open-Kollektor mit Pull-Up hat?

Wie willst du Audio in CD Qualität aufzeichnen, wenn der ADC nur 10 Bit 
und nicht 2x 44,1 kHz kann?

von Johannes S. (Gast)


Lesenswert?

Matthias U. schrieb:
> brauche ich aber noch so Sachen wie Timer- und Portinterrupts und die
> Möglichkeit, die CPU bis zum Eintreffen des nächsten Interrupts schlafen
> zu legen.

Dafür gibt es doch https://www.arduino.cc/en/Reference/LowPowerDeepSleep

von Toby P. (Gast)


Lesenswert?

Matthias U. schrieb:
> Meine Frage ist nun: gibt es das irgendwo? oder ist das (wiedermal) ein
> Fall von "alles muss man selber machen"?

Abstrahieren kann jedes OS oder RTOS oder SPS Standard. Dass ist für 
µC's aber meist Overkill. Das jemand genau die gleichen Anforderungen 
wie du hatte, das alles ausgetestet und betriebsbereit veröffentlicht 
oder auf den Markt gebracht hat und dann noch alle Prozessoren deiner 
Wahl unterstützt kann möglich sein. Ist aber sehr unwahrscheinlich und 
wenn auch nicht billig.

Treiber für digital I/O zu schreiben ist imo einfach. Das ist eine 
Funktion die den Portstatus setzt oder zurück gibt. Die wird dann je 
nach Prozessortyp oder Sprache ausgetauscht. Timer, Sleep und A/D 
ähnlich.

Interrupts muss man wohl gesondert behandeln.

von Peter D. (peda)


Lesenswert?

Matthias U. schrieb:
> die Möglichkeit, die CPU bis zum
> Eintreffen des nächsten Interrupts schlafen zu legen.

Wenn es nur um das Warten geht, kann man ganz generisch ein Bool setzen, 
und in den Interrupts löschen.
Ansonsten, die ganzen Stromsparoptionen unterscheiden sich schon sehr 
bei den verschiedenen MCs und oft sogar von Typ zu Typ. Manche wachen 
nur durch Interrupts auf, manche ohne Interrupts usw. Auch muß man bei 
den AVRs eine ganz bestimmte Abfolge einhalten, sonst schlafen sie für 
immer.

Ich hab mal versucht, für verschiedene AVRs unabhängigen Code zu 
schreiben, hab es aber ganz schnell wieder aufgegeben. Die Unterschiede 
zwischen den Typen waren einfach zu groß. Z.B. bei den Timern ist es 
schon richtig abartig, wieviel verschiedene Varianten sich da Atmel 
ausgedacht hat.

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

Matthias U. schrieb:
> Schon. Andererseits: Wirklich jeder Controller kann das alles. Insofern
> finde ich die Idee, dass diese Funktionen auch von einer Bibliothek mit
> ausreichend plattform-unabhängiger API unterstützt werden sollten, nicht
> so weit hergeholt.

denke das ganze ein Stück weiter und du kommst beim Linux Device Tree 
raus. Abstraktion kostet halt CPU-Zeit.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.