Ich bin ja gerade dabei, mein 25J nicht genutztes C wieder auf Vordermann zu bringen. und wozu? Um ein Spielzeug wie den Arduino zum fliegen zu bringen. Ich mag den Arduino trotzdem :-) Wegen 25J Nichtstun gelte ich ja wieder als Anfänger. Bevor ich programmiere, will ich ein Konzept haben. Ein Konzept, das (später) auch größere und komplexe Aufgaben easy+locker bewältigen kann. Was haltet ihr davon, alle I/O-Operationen im Interrupt abzuarbeiten? Jedenfalls das "Grobe", z.B. valide Portabfrage, simutaneous sampling, Entprellung, Dämpfung .... Das Mainprogramm greift dann gar nicht mehr direkt auf die Ports zu, sondern nur auf aufbereitete (und damit validen) korrespondierenden Speicherstellen (Variablen). Ich könnte mir vorstellen, dass es ausreicht, z.B. 25 x pro Sek. die Eingangsports abzufragen, diese ggf. zu entprellen und dem Hauptprogramm als einen validen Wert global zur Verfügung zu stellen. Damit wären viele Problem gelöst, mit der sich ein Anfänger üblicherweise rumplagen muss, wie z.B. ein nicht oder nicht korrekt entprellter Schalter/Taster. Ich habe das früher in MCUs/Embedded gerne realisiert, was eigentlich immer nützlich war. So richtig erinnere ich mich leider nicht mehr. 25 Jahre, viel vergessen ... :(
Ja, so etwas ist eine sehr gute Vorgehensweise, die sich in der Tat als äußerst robust gegen Störungen erweist. Man sollte nur darauf achten, in solch einem Interrupthandler keine großen Verzweigungen des Programmablauf oder irgendetwas mit nicht vorhersagbar geringem Rechenzeitbedarf einzubauen. Gerade bei hochauflösenden A/D-Wandler kann man auf diese Art und Weise auch sicherstellen, dass deren Leistungsaufnahme auch nicht durch die Firmware beeinflusst wird, sondern konstant und reproduzierbar ist. Hierdurch kann man thermische Drift reduzieren. Ich arbeite derzeit an einem FPGA, bei dem insgesamt 110 A/D-Wandler-Kanäle in Hardware angesteuert und ausgelesen werden. Die zugehörige Microblaze-Firmware verarbeitet all die Daten auch in einem Timerinterrupt, der mit einstellbarem Zeitversatz synchron zur Ausleselogik erzeugt wird. Für die Software im Vordergrund bleibt auch nur ein Bruchteil der Gesamtrechenleistung übrig, was aber völlig ausreicht. Auch aus dem Bereich der Telefonanlagen kenne ich genau diese Vorgehensweise, d.h. die gesamte Sprachvermittlung, Tonerzeugung und -erkennung läuft in einem (ISDN-synchronen) 8kHz-Handler und wird "von außen" gesteuert, d.h. teils sogar über selbstmodifizierenden Programmcode. Letzteres ist aber nur sinnvoll, wenn man wirklich das allerletzte Bisschen an Rechenleistung herausholen muss.
:
Bearbeitet durch User
Roth schrieb: > Was haltet ihr davon, alle I/O-Operationen im Interrupt abzuarbeiten? Für die Entprellung ist das in jedem Fall sinnvoll, ebenso bei der Ausgabe von Daten an multiplexte Anzeigen, weil beides sowieso in einem festen Zeitraster erfolgen sollte. Ich erledige Tastaturabfrage und Anzeige normalerweise in einem 1ms-Timerinterrupt, wobei z.B. die Tastenverarbeitung einschliesslich Entprellung nicht in jedem 1ms-Takt erfolgen muss, bei ein paar Tasten genügt auch jedes 2. oder 4. Mal, ebenso für die Anzeige, das kann man zur besseren Lastverteilung dann durch einen zusätzlichen Zähler gegeneinander verschachteln. Praktisch gibt es für eine 8stellige Anzeige einen 8stelligen Puffer, in den schreibt das Hauptprogramm rein was angezeigt werden soll und die Timerroutine befördert das auf die Anzeige, umgekehrt erkennt die Timerroutine Tastendrücke und speichert sie in einen Eingabepuffer. Serielle Daten können ebenso behandelt werden, allerdings begrenzt ein 1ms-Takt die Baudrate auf 9600 Baud. Braucht man es schneller, kann man einen kürzeren Zeitttakt wählen oder man benutzt für Seriell-I/O eigene Interrupts. Ähnliches gilt für ADC-Daten. Sehr wichtig: keine Verzögerungen im Interrupt, nur die nackte Rechenzeit. D.h. z.B. ist ein Zeichen am seriellen Port angekommen, wird es in einen Eingangspuffer gelegt, sonst passiert NICHTS - auf keinen Fall wird auf irgendetwas gewartet. Da die Verarbeitung asynchron erfolgt, muss man sich Gedanken machen über konkurrierende Datenzugriffe. Im Interrupt ist das normalerweise kein Problem, weil das Hauptprogramm den Interrupt nicht unterbricht, aber wenn das Hauptprogramm ein Zeichen von einem Puffer holt und den Zeiger eins weiter setzt darf dazwischen kein Interrupt auftreten, z.B. schliesst man das mit Enable/Disable Interrupt aus oder durch atomare Operationen, wenn es die gibt. Bei Systemen mit mehreren IRQ-Prioritäten wird es komplizierter. Georg
Andreas S. schrieb: > Timerinterrupt, der mit einstellbarem Zeitversatz synchron zur > Ausleselogik erzeugt wird. Das könnte man theoretisch auch in Main unterbringen. Ich habe das mal in einem PIC umgesetzt, der keine Timer hatte. Dem Hauptprogramm habe ich den "Timer"-Block einfach vorangestellt, und das ganze mit ein paar Steuer-Variablen zeitlich synchronisiert. Das lief tatsächlich funktionell wie ein echter Timer, und das Mainprogramm konnte völlig auf die aufbereiteten und validen I/O-Results des "Timers" zurückgreifen. Das wichtigste ist, wie du schon geschrieben hast, sich mit den Laufzeiten SEHR GUT auseinanderzusetzen. Sonst ist der Crash vorprogrammiert. Such mal Fehler in einen Timer-Interrupt ... Für mich gilt daher: Code in einem Timer-Interrupt (gilt für alle Interrupts) sollte so kurz wie möglich sein. Wenn der Timer neu triggert, während ein alter Prozess noch am laufen ist, kann sich jeder vorstellen, was dann passiert ;)
georg schrieb: > Da die Verarbeitung asynchron erfolgt, muss man sich Gedanken machen > über konkurrierende Datenzugriffe. Im Interrupt ist das normalerweise > kein Problem, weil das Hauptprogramm den Interrupt nicht unterbricht, > aber wenn das Hauptprogramm ein Zeichen von einem Puffer holt und den > Zeiger eins weiter setzt darf dazwischen kein Interrupt auftreten Das ist völlig richtig. Ich erinnere mich. Eine Z80-Maschine hatte dazu eine DI- und EI-Anweisung (Disable/Enable Interrupt) implementiert, die im Hauptprogramm den Timer für die Auslesezeit der Variablen temporär blocken konnte (etwaige verlorene Interrupts wurden nach EI komplett nachgeholt).
georg schrieb: > Bei Systemen mit mehreren IRQ-Prioritäten > wird es komplizierter. Du meinst mit mehreren INT-Ebenen, d.h. sich gegenseitig unterbrechbare Ineterrupts? Dann wird es nach meiner Erfahrung einfacher!
Roth schrieb: > Was haltet ihr davon, alle I/O-Operationen im Interrupt abzuarbeiten? > Jedenfalls das "Grobe", z.B. valide Portabfrage, simutaneous sampling, > Entprellung, Dämpfung .... > > Das Mainprogramm greift dann gar nicht mehr direkt auf die Ports zu, > sondern nur auf aufbereitete (und damit validen) korrespondierenden > Speicherstellen (Variablen). Ersteres ist eine ausgesprochen dusslige Idee und aus Letzterem könnte man etwas Sinnvolles machen. Also: Portabfragen eben bloß so per Interrupt tun zu wollen, ist blanker Unsinn. Interrupts sind dazu da, den gewöhnlichen Lauf der Abarbeitung zum Behandeln von zeitlich nicht vorhergesehenen Ereignissen mal eben zu unterbrechen - und nicht zum Port-Polling. Zweitens: Die Idee, nicht alles durcheinander zu wurschteln, sondern sauber zu unterscheiden zwischen den Algorithmen, also den höheren Programmstrukturen und den Lowlevel-Ebenen, also den Hardware-Treibern, ist sehr vernünftig. Aber sowas in irgendwelche "korrespondierenden Speicherstellen" münden zu lassen, ist albern. Was soll daraus werden? Sowas geht bestenfalls für die Systemuhr, die im Hintergrund die Uhrzeit seit dem Einschalten in Millisekunden zählt, weswegen man eben auf diese Uhrzeit als long Variable von überall her LESEND zugreifen kann. Ich geb dir mal ein paar Beispiele, wie man die Schnittstellen zwischen Lowlevel und dem Rest der Firmware gestalten kann: Unit Motor (eine separate C Quelle, hier nur das, was in die zugehörige .h kommt): bool InitMotor(void); void MotorEin(void); void MotorAus(void); Unit Serial (für UART's und dergleichen) bool InitSerial(long Baudrate); bool IsPlatzImSendepuffer(void); char CharOut(char C); bool IsCharAvailable(void); char ReaChar(void); Unit I2C: bool InitI2C(void); bool I2C_OpenSlave(byte Addr, bool toRead); bool I2C_ByteOut(byte B); byte I2C_ByteIn(bool GibACK); void I2C_CloseSlave(void); und so weiter. Merke: Die Lowlevel-Treiber sollen sich tatsächlich um die jeweilige Hardware kümmern und nicht die höheren Schichten mit Hardwaredetails belästigen. Ebenso soll in den zugehörigen .h auch nur so viel drinstehen, wie "von oben" tatsächlich benötigt wird - und nicht jeder lowlevelinterne Krempel. Dabei werden die Treiber sicherlich diverse Interrupts benötigen und die entsprechenden Interrupthandler beinhalten. Ebenso werden sie öfters auch Datenflüsse zwischenpuffern, z.B. bei den seriellen kanälen (UART, USB etc.) Aber das alles soll die höheren Schichten nichts angehen und folglich auch nicht aus dem jeweiligen Treiber herausgrinsen. Und für simple Portangelegenheiten solltest du auch nicht versuchen, sowas zu generalisieren, sondern du solltest dir einen treiber für die dahintersteckende AUFGABE schreiben, also nicht SetzePort(port,bit) sondern SchalteLampeEin(void) oder RelaisAus(void) W.S.
W.S. schrieb: > Ersteres ist eine ausgesprochen dusslige Idee und aus Letzterem könnte > man etwas Sinnvolles machen. Warum schreibst du so etwas? Deinem Kommi nach zu folgen hast du doch Ahnung. Selbstverständlich werden Timer-Interupts zum zum Port-Polling genutzt. Bevorzugt sogar. Wie denn sonst? Zeichen von der Tastatur werden in den Puffer geschrieben, wo sie das Programm bzw. die Firmware auf Main-Ebene dann auslesen kann. Es gibt noch weitere "999 Beispiele".
Roth schrieb: > Ich könnte mir vorstellen, dass es ausreicht, z.B. 25 x pro Sek. die > Eingangsports abzufragen, diese ggf. zu entprellen und dem Hauptprogramm > als einen validen Wert global zur Verfügung zu stellen. Das kommt drauf an, was an deinen Eingangsports für Signale anliegen. Wenn das irgendwelche quasistatischen Signale sind, kannst du das machen. Aber sobald die Signale ein bisschen dynamischer sind, wird man evtl. sogar auf entsprechend schnelle Hardware zurück greifen.
W.S. schrieb: > Interrupts sind dazu da, den gewöhnlichen Lauf der Abarbeitung > zum Behandeln von zeitlich nicht vorhergesehenen Ereignissen mal eben zu > unterbrechen Sobald ihr im Unterricht auch Timer-Interrupts kennenlernt die aufgrund von zeitlich "vorhergesehenen" (Programmierer würden von "vordefinierten" schreiben) Bedingungen den 'gewöhnlichen' Lauf (was bei euch auch immer ein 'gewöhnlicher' Lauf im Gegensatz zu programmierten Anweisungen bei konventioneller Programmierung sein mag) "mal eben unterbrechen", könnt ihr lernen, dass Interrupts nicht nur zum 'Behandeln' zeitlich nicht vorhergesehenen Ereignisse "da sind".
W.S. schrieb: > Aber sowas in irgendwelche "korrespondierenden > Speicherstellen" münden zu lassen, ist albern. Was > soll daraus werden? Eine SPS. Nur haben Hobby-Mikrocontroller-Bastler selten Ahnung davon, wie eine SPS funktioniert -- deswegen gilt dann dort: "Was der Bauer nicht kennt, das frisst er nicht." Das die Industrie das millionenfach so macht, interessiert dann nicht.
W.S. schrieb: > Interrupts sind dazu da, den gewöhnlichen Lauf der Abarbeitung > zum Behandeln von zeitlich nicht vorhergesehenen Ereignissen mal eben zu > unterbrechen. Wer hat dir den Floh ins Ohr gesetzt? Gerade wenn es auf zeitlich genau vorhersehbare Abläufe an kommt, die unabhängig vom aktuellen Status des Programms sein müssen, sind Interrupts das Mittel der Wahl - ausgelöst durch einen Timer. Etwas vorhersehbareres als den Timertakt gibt es eigentlich nicht, wenn man mal von externen Zeitnormalen absieht.
Roth schrieb: > Was haltet ihr davon, alle I/O-Operationen im Interrupt > abzuarbeiten? Übertreibung. :) > Jedenfalls das "Grobe", z.B. valide Portabfrage, simutaneous > sampling, Entprellung, Dämpfung .... > > Das Mainprogramm greift dann gar nicht mehr direkt auf die > Ports zu, sondern nur auf aufbereitete (und damit validen) > korrespondierenden Speicherstellen (Variablen). Das geht aber auch anders als mittels Interrupt. Die SPS bündelt die Portzugriffe, d.h. sie fertigt erst ein Speicherabbild der Eingaenge an, fuehrt dann eine Runde des Hauptprogrammes aus und schreibt dann das Speicher- abbild der Ausgaenge heraus. Das vereinigt beide Vorteile -- das Hauptprogramm muss sich nicht mehr mit Portzugriffen herumaergern, aber es koennen auch keine Synchronisations- probleme auftreten wie bei timergesteuertem Polling. Deine Idee ist grundsaetzlich nicht schlecht, aber ich wuerde vielleicht nicht so weit gehen, ALLES I/O im Interrupt zu machen. Man kann die Methoden ja flexibel kombinieren.
my2ct schrieb: > Das kommt drauf an, was an deinen Eingangsports für Signale anliegen. Natürlich ist es selten sinnvoll, alles über einen Kamm zu scheren. Aber darum ging es mir nicht. Ich beabsichtige, wie beschrieben, ein paar (nicht alle) Routinen in einen Interrupt zu verlagern. Mit dem Zweck, das Hauptprogramm von Trivialitäten (Entprellung, Dämpfung, ...) zu entlasten. Wie schön es sich programmieren lässt, wenn der Programimerer valide Signale vorliegen hat, weiß nur der, der das schon mal umgesetzt hat. Egon D. schrieb: > Eine SPS. Nicht nur bei SPS wird das umgesetzt. Wieviele Tastaturen ahbe ich schon gesehen, die keinen Hilfsprozessor im Gehäuse hatten. Hier bleibt nur das Polling, weil passive Tastaturen nun mal kein Interrupt-Signal liefern können. Egon D. schrieb: > Deine Idee ist grundsaetzlich nicht schlecht, aber ich > wuerde vielleicht nicht so weit gehen, ALLES I/O im > Interrupt zu machen. Man kann die Methoden ja flexibel kombinieren. Das beabsichtige ich und ich hoffe in diesem Thema auf Hinweise. Was ihr ja auch tut. Vielen Dank an alle :´-)
my2ct schrieb: > Das kommt drauf an, was an deinen Eingangsports für Signale anliegen. > Wenn das irgendwelche quasistatischen Signale sind, kannst du das > machen. Aber sobald die Signale ein bisschen dynamischer sind, wird man > evtl. sogar auf entsprechend schnelle Hardware zurück greifen. Ich habe heute irgendwo die (Assembler)Sourcen einer kompletten Firmware verlinkt. Diese Sourcen sind sowas von durchdacht. 40 Jahre alt, aber das ist für mich immer noch wie ein Bibel. Und vor allem: unübertroffen in der Effizienz. Die Tastatur wurde erst quantitativ über X- und Y-Leitungen gecheckt ("Liegt etwas an?") und nur wenn JA, wurde qualitativ ausgewertet: der Code der gerückten Taste in ein Puffer eingelesen. (Amstrad 8 Bit Z80 System mit 4 MHz).
Roth schrieb: > Andreas S. schrieb: >> Timerinterrupt, der mit einstellbarem Zeitversatz synchron zur >> Ausleselogik erzeugt wird. > Das könnte man theoretisch auch in Main unterbringen. Ich habe das mal > in einem PIC umgesetzt, der keine Timer hatte. Dem Hauptprogramm habe > ich den "Timer"-Block einfach vorangestellt, und das ganze mit ein paar > Steuer-Variablen zeitlich synchronisiert. Das lief tatsächlich > funktionell wie ein echter Timer, und das Mainprogramm konnte völlig auf > die aufbereiteten und validen I/O-Results des "Timers" zurückgreifen. Das funktioniert nur dann einwandfrei, wenn "Langläufer" im Hauptprogramm in mehrere kurze Abschnitte zerlegt werden und pro Programmdurchlauf nur einer abgearbeitet wird. Es ist aber wesentlich schwieriger, hierbei den Worst-Case-Fall zu berechnen oder zumindest abzuschätzen. Außerdem muss man viel zu große Reserven für ggf. selten auftretende Vorgänge vorhalten. Ein typischer Fall, in dem so etwas ohnehin nur schlecht funktioniert, ist ein eingebauter Webserver, da ein Webbrowser (oder sonstiger HTTP-Client) eine fast beliebig hohe Systemlast verursachen kann. Bei meinem konkreten Projekt werden in dem Interrupthandler natürlich auch noch andere streng zeitsynchrone und hochgradig wichtige Dinge erledigt, wie z.B. Schwellwertüberschreitungen, die zur Abschaltung von Teilen des Systems führen können. So etwas darf auf keinen Fall durch einen "DoS-Angriff" über eine der Schnittstellen ausgebremst werden. > Das wichtigste ist, wie du schon geschrieben hast, sich mit den > Laufzeiten SEHR GUT auseinanderzusetzen. Sonst ist der Crash > vorprogrammiert. Such mal Fehler in einen Timer-Interrupt ... Mit einem externen Statusausgang und einem Oszilloskop oder Logianalysator kann man den Rechenleistungsbedarf des Interrupthandlers sehr genau bestimmen, insbesondere auch den Jitter, der z.B. auch durch das Hauptprogramm oder gar anderen Interrupthandler verursacht wird. In einem FPGA kann man auch sehr einfach einen kleinen Profiler implementieren, der diese Überwachung durchführt, d.h. einen Timer, der beim Interrupt gestartet und durch einen Registerzugriff beim Verlassen des Interrupthandlers wieder gestoppt wird. Wird er bis zum nächsten Interrupt nicht gestoppt, kann dies ebenfalls protokolliert werden. Diese Funktionalität lässt sich sogar in Richtung eines Watchdogs ausbauen. > Für mich > gilt daher: Code in einem Timer-Interrupt (gilt für alle Interrupts) > sollte so kurz wie möglich sein. Er muss nicht so kurz wie möglich sein, sondern zuverlässig innerhalb eines Interruptzyklus ausgeführt werden. Je nachdem, wie viel es zu rechnen gibt, kann es große Reserven geben oder eben auch nicht. > Wenn der Timer neu triggert, während > ein alter Prozess noch am laufen ist, kann sich jeder vorstellen, was > dann passiert ;) Nein, dass kann man sich nicht so allgemein vorstellen, da es ganz empfindlich von alle möglichen Randbedingungen abhängt.
Roth schrieb: > Was haltet ihr davon, alle I/O-Operationen im Interrupt abzuarbeiten? > Jedenfalls das "Grobe", z.B. valide Portabfrage, simutaneous sampling, > Entprellung, Dämpfung .... Wenig. Der Interrupt wird stark aufgebläht und die Variablen müssen entweder übergeben werden (was die Latenz erhöht) oder global sein (was die Sache unübersichtlich und fehleranfällig macht). Dann sind Portabfragen selten universell. Das eine Signal braucht nur 1x pro Sekunde abgefragt werden, der Debouncer alle 20 ms und schnelle Signale evtl. sooft wie geht. Bei Ausgängen kommt es dann meist zum totalen Overload. Das beisst sich alles. Da mache in mir lieber ne loop mit nem Zähler (z.B. 0-1000ms) der durch den (timer)Interrupt hochgezählt wird und führe die Tasks entsprechend aus. Das macht den Interrupt schlank und ein Überlauf ist leicht und ohne Scope und Analyzer zu erkennen (wenn der Zähler > 1000 wird). Zusätzlich kann das ganze dann noch auf Units verteilt werden, was ich bei "alles im Interrupt" noch nicht hinbekommen habe. Ist das ganze SPS mäßig Zyklus gesteuert wird die Restzeit einfach am Ende in einer Loop verbraten (und gemessen).
Andreas S. schrieb: > Ein typischer Fall, in dem so etwas ohnehin nur schlecht funktioniert, > ist ein eingebauter Webserver, da ein Webbrowser (oder sonstiger > HTTP-Client) eine fast beliebig hohe Systemlast verursachen kann. In so einem Fall wäre imo ein RTOS oder Betriebssystem angesagt.
W.S. schrieb: > solltest dir einen treiber für die dahintersteckende AUFGABE schreiben, > also nicht SetzePort(port,bit) sondern SchalteLampeEin(void) oder > RelaisAus(void) > > W.S. ich bewunder deine Geduld! Aber, es ist so, wie c-hater immer schreibt: "Dazu muß man zuerst Denken lernen!"....
X4U schrieb: > In so einem Fall wäre imo ein RTOS oder Betriebssystem angesagt. Ein RTOS oder ein Betriebssystem ist auch "nur" eine Speicher-/Ablauf- und Tasksteuerung, der vielleicht irgend jemand mal einen Namen gegeben hat und mit programmiererfreundlichen Schnittstellen ausgestattet ist - nichts sonst.
"I/O-Operationen via Timer-Interrupt - gut oder überflüssig?" "gut" ist, wenn man genau den Aufwand betreibt, der notwendig ist, um ein bestimmtes Problem zu lösen. "überflüssig" ist, wenn man mehr (oder auch sehr viel mehr) Aufwand als notwendig betreibt, um ein bestimmtes Problem zu lösen. Ergo gibt es - ohne das eigentliche Problem zu kennen, das Du lösen willst - keine vernünftige Antwort auf deine Frage.
Roth schrieb: > Die Tastatur wurde erst quantitativ über X- und > Y-Leitungen gecheckt ("Liegt etwas an?") und nur wenn JA, wurde > qualitativ ausgewertet: der Code der gerückten Taste in ein Puffer > eingelesen. Wie Du selber schreibst, ist das ja auch ein alter Hut, der geschickterweise schon immer im Timerinterrupt (nebst Entprellung) erledigt wurde. Auch die Pufferung von seriellen Daten und Empfang bzw. Versand per Interrupt ist doch nichts Spezielles. Nur für Arduino-Nutzer dürfte das etwas geheimnisvoll Neues darstellen. Aber niemand käme auf die Idee, Schieberegister per Portpins anzusteuern und jedes Togglen per Interrupt auszulösen. Und niemand kommt auf die Idee, einen Schrittmotor im 1 - 10 ms Takt per Timerinterrupt drehen zu lassen. Dafür gibt es ja schließlich "delay()" ;-) Markus F. schrieb: > Ergo gibt es - ohne das eigentliche Problem zu kennen, das Du lösen > willst - keine vernünftige Antwort auf deine Frage. So sieht es aus!
Interrupts sind vielfach äquivalent zu einem RTOS ohne wait/sleep etc. wie Basic Tasks bei Autosar. Zudem eefirdern zyklusche Interrupts ähnliche strategien wie SPS-loop-nodule. Die Gefahr von RTOS-Tasks und Interrupts bleibt die notwendige Synchronisierung wenn zwischen verschiedenen Tasks/Interrupts Daten ausgetauscht werden. Jeder embedded Programmierer sollt das nach ein paar Jahren kennen (basics), der TO wird dabei offensichtlich auch viel Erfahrung sammeln. Das wirklich einfachste, robusteste und lesbarste ist die SPS-Loop. Wer sie nicht kennt, wird das bestreiten. Wer für die Ausnahmen (z.B. einzelne deutlich schnellere IO -prozesse) die intertask-probleme und -Lösungen nicht kennt, wird ein Vodoo-Programmierer bleiben (mit 4 nops geht's, ist wohl ein Compiler Bug)
So weit wollte ich gar nicht in die Tiefe gehen. Es geht um einen kleinen µC, mit ein paar Tastern und ADC-Eingängen. Der Timer Interrupt sollte dabei u.a. das Entprellen vornehmen und noch ein paar Notwendigkeiten, die keine nenneswerte Rechenleistung verlangen. Mehr nicht. Ein kleiner µC mit Interrupts auszustatten oder einen Webserver, dazwischen liegen Welten. Die liebsten Interrupts sind mir die, die ich in Assembler schreiben kann. Hohe Transparenz über das Geschehen, unabhängig von "Optimierungen" etwaiger Parser oder Compiler. Es ist stets darauf zu achten, was in einen Interrupt gepackt wird. Es ist in jedem Einzelfall zu prüfen, ob es Sinn macht und Vorteile für das Hauptprogramm bringt, Routinen in eine zeitkritische Umgebung auszulagern. Wie viele schon geschrieben haben: Da gibts kein grundlegendes Konzept. Insgesamt war der Ausflug interessant. Vieln Dank für die Beteiligung.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.