Forum: Mikrocontroller und Digitale Elektronik Atxmega128A4U: Keine Interrupts im Bootloader


von Arnd (Gast)


Lesenswert?

Hallo,

meine Interrupts im Bootloader funktionieren nicht! Kann mir da jemand 
weiterhelfen? Danke!

ich verbiege mit folgendem Code die Interrupt Tabelle:
1
CCP = CCP_IOREG_gc;                                      // Enable high, medium and low level interrupts,Interruptsprungtabelle verbiegens
2
  PMIC.CTRL = PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm;
3
    sei();

Der Linker hat die Option "-Wl,--section-start=.text=0x10000". Im .lss 
File sehe ich auch, dass der Code in der Bootloadersection geschrieben 
wird:

00010000 <__vectors>:
   10000:  0c 94 01 81   jmp  0x10202  ; 0x10202 <__ctors_end>
   10004:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10008:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   1000c:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10010:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10014:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10018:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   1001c:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10020:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10024:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10028:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   1002c:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10030:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10034:  0c 94 29 81   jmp  0x10252  ; 0x10252 <__bad_interrupt>
   10038:  0c 94 bb 85   jmp  0x10b76  ; 0x10b76 <__vector_14>

Die main.cpp
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "c_avr_iopin.h"
4
#include "c_avr_uart.h"
5
#include "c_dispatcher.h"
6
#include "c_avr_timer.h"
7
8
c_avr_uart g_uart_SoM(c_avr_uart::E0, 115200);
9
c_dispatcher g_dispatcher(&g_uart_SoM);
10
11
ISR(TCC0_OVF_vect) {                                      //Timerclock; Bei jedem Überlauf des Hardwaretimers wird in der c_timer Klasse die statische Timerclock um 1 erhöht
12
  /*
13
    Bei 2MHZ und einem Teiler von 1 entspräche "1" in der Timerclock
14
    1000*2^16/(2000000) = 32.7675 mS
15
  */
16
  c_avr_timer::ulClock++;                                    //Timerclock + 1
17
}
18
19
int main(void)
20
{
21
  BYTE * resp;
22
  
23
  ///////////////////////////////////////////////////////////////////////////////
24
  // INIT
25
  ///////////////////////////////////////////////////////////////////////////////
26
  cli();                                            //Interrupts gesperrt
27
  
28
  TCC0_CTRLA  = TC_CLKSEL_DIV1_gc;                              //Hardware Timer starten
29
  TCC0_INTCTRLA = 0x03;                                    //Interrupt definieren
30
  c_avr_timer::fResolution = 32.7675;
31
      
32
  CCP = CCP_IOREG_gc;                                      // Enable high, medium and low level interrupts,Interruptsprungtabelle verbiegens
33
  PMIC.CTRL = PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm;
34
    sei();
35
  
36
  /////////////////////////////////////////////////////////////////////////////
37
  // Main
38
  /////////////////////////////////////////////////////////////////////////////
39
  c_avr_timer timeout;
40
  timeout.StartMs(250);
41
  
42
  c_avr_iopin led(&PORTD, PIN7_bm, true, false, false);
43
  c_avr_iopin led2(&PORTD, PIN6_bm, true, false, false);
44
  c_avr_timer t;
45
  while(1){
46
    if(t.ready()){
47
      led.toggle();
48
      t.StartS(1);
49
    }
50
    led2.toggle();
51
  }
52
  
53
  cli();                                            //Programm starten, nach Update oder Timeout
54
  CCP = CCP_IOREG_gc;
55
  PMIC.CTRL = 0;
56
  asm("jmp 0");                                          
57
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Optimierung abgeschaltet?  Dann wird das Timing für das CCP-Register
nicht passen.

Mit Optimierung müsste es passen, aber es gibt natürlich keine
Garantie.

Alternativ:
1
#include <avr/xmega.h>
2
3
...
4
   _PROTECTED_WRITE(PMIC.CTRL, PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm);

: Bearbeitet durch Moderator
von Arnd (Gast)


Lesenswert?

Optimierung ist auf Standard. Mit PROTECTED_WRITE scheint es auch nicht 
zu gehen. So wie ich meiner Main jedoch entnehmen kann, sollte mein 
Timer laufen und bei jedem Überlauf einen Ausgang schalten.

Meine Timer und IO Klassen sind eigentlich hinlänglich getestet in 
anderen Projekten. Aber in der ISR vom Timer passiert leider nichts. 
Nichtmal PORTD.OUTTGL = PIN5_bm;

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Moment mal, sind die 0x10000 da Byte- oder Wortadressen?

Da danach jeweils 4 Opcode-Bytes kommen, gehe ich von Byteadressen
aus.  Dann steht die Tabelle aber auf 64 KiB, nicht auf 128 KiB.

Edit: ja klar, das muss „-Wl,--section-start=.text=0x20000“ heißen.

Die GNU-Tools zählen unabhängig von der Wortbreite des Prozessors
immer in Byte-Adressen.

: Bearbeitet durch Moderator
von Arnd (Gast)


Lesenswert?

PS: Nur led2.toggle(); wird natürlich ausgeführt. Timer t steht still, 
weil die Clock der Klass vom Interrupt nicht angetrieben wird.

von Arnd (Gast)


Lesenswert?

Jörg W. schrieb:
> Moment mal, sind die 0x10000 da Byte- oder Wortadressen?
>
> Da danach jeweils 4 Opcode-Bytes kommen, gehe ich von Byteadressen
> aus.  Dann steht die Tabelle aber auf 64 KiB, nicht auf 128 KiB.

Dane super... mit 0x20000 läuft es jetzt :)

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.