Hallo zusammen, mich interessiert wie man die Dauer der ISR berechnen die man Programmiert hat? Warum ? Ich habe gelesen das wenn eine ISR zu lange brauch der Interrupt wieder ausgelöst werden kann und damit Daten verloren gehen können z.B. bei ADC Messungen. Um dies zu verhindern bin ich der Meinung man sollte wissen wie die Dauer einer ISR ist. danke euch im Voraus
Tim H. schrieb: > mich interessiert wie man die Dauer der ISR berechnen die man > Programmiert hat? die ASM schritte summieren. Oder einfach im Simulator (wenn es denn einen gibt) laufen lassen und die zeit ablesen.
Tim H. schrieb: > Um dies zu verhindern bin ich der Meinung man sollte wissen wie die > Dauer einer ISR ist. a) Abschätzen b) am Anfang einen Timer auslesen, merken, am Ende nochmal auslesen und Differenz bilden. rgds
Peter II schrieb: > die ASM schritte summieren. Hallo Peter, da ich leider kein ASM programmier sondern in C ist es für mich schwer dies nachzuvollziehen. Was ich schon herausgefunden und verstanden habe ist, dass ASM Befehle x Taktzyklen brauchen um sie zu bearbeiten/auszuführen. Ich weis aber nicht wie der Compiler meinen in C geschrieben Code als asm darstellt.
Tim H. schrieb: > Ich weis aber nicht wie der Compiler meinen in C geschrieben Code als > asm darstellt. das wissen wir auch nicht, denn du sagt weder welchen Compiler noch welche IDE du verwendest. (auch wissen wir nichts über den Prozessor)
Tim H. schrieb: > Ich weis aber nicht wie der Compiler meinen in C geschrieben Code als > asm darstellt. Dann lass Dir ein Listing davon machen. Denn der Complier erzeugt erst mal Assembler Code. oder: b) am Anfang einen Timer auslesen, merken, am Ende nochmal auslesen und Differenz bilden. Das geht in C wunderbar. rgds
6A66 schrieb: > a) Abschätzen Hallo 6A66, davon bin ich kein freund was das Programmieren angeht, ich möchte ja etwas genaues haben. 6A66 schrieb: > b) am Anfang einen Timer auslesen, merken, am Ende nochmal auslesen und > Differenz bilden. Wie macht man sowas ? Wenn das Programm in die ISR springt einen Timer Starten und am ende dann auslesen? Verlängert das nicht die ISR?
Peter II schrieb: > auch wissen wir nichts über den Prozessor) µC ist MSP430 Familie (wie im Namen steht) IDE nutze ich die von TI (CSS 6)
Tim H. schrieb: > 6A66 schrieb: >> a) Abschätzen > > Hallo 6A66, > > davon bin ich kein freund was das Programmieren angeht, ich möchte ja > etwas genaues haben. Das kommt drauf an, wie 'genau' denn 'genau' sein muss. Im Regelfall geht es nicht darum, jeden einzelnen Taktzyklus zu kennen, sondern es geht um Grössenordnungen. Wenn dein Timer alle 10ms einen ISR Aufruf auslöst, dann ist dir (im Regelfall) der einzelne Taktzyklus egal. Wenn du begründet abschätzen kannst, dass deine ISR nicht länger als ca 10µs dauern wird, dann reicht das völlig aus um eine Aussage betreffend deines konkreten Problems stellen zu können. Ob das dann 10µs oder 15µs sind, spielt eine untergeordnete Rolle. Wichtig ist, dass du von den 10ms weit genug entfernt bist. > Wenn das Programm in die ISR springt einen Timer Starten und am ende > dann auslesen? > > Verlängert das nicht die ISR? Natürlich. Jede Modifikation bzw. Instrumentierung eines Programms verändert auch das Programm. Wenn du keine Programmänderung zulassen kannst, musst du entweder diese veränderung wieder herausrechnen oder mit einem externen Messinstrument ran. Das kann zb ein Simulator sein, der Takte zählt.
Karl Heinz schrieb: > Das kommt drauf an, wie 'genau' denn 'genau' sein muss. > Im Regelfall geht es nicht darum, jeden einzelnen Taktzyklus zu kennen, > sondern es geht um Grössenordnungen. Ausnahmen bestätigen natürlich die Regel. Natürlich gibt es auch Aufgabenstellungen, bei denen man um jeden Taktzyklus Bescheid wissen muss.
Tim H. schrieb: > Wenn das Programm in die ISR springt einen Timer Starten und am ende > dann auslesen? Nein, ich habe einen Systemtimer mit laufen der macht 1us Ticks. Den lese ich am Anfang der ISR (je nach Implementierung): Start=*TimerRegister; Am Ende: Differenz = Start - *TimerRegister; Klar verlängert das die ISR um genau diese beiden Befehle. Aber das macht das Kraut nicht wirklich fett. Wenn ich in der ISR ohnehin gezwungenermaßen Berechnungen machen muss (ich weiß, das sollte man tunlichst unterlassen aber es gibt auf dieser Welt Dinge da geht das architektonisch nicht anders) die länger dauern ist ir nicht die Verlängerung um die beiden Befehle das wichtigste sondern was ich durch Änderungd er Berechnung an Zeit in der ISR gewinne. Und nach der Optimierung kommentiere ich die Befehle wieder aus. rgds
Was spricht dagegen, beim Betreten der ISR einen Pin auf High zu setzen und beim verlassen wieder zu löschen? Ist zwar nicht 100% genau, aber ich denke 99,x% reichen ja auch als Überblick
Ingo Less schrieb: > Was spricht dagegen, beim Betreten der ISR einen Pin auf High zu > setzen > und beim verlassen wieder zu löschen? Ist zwar nicht 100% genau, aber > ich denke 99,x% reichen ja auch als Überblick Oder man toggelt in der Main Schleife einen Pin mit höchst möglichster Frequenz (kurzer Pulsabstand). Sobald nun ein Interrupt bearbeitet wird, verlängert sich der Abstand zwischen zwei Flanken. Dieser neue Abstand minus kurzer Abstand ist exact die Zeit des IRQ. inklusive rein- und rausspringen. mfg DerDan
DerDan schrieb: > Oder man toggelt in der Main Schleife einen Pin mit höchst möglichster > Frequenz (kurzer Pulsabstand). Hallo DerDan, dies bringt mich zu einer weitern frage. Wenn ich den MSP430 in einen LPMx Mode setzten möchte um den Stromverbrauch zu verringern (bei Batterie betrieb). wie Könnte ich dies lösen? 6A66 schrieb: > Wenn ich in der ISR ohnehin > gezwungenermaßen Berechnungen machen muss (ich weiß, das sollte man > tunlichst unterlassen aber es gibt auf dieser Welt Dinge da geht das > architektonisch nicht anders) Hallo 6A66, WO du dies schreibest mit dem im Interrupt Berechnungen machen. Wie kann man dies anders Handeln? Besser gefragt Wie handelt man dies dann? Ich kann doch nicht eigen Interrupt flag programmieren oder? ich kann mir sowas nur so vorstellen:
1 | int mein_interruptflag = 0; |
2 | void meine_Inter_funktion (void){ |
3 | //code
|
4 | mein_interruptflag = 1; |
5 | }
|
6 | while(!mein_interruptflag){} |
das ist nur pseudocode aber ich mache dort ja kein interrupt sondern ein polling. oder habe ich einen falschen Ansatz?
Tim H. schrieb: > Ich kann doch nicht eigen Interrupt flag programmieren oder? > ich kann mir sowas nur so vorstellen: > >
1 | > int mein_interruptflag = 0; |
2 | > void meine_Inter_funktion (void){ |
3 | > //code |
4 | > mein_interruptflag = 1; |
5 | > } |
6 | > while(!mein_interruptflag){} |
7 | >
|
> > das ist nur pseudocode aber ich mache dort ja kein interrupt sondern ein > polling. > > oder habe ich einen falschen Ansatz? Der Ansatz ist im Grunde schon ok. Der Interrupt dient nur dazu, das Auftreten des Ereignisses zu registrieren und zwar unabhängig davon, was der µC sonst noch so zu tun hat. Wenn die eigentliche Bearbeitung des Ereignisses etwas warten kann, dann kann man das genau so mit dem Pollen eines Flags in der Hauptschleife lösen.
Karl Heinz schrieb: > Wenn die eigentliche Bearbeitung des Ereignisses etwas warten kann, > dann kann man das genau so mit dem Pollen eines Flags in der > Hauptschleife lösen. Wie entscheide ich eigentlich ob es sinnvoll ist etwas über einen Interrupt zu lösen oder über Pollen in der Hauptschleife? so wie ich das verstanden haben sind sie dazu da um den MSP aus dem LPM mode zu holen. könntet ihr mir ein Beispiel geben mit einem Ablauf in der Hauptschleife und Interrupts? Den ich wüsste grade nicht was ich in der Hauptschleife machen sollte. Ich bin noch nicht so vertraut mit den µControllern und habe deswegen auch noch nicht so lange Programme geschrieben. Meine Programme: Blinky LED ohne Timer Blinky mit Timer und Interrupt Taster interrupt Led toggle Piezo ton mit pw. erzeugen. Piezo an aus schalten mit 2 Schalter ton verändern (2 tasten piano XD) ADC Wandlungen von Sensoren. danke im voraus
:
Bearbeitet durch User
Tim H. schrieb: > mich interessiert wie man die Dauer der ISR berechnen die man > Programmiert hat? Tim H. schrieb: > Um dies zu verhindern bin ich der Meinung man sollte wissen wie die > Dauer einer ISR ist. ich kann das auch nicht rechnen, ist mir auch zu mühsam, ich setze am Anfang der ISR einen Port und am Ende wieder zurück und schaue auf dem Oszi (oder billigster LA) die Dauer an, ggffs. im single shot um es in Ruhe lesen zu können. Ich lese im 10ms Timer IRQ auch I2C aus und mit der variablen Dauer -> clockstretching kann das gemessene 100-200µs dauern, genügend Zeit in der 10ms IRQ.
:
Bearbeitet durch User
Tim H. schrieb: > Um dies zu verhindern bin ich der Meinung man sollte wissen wie die > Dauer einer ISR ist. Beim Eintritt in die ISR einen Pin auf High, beim Austritt den Pin wieder auf Low setzen. Multimeter dran und Spannung messen. 0V: Keine bis wenig Zeit in der ISR 5V: 100% Verweildauer in der ISR. Alles dazwischen ist Dreisatz. P.S. Wenn Dein Multimeter damit nicht klarkommt, dann musst Du noch einen Tiefpass an den Pin legen.
Fabian Dichelmann schrieb im Beitrag #4100317: > Wozu denn noch ein Tiefpass? Miss doch einfach die Differenz mit einem > Oszilloskop an dem Pin. Wenn der TO ein Oszilloskop hat, ja.
Gibt es von den MSP430 Fanboys echt keine Empfehlung für einen Simulator, mit dem man die Zyklen zählen kann?
Tim H. schrieb: > int mein_interruptflag = 0; > void meine_Inter_funktion (void){ > //code > mein_interruptflag = 1; > } > while(!mein_interruptflag){} Je nach CPU-Architektur bietet sich eher sowas an (kenne den MSP nicht näher):
1 | volatile int mein_interruptflag; |
2 | void meine_Inter_funktion (void) |
3 | {
|
4 | //code
|
5 | mein_interruptflag = 1; |
6 | }
|
7 | |
8 | void main() |
9 | {
|
10 | mein_interruptflag=0; |
11 | |
12 | do
|
13 | {
|
14 | schlafe_bis_zum_naechsten_interrupt(); |
15 | |
16 | if (mein_interruptflag) |
17 | {
|
18 | tue_irgend_was -> code |
19 | mein_interruptflag=0; |
20 | }
|
21 | }
|
22 | while(true); |
23 | }
|
Irgendwer schrieb: > if (mein_interruptflag) > { > tue_irgend_was -> code > mein_interruptflag=0; > } Ich würd das Flag ganz als allererstes löschen. Je nachdem wie lange tue_irgend_was dauert könnte zwischendurch schon wieder ein weiterer Interrupt aufgetreten sein, den würde man sonst verpassen.
Tim H. schrieb: > 6A66 schrieb: >> b) am Anfang einen Timer auslesen, merken, am Ende nochmal auslesen und >> Differenz bilden. > > Wie macht man sowas ? > Wenn das Programm in die ISR springt einen Timer Starten und am ende > dann auslesen? > > Verlängert das nicht die ISR? Nicht nur das; Simulation und Timer-Auslesen liefern prinzipbedingt nur untere Gernzen für die Ausführungsdauer. Im eine solide Abschätzung der Laufzeit nach oben zu bekommen, ist nur eine statische Codeanalyse geeignet. D.h. auf den Hosenboden setzen und analysieren oder ein — i.d.R nicht ganz zu kostengünstiges — Werkzeug zur statischen Codeanalyse bemühen. Bei linearem Code ist die Abschätzung nach oben normalerweise recht einfach, wobei Code, der printf verwendet, vielleicht linear ausieht aber es im Endeffekt nicht ist :-) Auch ist nicht klar, was mit "Ausführungszeit einer ISR" genau gemeint ist, z.B. ob auch IRQ-Latenzen — d.h. die Zeit von IRQ-Ereignis bis zum Start der ISR bzw. bis zur geforderten Aktion — eine Rolle spielen oder nicht. Im allgemeinen ist die Zeit nicht direkt am erzeugten Assemblercode ablesbar, sondern auch abhängig von: IRQ-Latenz (abhängig von Hardware uns Software), Code- und Datenablage (wegen Caching-Verhalten, Speichergeschwindigkeit, Wait-States, ...), den zu berarbeitenden Daten (Hardware-Scheduling abhängig von Registerinhalten), anderen Prozessen (konkurrierende Speicherzugriffe durch andere Cores, Software-Scheduling), etc.
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.