Forum: Mikrocontroller und Digitale Elektronik Stack overflow durch nested Interrupts?


von Rolf F. (Gast)


Lesenswert?

Können nested Interrupts einen Stack Overflow bewirken?

Und wo kann man eigentlich eine Liste der häufigsten Fehler-Ursachen und 
eine Liste aller Fehlerursachen (bei Microcontrollern) finden?

von thkais (Gast)


Lesenswert?

Aber sicher. Bei jedem Sprung in einen Interrupt wird die 
Rücksprungadresse ins Hauptprogramm auf dem Stack abgelegt (je nach 
Controller-Typ auch mehr), hinzu kommen noch evtl. gesicherte Register. 
Wenn nun sehr viele Interrupts verschachtelt aufgerufen werden, z.B. 
durch Aufrufe in mehreren Prioritäten, kann der Stack schon mal ins 
Schwitzen kommen.

von Peter D. (peda)


Lesenswert?

Kommt ganz auf den Prozessor an:

Z.B. beim 8051, der verschiedene Prioritäten in Hardware macht, nicht, 
da ja jede Priorität (max 4) auch nur einmal aktiv sein kann.


Aber z.B. beim AVR muß man höllisch aufpassen. Einfach nur die 
Interrupts wieder freigeben reicht da bei weitem nicht.
Damit ist ein Interrupt, der sich immer wieder selbst unterbricht schon 
vorprogrammiert. Ist dann quasi wie eine Rekursion ohne 
Abbruchbedingung.

Man muß also in sämtlichen Interrupts niederer Priorität sämtliche 
Interruptfreigaben neu setzen, d.h. nur die hohen enabled lassen, ehe 
der globale wieder freigegeben wird.


Fehlerlisten habe ich bisher noch nicht gesehen.
Das ist ja auch stark unbterschiedlich, z.B. je nach Architektur, 
Programmierstil, Programmiersprache bzw. reine Anfängerfehler.

Es gibt aber eine Menge Empfehlungen für gutes Programmieren.


Peter

von Rolf F. (Gast)


Lesenswert?

Aha, dann müssen einige Eingänge wohl hardwaremäßig enptprellt werden 
oder es müssen häufiger alle Interrupts disabled werden.

von Peter D. (peda)


Lesenswert?

Wenn es ums Entprellen geht, dann ist der externe Interrupt ja auch 
völlig fehl am Platze. So etwas muß man doch im Timerinterrupt machen 
(siehe Codesammlung).

Externe Interrupts sind nur dann gut, wenn man auch wirklich sehr 
schnell auf etwas reagieren muß, z.B. die Daten von einem Ethernetchip 
lesen oder von einer Festplatte usw., also Signale von digitalen 
Quellen.

Der externe Interrupt reagiert ja innerhalb 1µs oder weniger und so 
schnell drückt kein Mensch eine Taste.


Peter

von Rolf F. (Gast)


Lesenswert?

Ja, aber ich habe hier Code von einem anderen, der auf rund 100.000 
Geräten läuft u. der nun nach einer kleinen Hardware-Änderung nicht mehr 
richtig läuft. Es gibt da auch eine Funktion für busy wating um so zu 
entprellen, aber elegant ist das nicht.

von Peter D. (peda)


Lesenswert?

Der Timerinterrupt hat ja auch überhaupt nichts mit "busy waiting" zu 
tun.
Er liefert Dir ganz genau so, wie der externe Interrupt ein Signal, 
bloß, daß es eben bereits entprellt ist und um die Entprellzeit 
(10..100ms) verzögert.
Diese Entprellzeit wird aber nicht nutzlos verwartet, sondern ist 
einfach die Zeit, die bis zum nächsten Timerinterrupt
vergeht.
Dein Mainprogramm kann in dieser Zeit alles mögliche andere machen.


Auch, wenn eine Software auf einer Billion Geräte läuft, ist das nicht 
der geringste Beweis ihrer Fehlerfreiheit.


Peter

von Rolf F. (Gast)


Lesenswert?

Also ich würde zum Entprellen einfach mit jedem Timer-Interrupt die 
Ports überprüfen und einen gleitenden Mittelwert bilden (z. B. x = 2.0*x 
+ (P1 & X) * 0.333333333). Wenn der größer als 0,5 ist, dann wird der 
Wert 1 genommen und ansonsten 0. Es ist dann ein Tiefpass mit 
nachgeschaltetem Schmitt-Trigger (ohne Hysterese) in Software.
Damit braucht man keine Interrupts und es müsste nur regelmäßig der 
Zustand der Tasten abgefragt werden.

Was meinen denn die Experten dazu?

von Rolf F. (Gast)


Lesenswert?

Korrektur, ich meine natürlich

x = 2.0*x + (float)(P1 & X);
x *= 0.3333333333;

Minimal wäre

x += (float)(P1 & X);
x *= 0.5;

und allgemein wäre es

x = (n-1)*x + (float)(P1 & X);
x /= (float)n;

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

FLOAT zur Tastenentprellung??? Das ist völlig unnötige Speicher- und 
Rechenzeitverschwendung.

von Peter D. (peda)


Lesenswert?

"... mit jedem Timer-Interrupt ... braucht man keine Interrupts ..."

Also was denn nun ?


Da muß ich Andreas recht geben, das ist mit Abstand die umständlichste 
aller Methoden.


Peter

von Matthias (Gast)


Lesenswert?

Hi

natürlich. Was den sonst? Warum sollte ein einziges Bit in einem 
Register genügen wenn mans mit float machen kann. Warum denn nicht 
gleich mit double? Das passiert wenn der übliche PC-Hobby-Hacker auf µC 
umsteigt. Einem PC mag es nichts ausmachen wenn er mal ein paar 
float-Zahlen berechnen muß. Der macht das in Hardware und Speicher ist 
eh genug da. Ein µC braucht aber diverse Routinen die float per Software 
nachbilden was Flash, RAM und Geschwindigkeit kostet.

Deswegen gilt auf µC (8-Bitter):
Verwende kein float.
Wenn du doch float brauchst denk dir einen anderen Algorithmus aus.
Wenns garnicht anders geht rechne mit deutlich höherem Speicherverbrauch 
und beschwer dich nicht über langsame Programmausführung und knappes 
Flash.

Matthias

von Rolf F. (Gast)


Lesenswert?

Also einen Timer-Interrupt hat man doch zu 99,9 % sowieso; den braucht 
man nicht extra!
Für die Ports kann man die Interrupts einsparen.

Und ein Float pro Taster-Eingang ist doch nicht viel, außer man hat nur 
128 Byte RAM (statt den üblichen 2 kB).
Und wenn bei den üblichen 10 Mips noch das letzte Quentchen CPU-Zeit 
rausgequetscht werden muss, kann man das ganze auch in int realisieren. 
Mit dem Hardware-Multiplier ist es dann in jedem Fall schnell genug, 
weil nur Additionen u. Multiplikationen nötig sind.
Wichtig ist doch, dass es fehlertolerant funktioniert, keine CPU-Zeit 
mit busy wating verschwendet und fast immer problemlos realisierbar ist!

von Peter D. (peda)


Lesenswert?

Also wenn es unbedingt sein muß, kannst Du auch float nehmen.

Allerdings bringt das keinerlei Vorteile in jeder Hinsicht.

Und so, wie Du es beschrieben hast, entprellst Du auch nicht richtig.
Du müßtest noch hinter Deinen Tiefpaß einen Schmitt-Trigger setzen, z.B. 
mit den Schwellen 0,25 und 0,75 sonst ist in der Nähe von 0,5 trotzdem 
ein Prellen möglich.

Einen Schmitt Trigger ohne Hysterese gibt es nicht, die Hysterese ist ja 
gerade der Sinn eines Schmitt Triggers. Sie soll nämlich das Schwingen 
in der Nähe des Schwellwertes verhindern.


Die üblichen Entprellbeispiele arbeiten aber viel viel einfacher:

Sie zählen nur, wie oft hintereinander Nullen bzw. Einsen auftreten, und 
wenn der Zähler z.B. bei 4 anlangt, d.h. 4 Einsen hintereinander gelesen 
wurden, dann wird dieser Eins-Zustand übernommen und man zählt dann 
wieder 4 aufeinaderfolgende Nullen usw.


Das Codebeispiel von mir macht das z.B. gleichzeitig für bis zu 8 Tasten 
und merkt sich auch den Übergang einer Taste von
Losgelassen zu gedrückt.



Peter

von Rolf F. (Gast)


Lesenswert?

Ok, dein Algorithmus verwendet aber auch einen gleitenden Mittelwert 
(mit einer Theta-Funktion).
Bei meinem hat der Schmitt-Trigger eine infenitesimale Hysterese, damit 
es keinen verbotenen Bereich gibt (den es in der boolschen Algebra nicht 
gibt), aber das kann man natürlich ausbauen und z. B. mit einer 
dreiwertigen Logik rechnen oder auch eine Hysterese einbauen.

Jedenfalls kann man bei meinem Algorithmus über die Zeitkonstante des 
exponentiell gleitenden Mittelwert ganz gut zwischen häufigen 
Tastendrücken und Prellern unterscheiden, wenn die deutlich 
unterchiedliche Zeitdauern haben.
Mit einer Zeitkonstante von rund 100 ms sollte es sehr gut 
funktionieren.

von Matthias (Gast)


Lesenswert?

Hi

du kannst Tasten auch mit Differenzialgleichungen entprellen. Ist nur 
die Frage ob das sinnvoll ist. Float-Berechnungen (Addition und 
Multiplikation) kosten beim AVRGCC etwa 3,2k Code. für einen Mega8 ist 
das ne Menge.
Ich verwende pro Taste im Allgemeinen 4 Bit.
2 Bit zur Entprellung im Timer-INT

2 Bit zur Zustandsanzeige
0: Taste nicht gedrückt aber abgefragt (vom Hauptprogramm)
1: Taste gedrückt aber noch nicht abgefragt
2: Taste gedrückt und abgefragt
3: Taste nicht gedrückt aber noch nicht abgefragt

Macht pro zwei Tasten 1 Byte. Bei 16-Tasten sind das 8 Byte. Bei deiner 
Methode brauchst du pro Taste ein float (4 Byte) sprich 64 Byte für 16 
Tasten.

Matthias

von Rolf F. (Gast)


Lesenswert?

Also da ist einiges übertrieben. Float hat nur 32 Bit und nicht 64.
Und zum Entprellen reicht das ganze mit 16-Bit-Integer und wem das noch 
zu viel ist, der kann 8-Bit-Integer nehmen.
Bei einem MC mit Hardware-Multiplikator macht die eine Multiplkation u. 
Addition pro Taster nicht viel aus.

Hm, vielleicht sollte ich das Verfahren patentieren lassen ...

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Bitte nenne einen einzigen Vorteil den das Verfahren in der Praxis hat.

von Matthias (Gast)


Lesenswert?

Hi

Selbst-Zitat:
pro Taste ein float (4 Byte)

Zitat Rolf F.
Float hat nur 32 Bit und nicht 64.

Und wieviel Bit hat nochmal ein Byte?

Matthias

von Rolf F. (Gast)


Lesenswert?

Ein Byte hat 8 Bit und weil pro Taster im worst case nur ein Float 
benötigt wird braucht man nur 32 Bit pro Taster (im best case sind es 
nur 8); ganz einfach.

von Matthias (Gast)


Lesenswert?

Hi

was genau 64 Byte für 16 Taster bedeutet. Und nichts anderes habe ich 
heute morgen um 9.18 geschrieben.

Matthias

von Rolf F. (Gast)


Lesenswert?

Ok. Aber bei 60 kB Flash u. 2 kB RAM macht das nicht viel aus.

von Peter D. (peda)


Lesenswert?

"vielleicht sollte ich das Verfahren patentieren lassen"

Etwas patentieren, was keinerlei Vorteile hat klingt ziemlich unsinnig. 
Aber keiner hindert Dich daran.


Ich denke auch, daß 4 Bit je Taste zum Entprellen und Flanke erkennen 
vollkommen ausreichend sind.

Zumal mein Code außerdem noch extrem fix ist (10 Zyklen, das C-Beispiel 
braucht ein kleines bischen mehr).

Bei mehr als 8 Tasten nehme ich einen anderen Code, da man diese dann 
doch besser als Matrix verschaltet.

Hatte ihn schon mal in 8052.com gepostet (für 3*8=24 Tasten).


Peter

von Rolf F. (Gast)


Lesenswert?

Tja, das war eigentlich sarkastisch gemein, das mit dem Patent (obwohl 
ich das in USA problemlos patentiert bekäme).

Und wo findet man denn die Code-Beispiele mit den paar Bits?

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.