Forum: Mikrocontroller und Digitale Elektronik Kann ein AVR im Idle Modus durch einen Interrupt geweckt werden ohne Sprung in die Interrupttabelle?


von EinBastler (Gast)


Lesenswert?

Mein Problem ist folgendes, ich versuche eine möglichst kleine UART 
Implementation zu bauen, welche keine Einträge in der Interrrupttabelle 
braucht, mittels USI zu realisieren indem ich USI über timer0 ctc 
tackte.
Nun würde ich die Warteschleife durch ein "sleep" ersetzen wollen.
Der ATtiny soll also durch das USI Overflow Interrupt geweckt werden und 
mit der Codeausführung in der nächsten Instruktion beginnen ohne einen 
Sprung in die Interrupttabelle.
Ich habe es bisher nicht geschafft einen AVR ohne eben jenen Sprung 
aufzuwecken.
Kann mir jemand verraten ob dies möglich wäre? Danke im Vorraus!

von c-hater (Gast)


Lesenswert?

EinBastler schrieb:

> braucht, mittels USI zu realisieren indem ich USI über timer0 ctc
> tackte.

Takt schreibt sich ohne "c". Daran hat auch die 
Rechtschreibverschlimmbesserungsreform nichts geändert.

> Nun würde ich die Warteschleife durch ein "sleep" ersetzen wollen.
> Der ATtiny soll also durch das USI Overflow Interrupt geweckt werden

Das bringt so gut wie nichts. Damit der Overflow-Int eintreten kann, muß 
der Timer0 laufen. Damit geht bloß der am wenigsten stromsparende 
Energiesparmodus ("Idle-Mode") und der spart wirklich kaum was.

> Kann mir jemand verraten ob dies möglich wäre?

Ich kann dir genau dasselbe verraten, was auch im Datenblatt steht: Das 
ist nicht möglich. Grundsätzlich kann nur ein ausgelöster Interrupt 
das Teil wecken. Und da es zwischen der Auslösung des Interrupt und dem 
Ansprung des zuständigen Interruptvektors keinerlei 
Eingriffmöglichkeiten gibt, ist es unmöglich.

Die Frage ist, warum stört dich das? Schreibst du einfach ein RETI auf 
den Vektor und fertig ist der Lack. Naja, falls du unbedingt die paar 
Bytes der Vektortabelle eines Tiny für Code brauchst, mußt du halt noch 
ein RJMP PC+2 davorschreiben. Insgesamt kostet das also nur 4 Byte. Und 
wenn's daran klemmt: Es findet sich garantiert eine Stelle in deinem 
Code, wo man die einsparen kann.

von EinBastlee (Gast)


Lesenswert?

Es ging darum keine Warteschleife bauen zu müssen sondern eben nur in 
den IDLE Modus zu gehen. Außerdem läuft timer0 ja auch im IDLE Modus und 
taktet bei jedem Compare USI hoch bis jener 4bit Counter überläuft. 
Wirklich Schade wegen dem Aufwachen, in einem Bootloader gehören sich ja 
keine Interrupts.
Ich danke jedenfalls für die Antwort und entschuldige mich für komische 
Schreibfehler, aber zu meiner Verteidigung ein Handy mit zerbrochenem 
Bildschirm ist nicht Ideal zum Tippen

von Hubs (Gast)


Lesenswert?

c-hater (Gast) schrieb:

Hier die Meinung:

> Das bringt so gut wie nichts. Damit der Overflow-Int eintreten kann, muß
> der Timer0 laufen. Damit geht bloß der am wenigsten stromsparende
> Energiesparmodus ("Idle-Mode") und der spart wirklich kaum was.

Hier die Fakten:

Datenblatt ATTiny13: 3,3 V & 9,6 MHz RC-OSZ

Idle Supply Current   ca. 0,9 mA
Active Supply Current ca. 3,6 mA

von c-hater (Gast)


Lesenswert?

Hubs schrieb:

> Hier die Fakten:
>
> Datenblatt ATTiny13: 3,3 V & 9,6 MHz RC-OSZ
>
> Idle Supply Current   ca. 0,9 mA
> Active Supply Current ca. 3,6 mA

So what? Das ist nichtmal annähernd eine Größenordnung, also wirklich 
kaum was.

Du mußt das relativ zu den mit tieferen Schlafmodi möglichen 
Einsparungen von mehreren Größenordnungen sehen.

von c-hater (Gast)


Lesenswert?

EinBastlee schrieb:

> Es ging darum keine Warteschleife bauen zu müssen sondern eben nur in
> den IDLE Modus zu gehen.

Aha, jetzt habe ich das verstanden. Es ging primär garnicht darum, Strom 
zu sparen.

> Wirklich Schade wegen dem Aufwachen, in einem Bootloader gehören sich ja
> keine Interrupts.

Quatsch. Wer erzählt so einen geistigen Dünnschiß? Wer es auch ist: der 
Typ hat keine Ahnung.

von EinBastler (Gast)


Lesenswert?

Was nutzt ein tieferer Schlafmodus wenn er den Zweck verfehlt den Code 
kürzer zu machen und die Timer abschaltet was auch die Funktion des 
Programmes irgendwie vernichtet...
Außerdem Faktor 4 ist außerdem ein deutliches Ersparnis

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Für diesen Fall (Bootloader) ist das doch völlig egal ob der nun in 
einer Warteschleife "hängt" oder schläft.

von EinBastler (Gast)


Lesenswert?

Ist doch irgendwie Allgemeinwissen, dass ein guter Bootloader indem 
Programmablauf gar nicht mehr eingreifen muss, bei jedem Programmstart 
die Interrupttable neu Flaschen ist kein Weg, und ein Muxer für 
Interrupts verfälscht den Cycle Count

von EinBastler (Gast)


Lesenswert?

@Läubi
Es geht darum wie ich UART mit USI am kompaktesten Bitbange, als 
Herausforderung hab ich mir einen <64 Opcode Bootloader gesetzt

von Hubs (Gast)


Lesenswert?

c-hater schrieb:
> Hubs schrieb:
>
>> Hier die Fakten:
>>
>> Datenblatt ATTiny13: 3,3 V & 9,6 MHz RC-OSZ
>>
>> Idle Supply Current   ca. 0,9 mA
>> Active Supply Current ca. 3,6 mA
>
> So what? Das ist nichtmal annähernd eine Größenordnung, also wirklich
> kaum was.

Das ist eine erhebliche Ersparnis und jeder gute Programmierer nutzt 
diese natürlich.

> Du mußt das relativ zu den mit tieferen Schlafmodi möglichen
> Einsparungen von mehreren Größenordnungen sehen.

Ich muss gar nichts. Du musst lernen effektiv zu programmieren. Das 
Beispiel zeigt, dass z. B. eine Verlängerung der Batterie-/Akkulaufzeit 
auf das Vierfache einfach zu erreichen ist.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

EinBastler schrieb:
> Es geht darum wie ich UART mit USI am kompaktesten Bitbange

Und ein bedingter Sprung braucht jetzt dermaßen viel weniger 
Instructions als ein sleep? Kompakt hin oder her, das macht doch den 
Code völlig unverständlich und komplexer als nötig.

von EinBastler (Gast)


Lesenswert?

Läubi .. schrieb:
> EinBastler schrieb:
>> Es geht darum wie ich UART mit USI am kompaktesten Bitbange
>
> Und ein bedingter Sprung braucht jetzt dermaßen viel weniger
> Instructions als ein sleep? Kompakt hin oder her, das macht doch den
> Code völlig unverständlich und komplexer als nötig.

Naja, der Sleep Befehl mit USI würde mir eigentlich alles ersparen... 
sbic funktioniert leider nicht mehr mit Addressen ab 0x20... also 
bräuchte ich 3 Opcodes
USI erspart mir wenn alles klappt die Hälfte der Opcodes beim Senden und 
Empfangen weil ich nichtmal eine for-artige Schleife machen müsste
Eigentlich ist es einfach eine Herausforderung an mich wie klein ich 
deen Bootloader (UART mit auto baud) schaffe

von c-hater (Gast)


Lesenswert?

EinBastler schrieb:

> Es geht darum wie ich UART mit USI am kompaktesten Bitbange, als
> Herausforderung hab ich mir einen <64 Opcode Bootloader gesetzt

Nett.

Allerdings: Wenn du das gleich eingangs auch so geschrieben hättest, 
wäre die Hälfte des Threads erst garnicht geschrieben worden!

Aber nachdem nun endlich nach einem Dutzend Postings klar ist, das daß 
Ziel minimale Codegröße ist, ist auch klar, daß die Idee mit dem Idle 
Mode statt der Warteschleife schlicht Schwachsinn ist.

Die Warteschleife kostet genau zwei Opcodes, also 4 Bytes.

Der ganze Kram der nötig ist, um überhaupt in den Idle-Mode zu kommen 
und dann auch wieder daraus aufwachen zu können, kostet mindestens 12 
Byte. Und außerdem: die Hauptschleife muß ja trotzdem geschlossen 
werden! Also 14 Byte.

Selbst wenn es möglich wäre, die vier Byte in der Vektortabelle zu 
sparen
(was ja deine Frage war), steht die Rechnung also immer noch 10:4.

Damit erübrigt sich deine Frage unter dem Aspekt des nun endlich 
offengelegten Ziels von vornherein, denn die Beantwortung der Frage kann 
an der Entscheidung für die richtige Architektur nichts ändern, es 
gewinnt in jedem Fall die Warteschleife.

von Hubs (Gast)


Lesenswert?

Hier die Welt wie sie " c-hater" wahrnimmt:

> Aber nachdem nun endlich nach einem Dutzend Postings klar ist, das daß
> Ziel minimale Codegröße ist, ist auch klar, daß die Idee mit dem Idle
> Mode statt der Warteschleife schlicht Schwachsinn ist.

Hier die Realität aus dem 1. Posting:

" ... ich versuche eine möglichst kleine UART Implementation zu bauen, 
.."

von c-hater (Gast)


Lesenswert?

Hubs schrieb:

> Das
> Beispiel zeigt, dass z. B. eine Verlängerung der Batterie-/Akkulaufzeit
> auf das Vierfache einfach zu erreichen ist.

Ja. Und wie lange hält sich der gemeine µC deiner Meinung nach 
typischerweise in einer Schleife in einem Bootloader auf?

Nur damit wir mal eine Vorstellung bekommen, ob der grandiosen 
Verlängerung der Batterielaufzeit, die deine hocheffiziente 
Programmiererei bewirken wird...

von c-hater (Gast)


Lesenswert?

Hubs schrieb:

> Das
> Beispiel zeigt, dass z. B. eine Verlängerung der Batterie-/Akkulaufzeit
> auf das Vierfache einfach zu erreichen ist.

Ja. Und wie lange hält sich der gemeine µC deiner Meinung nach 
typischerweise in einer Schleife in einem Bootloader auf?

Nur damit wir mal eine Vorstellung bekommen, ob der grandiosen 
Verlängerung der Batterielaufzeit, die deine hocheffiziente 
Programmiererei bewirken wird...

von EinBastler (Gast)


Lesenswert?

Naja, die Verzögerung braucht mindestens 3 Opcodes, weil c-hater nicht 
versteht das eine sbic+rjmp PC-1 nicht geht
An c-hater:
Kapierst du nicht, ich kann nicht bei jedem Bootvorgang die 
Interrupttabelle umschreiben oder einen Muxer machen weil dies einen 
Eingriff in den Programmablauf eines jeden Programmes entspricht?
Und dank USI... welche Hauptschleife?

von Hubs (Gast)


Lesenswert?

c-hater schrieb:

> Damit geht bloß der am wenigsten stromsparende Energiesparmodus ("Idle-
> Mode") und der spart wirklich kaum was.

und das ist schlicht und ergreifend: FALSCH.

Du hast eine Wahrnehmung die nicht mit der Wirklichkeit übereinstimmt. 
Man verfolge einfach nur diesen Thread.

Du zeigst, dass du von der Materie wenig Ahnung hast. Darüber hinaus 
sind deine weiteren Einlassungen nur Ablenkungen, Ausreden und 
Relativierungen.

Du kannst es nicht, Kleiner.

von Simon K. (simon) Benutzerseite


Lesenswert?

Warum musst du eigentlich die Interrupttabelle neu flashen? Lese das 
jetzt zum zweiten mal hier.

Soweit ich weiß gibt es bei den AVRs doch ein Bit, was man setzen kann, 
dass den Offset der Interrupttabelle auf die Boot-Section stellt.

von EinBastler (Gast)


Lesenswert?

@Hubs
Ich stimme dir voll und ganz zu, danke

von Sven P. (Gast)


Lesenswert?

c-hater schrieb:
> Ich kann dir genau dasselbe verraten, was auch im Datenblatt steht: Das
> ist nicht möglich. Grundsätzlich kann nur ein ausgelöster Interrupt
> das Teil wecken. Und da es zwischen der Auslösung des Interrupt und dem
> Ansprung des zuständigen Interruptvektors keinerlei
> Eingriffmöglichkeiten gibt, ist es unmöglich.

Ist ja schlimm, wenn du so einen schlechten Tag gehabt hast. Dafür 
können wir aber allesamt nichts, also trink ein Bier und komm mal wieder 
runter.

Zwischen der Auslösung eines Interrupts und dem Sprung in die 
Serviceroutine gibt es nun sehr wohl einen Unterschied. Nämlich wenn man 
etwa das I-Bit im Statusregister löscht. Dann können Interrupts zwar 
ausgelöst werden (es werden nämlich Interruptflags gesetzt), aber die 
Serviceroutinen werden eben nicht angesprungen.

Zugegebenermaßen ist die Doku aber an dieser Stelle nicht so vielsagend. 
Ich werde es bei Gelegenheit mal testen.

von MWS (Gast)


Lesenswert?

Sven P. schrieb:
> Dann können Interrupts zwar
> ausgelöst werden (es werden nämlich Interruptflags gesetzt), aber die
> Serviceroutinen werden eben nicht angesprungen.

Das Auslösen eines Interrupts ist per Definition das Ausführen 
desselben. Interrupt bedeutet unterbrechen, also bedeutet das eine 
Unterbrechung auslösen. Und nicht nur anzeigen, dass etwas ausgelöst 
werden soll.

> Zugegebenermaßen ist die Doku aber an dieser Stelle nicht so vielsagend.
> Ich werde es bei Gelegenheit mal testen.

Die Doku dürfte eindeutig sein, da brauchst Du auch nicht viel 
auszuprobieren, ohne aktiviertem I-Flag kein Aufwachen. Da gibt's so 
Kandidaten, die in der ISR ein Sleep auslösen und sich dann wundern, 
dass trotz aktiviertem Interrupt nix mehr aufwacht...

Das Kürzeste, das geht ist ein RETI in den Interruptvektor zu schreiben.

von Sven P. (Gast)


Lesenswert?

MWS schrieb:
> Sven P. schrieb:
>> Dann können Interrupts zwar
>> ausgelöst werden (es werden nämlich Interruptflags gesetzt), aber die
>> Serviceroutinen werden eben nicht angesprungen.
>
> Das Auslösen eines Interrupts ist per Definition das Ausführen
> desselben. Interrupt bedeutet unterbrechen, also bedeutet das eine
> Unterbrechung auslösen. Und nicht nur anzeigen, dass etwas ausgelöst
> werden soll.
Je nach Definition...
Man kann ihn auch auslösen und dann bedienen. So jedenfalls in der mir 
vertrauten Terminologie. Manchmal werden Interrupts auch garnicht 
ausgelöst, sondern angefordert und dann bedient. Dann ists auch schön 
eindeutig.

Ich habe es allerdings auch gerade ausprobiert: Es ist tatsächlich das 
Anspringen der Serviceroutine entscheidend fürs Aufwachen.

von MWS (Gast)


Lesenswert?

Sven P. schrieb:
> Ich habe es allerdings auch gerade ausprobiert: Es ist tatsächlich das
> Anspringen der Serviceroutine entscheidend fürs Aufwachen.

Ja, wusste ich. Das Ausführen des Vektors ist entscheidend, im Vektor 
kann dann statt eines JMP/RJMP auf die ISR auch einfach nur ein RETI 
stehen.

von EinBastler (Gast)


Lesenswert?

Ja, das ich das Abspringen eines ISRs brauche hatte ich.... da ich kein 
reti verwenden kann muss ich wohl weil eine andere Lösung suchen

von Simon K. (simon) Benutzerseite


Lesenswert?

EinBastler schrieb:
> Ja, das ich das Abspringen eines ISRs brauche hatte ich.... da ich
> kein
> reti verwenden kann muss ich wohl weil eine andere Lösung suchen

Wieso nicht?

von EinBastler (Gast)


Lesenswert?

Weil ich einen Bootloader basteln will und dabei nicht die 
Interrupttabelle jedesmal überschreien will und auch keinen Muxer für 
Interrupts verwenden sollte

von Simon K. (simon) Benutzerseite


Lesenswert?

EinBastler schrieb:
> Weil ich einen Bootloader basteln will und dabei nicht die
> Interrupttabelle jedesmal überschreien will und auch keinen Muxer für
> Interrupts verwenden sollte

Es gibt bei den AVRs soweit ich weiß das IVSEL Bit, womit du einfach nur 
die Einsprungadressen in den Bootloader schieben kannst. Da muss nix 
überschrieben werden? Und was ein Muxer für Interrupts ist, ist die 
andere Frage.

von EinBastler (Gast)


Lesenswert?

Nicht bei den ATtinys...
Naja, es gibt einen Entry Point für Interrupts, wenn nun zwei Programme 
laufen muss ein Interrupt an die jeweilige Routine eines der beiden 
verteilt werden

von Simon K. (simon) Benutzerseite


Lesenswert?

Zumindest nicht bei den ATTinys, die keine Bootloader section haben... 
Macht ja auch Sinn. Was spricht gegen die Benutzung eines AVRs mit 
Bootloader section?

: Bearbeitet durch User
von EinBastler (Gast)


Lesenswert?

Es geht doch um das Lernen und die Herausforderung bei solchen Dingen, 
mit einen ATmega wäre das leicht, der hat dediziertes UART, eine 
Bootloadersection,... aber ein ATtiny hat nichts von dem und sowas 
trotzdem in 64 Opcodes (2 Pages) oder vielleicht per SPI in 32 Opcodes 
(1 Page) ist eine interessante Aufgabe

von Carsten R. (kaffeetante)


Lesenswert?

Hubs schrieb:
>> Damit geht bloß der am wenigsten stromsparende Energiesparmodus ("Idle-
>> Mode") und der spart wirklich kaum was.
>
> und das ist schlicht und ergreifend: FALSCH.

Man muß halt aufpassen, daß an sich nicht verrennt. Ein Wort kann schon 
viel ändern. Geht es um Stromsparen oder Laufzeitverlängerung (durch 
Stromsparen).

Hubs schrieb:
> Hier die Fakten:
>
> Datenblatt ATTiny13: 3,3 V & 9,6 MHz RC-OSZ
>
> Idle Supply Current   ca. 0,9 mA
> Active Supply Current ca. 3,6 mA

Auch wenn es nur ein Beispiel von vielen ist, es önnen noch ganz andere 
Zahlen zustande kommen, so Sieht man hier, daß der Idle 2,7 mA spart. 
Jeder tiefere Schalfmodus kann maximal nur noch weitere 0,9 mA sparen. 
Soviel zum Stromsparen an sich. Ich glaube das geht in Hubs Richtung.

Geht es um Laufzeitverlängerung (durch Stromsparen), so verdoppelt jede 
weitere Halbierung des Reststromes die Laufzeit. Das sheint bei c-hater 
der Gedanke zu sein.

Beides geht jedoch an der Frage nach Kompaktheit des TE vorbei.

Idle und die tieferen Sleep-modi sind nicht nur zum Energiesparen da. 
Sie erweitern auch das Programmierkonzept und ermöglichen bei geeigneter 
Programmierung einen anderen Programmfluß. Ich kann mit Sleep + Timer 
definiert warten und trotzdem noch andere Sachen wie ISRs abarbeiten 
wenn ich mit einem kleinen Jitter leben kann.

Mit einer Schleife kann ich Präzise warten, darf dann aber keine ISRs 
zulassen, oder ich warte und jeder Interrupt verlängert die Wartezeit.

Beides dürfte neben der Kompaktheit ebenfalls relevant sein. Es betrifft 
zwar weniger die Programmgröße an sich, aber die Funktionalität einer 
Kommunikation kann dadurch beeinträchtigt werden wenn ich dies nicht 
berücksichtige.

: Bearbeitet durch User
von Simon K. (simon) Benutzerseite


Lesenswert?

EinBastler schrieb:
> Es geht doch um das Lernen und die Herausforderung bei solchen
> Dingen,
> mit einen ATmega wäre das leicht, der hat dediziertes UART, eine
> Bootloadersection,... aber ein ATtiny hat nichts von dem und sowas
> trotzdem in 64 Opcodes (2 Pages) oder vielleicht per SPI in 32 Opcodes
> (1 Page) ist eine interessante Aufgabe

Achso, ich dachte es ging hier um was ernsthaftes und sinnvolles. Dann 
bin ich wohl raus hier ;-)

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.