Forum: Mikrocontroller und Digitale Elektronik Extrem großer Stack - 110 Bytes reichen nicht


von Jemand mit Stackoverflow (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe versucht, ein Programm in BASCOM zu schreiben, das ein 
bestimmtes "Farb-Programm" auf einer RG-LED anzeigt. Die LED hängt an 
PB3 und PB4 an einem ATTiny25. Funktioniert auch gut mit 
Rot-Gelb-Grün-Gelb-Rot...-Wechseln. Jetzt wollte ich eine Farbfolge aus 
Data-Zeilen laden und anzeigen. In den Data-Zeilen werden immer einzelne 
Farben angegeben, zwischen denen dann langsam übergeblendet wird. Es 
sollte auch funktionieren, ich habe alles nochmal auf Programmierfehler 
geprüft, doch leider läuft der Stack (laut Simulator) über... M*st. 
Selbst 110 Bytes reichen nicht! Mehr als 110 Bytes hab ich aber nicht... 
Ich nutze die kompletten 128 Bytes vom ATTiny25 aus. Eigentlich war das 
Programm sogar für einen ATTiny13 gedacht.

Kann mir jemand helfen, wie ich den Stack "entlasten" kann?
Der Code ist im Anhang.

Gruß,
Jemand mit Stackoverflow

von Philipp (Gast)


Lesenswert?

assembler lernen

von Jemand mit Stackoverflow (Gast)


Lesenswert?

Hallo,

Assembler hatte ich mir auch schon mal vorgenommen, bin aber sowas wie 
BASCOM bereits seit 5 Jahren von der Windows-Programmierung gewöhnt... 
Ich hatte ASM auch schon ein Bisschen gelernt, habe dann aber schnell 
die Lust verloren, weil die Programme dann so lang werden (das kann aber 
auch daran liegen, dass ich es noch nicht so lang benutzt habe). Ich 
werde mich in asm wahrscheinlich auch noch einarbeiten, aber nicht 
jetzt, weil ich erstmal lernen will, mit BASCOM "smart" zu 
programmieren.

Gruß,
Jemand mit Stackoverflow

von holger (Gast)


Lesenswert?

>assembler lernen

Ha, ha.

Pack deine Tabelle doch ins EEPROM oder ins Flash.
Wie das bei Bascom geht weiss ich allerdings nicht.

von Jemand mit Stackoverflow (Gast)


Lesenswert?

Die Tabelle ist schon im Flash (Data-Zeilen). Es kann aber sein, dass 
Read viel Stack braucht... Ich probiere es jetzt mal mit dem EEPROM. 
Vielleicht braucht das weniger Stack zum lesen. Der Stack läuft nämlich 
immer dann über, wenn er einen neuen Wert aus dem Flash holt.
Danke für den Tipp mit dem EEPROM!

Gruß,
Jemand mit Stackoverflow

von Tom (Gast)


Lesenswert?

Ursachen suchen, nicht Symptome bekämpfen!

von Jemand mit Stackoverflow (Gast)


Lesenswert?

Nein, mit dem EEPROM braucht es leider noch mehr Stack zum auslesen... 
Schade.

Gruß,
Jemand mit Stackoverflow

von BASCOM-User (Gast)


Lesenswert?

Hallo,

ein Problem bei BASCOM ist es, dass beim Verwenden einer Interrupt- 
Routine fast alle internen Register auf den Stack gesichert werden; das 
belegt schon mal ca. 30 Byte. Es gibt zwar die Option "Nosave", aber 
dann muss man selbst die verwendeten Register sichern (was bei Basic in 
der ISR nicht einfach ist).
Ich bevorzuge es, bei BASCOM in der ISR nach Möglichkeit Inline- 
Assembler zu verwenden. Dann weiss ich, welche Register ich sichern und 
wiederherstellen muss, und wenn grössere Berechnungen anstehen, wird in 
der ISR (meist von einem Timer) ein Flag (Bit, Byte) gesetzt, das dann 
in der Hauptroutine ausgewertet wird. So bleibt die ISR schön schlank 
...

Ein Vorteil ist, dass man bei BASCOM auf dimensionierte Byte-Variablen 
im (BASCOM-) Assembler zugreifen lann; so wird das Setzen von Bits in 
Variablen oder das Übergeben von Variablen aus der ISR vereinfacht.

Gruss

P.S.: Multiplikationen und vor allem Divisionen haben in einer ISR 
nichts verloren; sie brauchen auch einiges vom Stack. Sowas gehört in 
die Haupt-Routine; dort werden sie mittels Flag aus der Timer-ISR dann 
aufgerufen.
Und Divisionen durch 256 ersetzt man durch Shift-Operation (Shift ... , 
Right, 8); das geht viel schneller und braucht kaum Ressourcen.

von Peter D. (peda)


Lesenswert?

Die PWM sieht sehr umständlich aus.
Warum willst Du sie unbedingt zu Fuß machen, nimm doch einfach 2 der 
HW-PWMs.
Und dann nimm den anderen Timer für das Tempo und mache alles in der 
Main-Loop ohne Interrupts.
Deine SW-PWM dürfte auch heftig flackern bei jedem Interrupt.

Warum dem Bascom die 128 Byte SRAM nicht reichen, verstehe ich auch 
nicht.


Peter

von Jemand mit Stackoverflow (Gast)


Lesenswert?

@Bascom-User:

Ja, das mit den 32 Bytes weiß ich... Aber es sind nur 32 Bytes der mehr 
als 110 Bytes, die da den Stack platzen lassen, deshalb lasse ich es 
jetzt erstmal so, die ISR geht ja, bis dann die neue Farbe gelesen wird. 
Die Divisionen hatte ich wohl durch das ganze Umprogrammieren wieder 
rein getan und dann vergessen... Das werde ich jetzt noch ändern.

Gruß und danke für die Tipps,
Jemand mir Stackoverflow

von Jemand mit Stackoverflow (Gast)


Lesenswert?

@Bascom-User:

Danke für den Tipp mit den Flags! Es geht jetzt! Das mit dem Auslagern 
in die Main-Loop hat geklappt! ISR + Farbe lesen war dann wohl zu viel 
für den Stack. Vielen Dank!


@Peter Dannegger:

Wie könnte ich die PWM besser machen? Ich hab ja schließlich 3 Zustände 
der LED: Rot, Grün, Aus. Wie mache ich das am Besten mit einer Hard-PWM? 
Ich möchte nämlich auch die Helligkeit steuern können.


Gruß und tausend mal Danke,
Jemand mit (ehemaligem :D) Stackoverflow

von Karl H. (kbuchegg)


Lesenswert?

Jemand mit Stackoverflow schrieb:

> Wie könnte ich die PWM besser machen?

Indem du sie von der Hardware erledigen lässt. Dafür hat dir Atmel extra 
beim Timer PWM-Modi eingebaut.

> Ich hab ja schließlich 3 Zustände
> der LED: Rot, Grün, Aus.

Hast du nicht.
Du hast konzeptionell 2 LED an 2 Pins. Mit der Hardware PWM bist du 
allerdings in der Pin-Wahl nicht mehr frei sondern musst dich nach dem 
richten, was dir Atmel vorschreibt.
Dort hast du also 2 LED und für jede LED kannst du mittels Hardware PWM 
die Helligkeit von komplett aus bis 100% ein in vielen Abstufungen 
einstellen.

> Wie mache ich das am Besten mit einer Hard-PWM?

Indem du die BASCOM Hilfe zum Thema Timer (bei den CONFIG Sachen 
studierst)

von mue-c (Gast)


Lesenswert?

Warum hast du ausgerechnet den SwStack auf 110 gesetzt und die anderen 
auf 0?
Im SoftwareStack werden die Adressen der Parameter von Funktionen oder 
Subroutinen gehalten. Hast du beides nicht.
Im Frame werden die Werte der übergebenen Parameter abgelegt. Außerdem 
nutzt Bascom 24Byte für Typ Konvertierungen von Zahlen in Strings.
Da du weder Parameter noch Strings in deinem Programm hast, brauchst du 
auch keinen Frame.
Dein Problem ist die 0 bei HwStack. Dort werden die Register und die 
Rücksprungadresse aus der Interruptroutine gespeichert.

Ergo so:
$HwStack = 32 'reicht
$SwStack = 0
$FrameSize = 0 ' 24 zur Sicherheit, falls du mal ein LCD oder einen 
Print Befehl benutzen willst.

von Jemand mit Stackoverflow (Gast)


Lesenswert?

Hallo,

ich hatte viel zu tun, deshalb kann ich mich erst jetzt melden.

@mue-c:

Oh, das habe ich noch gar nicht gewusst, dass das mit dem sw- und dem 
hw-Stack so ist. Vielen Dank, dass du mir das gesagt hast! Jetzt geht's 
auch mit nur 32 Byte Stack. Dann kann ich es ja auch wie geplant auf 
einen Tiny13 machen! Danke!


Gruß

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.