Forum: Mikrocontroller und Digitale Elektronik AT91SAM7S256: Verständnisfragen.


von Dirk H. (xplod)


Lesenswert?

Hallo zusammen.

Ich bin gerade dabei, ein wenig mit einem AT91SAM7S256 zu "spielen", und 
habe soweit mein erstes "Minimalprojekt" am laufen (Die Grundlage, auf 
der alle anderen später aufbauen sollen).

Allmählich begreife ich auch die Struktur des Programmaufbaus, 
allerdings hätte ich da noch einige Fragen zu der Umsetzung:

1.) Bei vielen Beispielanwendungen ist als erste zu linkende Datei immer 
eine "CRT.S" Datei enthalten. Soweit ich es verstanden habe dient diese 
Datei dazu, direkt auf Position 0x0000000 die System Interrupts per 
Sprungkommando einzubinden ( bedeutet "_vec_reset:   b  _init_reset" 
Sprung nach Funktion _init_reset? Oder ist das ein "b" ein define? Ich 
habe "b" nirgends als assemlberbefehl finden können)

2.) Könnte man die Datei crt.s auch als normales C-File anlegen? 
Prinzipiell müsste ich ihm ja nur sagen, dass auf Adresse 0x0000 direkt 
eine Sprungoperation auf eine Funktion reset_event_handler ausgeführt 
werden soll. Aber wie macht man sowas in C? Wenn ich in dieser Datei 
einfach nur
1
void reset_event_handler(void)
2
{
3
  init_frequency();
4
  ....
5
  main();
6
}
schreibe, dann kommt der Debugger durcheinander. Ist ja auch 
verständlich, da alle anderen System Interrupts des Vectors mit teilen 
dieser Funktion belegt sind.

3. Bin ich auf dem Holzweg, wenn ich eine Datei MIN_CRT.s schreibe, die 
nichts anderes enthält als:
1
.global _vec_reset            
2
.global _vec_undef            
3
<...>
4
.text
5
.arm
6
.align
7
<...>
8
_vec_reset:   b   reset_event_handler
9
_vec_undef:   b   undefined_event_handler
10
<...>
dass ich von dort aus direkt die C-Funktionen anspringen könnte? Wenn 
ich "_vec_reset:   b   main" schreiben würde, wäre dann alles so, wie 
man es bei einem Standard C-Projekt erwarten würde, nämlich dass der 
Prozessor im Defaultzustand in die void main(void) Funktion springt? 
Oder sollte man sowas unterlassen?

von Dirk H. (xplod)


Lesenswert?

Ich habe noch was vergessen:

4. Ich habe ein Problem mit dem PIO-Interrupt:
1
void pin_interrupt_enable(int pin_mask)
2
{
3
  volatile AT91PS_PIO PIO_p = AT91C_BASE_PIOA;
4
  PIO_p->PIO_PER  |= pin_mask; // enable PIO for pin
5
  PIO_p->PIO_IFER |= pin_mask; // enable glitch filter
6
  PIO_p->PIO_IER  |= pin_mask; // enable interrupt for pin
7
  PIO_p->PIO_ASR  |= pin_mask; // use PIO-A funtions
8
  
9
}// end of void pin_interrupt_enable(int pin, int iecr)
10
11
void set_interrupt_handler(int iecr, int fcn)
12
{
13
  volatile AT91PS_AIC AIC_p = AT91C_BASE_AIC;
14
15
  AIC_p->AIC_SMR[iecr]  = AT91C_AIC_PRIOR_HIGHEST;
16
  AIC_p->AIC_SMR[iecr] |= AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE;
17
  AIC_p->AIC_SVR[iecr]  = fcn;
18
  AIC_p->AIC_IECR   |= ( 1 << iecr); // enable PID2 interrupt
19
  AIC_p->AIC_ISCR   |= ( 1 << iecr); // set PID2 interrupt (???)
20
} // end of void set_interrupt_handler(int iecr, ISRFcnPtr fcn)
21
22
void dummy_interrupt_handler(void)
23
{
24
  <...> // mache irgendwas + breakpoint
25
}
26
int main()
27
{
28
  const int button1 = (1 << 19);//PA19 = bt1
29
  const int LED1 = ( 1 << 18 );
30
  
31
  pin_interrupt_enable(button1);
32
  set_interrupt_handler(AT91C_ID_PIOA, (int)dummy_interrupt_handler); // AT91C_ID_PIOA = 2
33
  
34
<...> 
35
36
  while ( 1 )
37
  {
38
    idle_task(LED1);
39
  }
40
  
41
  return 1;
42
  
43
}
Leider funktioniert dies nicht. Die Funktion dummy_interrupt_handler 
wird nie angesprungen. Im AIC-Register steht auch nie ein "Operation 
pending, o.ä. Bei den AVRs gibt's einen globalen Interrupt_enable, 
leider habe ich den nicht gefunden. Weder in der Doku noch in den 
Beispielapplikationen. Bin ich blind, oder gibt's den nicht und ich habe 
einen anderen Fehler eingenaut?

Wofür benütige ich das   "PIO_p->PIO_ASR  |= pin_mask; // use PIO-A 
funtions"? Es war in den Beispielen enthalten, aber ich habe nicht 
gefunden, wofür das gut ist. Die Beschreibung in der Atmel Doku ist da 
scheinbar etwas dürftig...

von Proc P. (proc)


Lesenswert?

Hallo Dirk, habe das gleiche Problem:
Beitrag "Externer Interrupt auf AT91SAM7X-EK mit Eclipse"
Hast Du Deines schon gelöst?

von Dirk H. (xplod)


Lesenswert?

Nein, leider nicht.

Würde mich interessieren, ob hier überhaupt jemand Eclipse und einen 
AT91SAM miteinander einsetzt...

von Proc P. (proc)


Lesenswert?

Hallo Dirk,
weiß inzwischen woran es liegt (an ethernut; brauche ich leider wegen 
tcpip) kann es aber auch nicht reparieren.

Ohne ethernut läuft bei mir folgendes Testprogramm:
1
void ex_int_handler (void) 
2
{ 
3
  volatile unsigned int ulDummy;    
4
  AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; 
5
  AT91C_BASE_AIC->AIC_ICCR = 0x04000000; 
6
  AT91C_BASE_PIOB->PIO_CODR=AT91C_PIO_PB19;  // LED1 im Interrupt zum Test anmachen
7
  asm("mrs r7,CPSR"); 
8
  asm("bic r7,r7,#0x80");
9
  asm("msr CPSR,r7"); 
10
  AT91C_BASE_AIC->AIC_IECR = 0x04000000; 
11
  AT91C_BASE_AIC->AIC_IVR = 0x0;
12
  AT91C_BASE_AIC->AIC_EOICR = 0x0;
13
  ulDummy = AT91C_BASE_PITC->PITC_PIVR;
14
  AT91C_BASE_AIC->AIC_EOICR = ulDummy;
15
16
}
und in
1
main(){
2
 ...
3
  AT91C_BASE_PIOA->PIO_PER=INTTAST;    
4
  AT91C_BASE_PIOA->PIO_ODR =INTTAST; 
5
  AT91C_BASE_PIOA->PIO_CODR=INTTAST; 
6
  AT91C_BASE_PIOA->PIO_PPUER=INTTAST; 
7
  AT91C_BASE_PIOA->PIO_ASR=INTTAST; 
8
  AT91C_BASE_PIOA->PIO_OWDR=INTTAST; 
9
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA]=AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 0; 
10
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA]=(unsigned int)ex_int_handler; 
11
  AT91C_BASE_PIOA->PIO_IFER=INTTAST; 
12
  int io_status = AT91C_BASE_PIOA->PIO_ISR; 
13
  AT91C_BASE_AIC->AIC_IECR=(1 << AT91C_ID_PIOA); 
14
  AT91C_BASE_PIOA->PIO_IER=INTTAST;   
15
 ...
16
  while(1){
17
   ... // hier LED2 blinken lassen
18
  }

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.