Forum: Mikrocontroller und Digitale Elektronik Wo wird die ISR beim Cortex M3 implementiert


von SAM3x Timer Interrupt erzeugen (Gast)


Lesenswert?

Hallo!
Ich programmiere gerade an einem SAM3X8E (Arduino DUE, IDE Atmel Studio 
6) und möchte gern einen Timer Counter (TC0) zyklisch laufen lassen. 
Beim Ablauf des Timers soll ein Interrupt erzeugt werden, das eine ISR 
aufruft. Ziel ist es eine mit dem Matlabcoder erzeugte Funktion in genau 
bestimmten Intervallen aufzurufen. Ich bin soweit recht gut 
fortgeschritten und habe mit dem "wunderschönen" ASF den Timer 
initialisiert und das Interrupt beim Compare Event des Zählers mit RC 
aktiviert.

Laut diesem Link 
http://asf.atmel.com/docs/latest/sam3x/html/group__interrupt__group.html#ga931b667f6490ad3d8905fa25bebb24b1
werden in interrupt_sam_nvic.h folgende Funktionen eingeführt

1
#define irq_initialize_vectors   ( ) \
2
    do{}                            \
3
    while(0)
4
5
#define irq_register_handler(int_num, int_prio) \
6
    NVIC_ClearPendingIRQ( (IRQn_Type)int_num); \
7
    NVIC_SetPriority( (IRQn_Type)int_num, int_prio); \
8
    NVIC_EnableIRQ( (IRQn_Type)int_num); \
9
10
#define ISR(func) void func (void)

leider ist es mit meinen c Kenntnissen nicht weit her. Ich würde einfach 
folgendes in meine main schreiben:
1
 
2
irq_initialize_vectors   (); //diese Funktion scheint keinen Zweck zu erfüllen!?
3
irq_register_handler(TC0_IRQn,0); // TC0_IRQn ist nur der Bezeichner für TC0
4
5
ISR(Timer_ISR){ //Funktionsanweisung}; //Was muss ich hier statt Timer_ISR einsetzen?

Mir erscheint das alles aber noch nicht so schlüssig. Der Name meiner 
ISR ist ja noch nirgends mit meinem Interrupt verknüpft oder? Kann mich 
hier vielleicht jemand auf die richtige Spur(oder das richtige 
Datenblatt) bringen?

Danke schonmal!

von (prx) A. K. (prx)


Lesenswert?

Die Namen der ISRs sind von der Entwicklungsumgebung bzw. dem 
Startup-Code festgelegt. Man definiert einfach eine Funktion mit dem 
richtigen Namen. Spezielle Attribute benötigt diese Funktion nicht, 
anders als beim AVR, nur der Name muss exakt stimmen.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

SAM3x Timer Interrupt erzeugen schrieb:
> Mir erscheint das alles aber noch nicht so schlüssig.

Mir auch nicht.

Normalerweise gibt es im Startupcode eine Tafel mit den Adressen von 
Dummy-Funktionen für alle Interrupts, die aber mit "weak" gekennzeichnet 
sind.

Wenn der Linker nun eine richtige ISR mit gleichem Namen findet, dann 
überschreibt er damit die entsprechende Dummy-Adresse und deine ISR ist 
damit richtig plaziert.

Deine Quelltext-Auszüge sehen nicht aus, als ob sie was Sinnvolles 
machen. Ich geb dir mal ein Beispiel aus einem LPC1751:

__irq void UART0_IRQHandler (void)
{ long L;
  L = LPC_UART0->IIR & 1;                     /* 1 = kein Int gewesen */
  if (L) LPC_UART0->IER  = 2;                 /* war Soft-Int, also THRE 
enable */
  if (LPC_UART0->LSR & (1<<5))                /* wenn THRE = 1 */
  { if (v24sin0==v24sout0)  return;           /* raus wenn Puffer leer 
*/
    LPC_UART0->THR = V24puffer0[v24sout0];    /* Zeichen senden      */
    v24sout0 = (v24sout0+1) & (v24bufsize-1); /* Index weiterstellen */
  }
}

So ungefähr sollte ein Interrupt-Handler aussehen - vom konkreten Inhalt 
der Routine mal abgesehen. Wie gesagt, der Name MUSS gleich dem Dummy im 
Startup sein.

W.S.

von Dr. Sommer (Gast)


Lesenswert?

> Normalerweise gibt es im Startupcode eine Tafel mit den Adressen von
> Dummy-Funktionen für alle Interrupts, die aber mit "weak" gekennzeichnet
> sind.
Streng genommen hat das mit dem Startupcode gar nichts zu tun, aus 
irgendwelchen Gründen sind diese Dinge aber bei den Beispielcodes immer 
in der Datei namens "startup" mit drin.
> Wenn der Linker nun eine richtige ISR mit gleichem Namen findet, dann
> überschreibt er damit die entsprechende Dummy-Adresse und deine ISR ist
> damit richtig plaziert.
Die ISR kann gar nicht falsch plaziert sein, es muss eben nur die 
Adresse der ISR an die richtige Stelle im Interrupt-Vektor 
kopieren/überschreiben.
> Deine Quelltext-Auszüge sehen nicht aus, als ob sie was Sinnvolles
> machen.
Eben nur den Interrupt im NVIC initialisieren.
> Ich geb dir mal ein Beispiel aus einem LPC1751:
> So ungefähr sollte ein Interrupt-Handler aussehen - vom konkreten Inhalt
> der Routine mal abgesehen. Wie gesagt, der Name MUSS gleich dem Dummy im
> Startup sein.
Ja, nur das __irq wird beim GCC (den er vermutlich über das Atmel Studio 
verwendet) nicht gebraucht.

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.