Forum: Compiler & IDEs LPC2148 ARM7 Interruptroutine beendet nicht richtig


von Geri (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

Ich verwende WINARM für LPC2148-Code.

Das Programm läuft, bis die Variable Flag != 0 wird und TestProc 
aufgerufen wird. Anschliessend wird
bei ISR_EXIT die Routine, welche auf PAbt_Addr liegt angesprungen 
(UNDEF_Routine())
1
void TestProc(void)
2
{
3
   //....
4
}
5
6
static void timer0ISR(void) __attribute__((naked));
7
8
static void timer0ISR(void) 
9
{
10
   ISR_ENTRY(); 
11
  
12
  if (Flag != 0) TestProc();
13
14
  VICVectAddr = 0;
15
   ISR_EXIT(); 
16
}
17
18
19
// in Startup.c
20
void UNDEF_Routine (void) {
21
  while (1) ;  
22
}
23
24
25
26
//crt.s
27
....
28
_vectors:       ldr     PC, Reset_Addr         
29
                ldr     PC, Undef_Addr
30
                ldr     PC, SWI_Addr
31
                ldr     PC, PAbt_Addr
32
                ldr     PC, DAbt_Addr
33
                nop              /* Reserved Vector (holds Philips ISP checksum) */
34
                ldr     PC, [PC,#-0xFF0]  /* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin  */
35
...



Hab ihr vielleicht eine Idee wo das Problem liegen könnte?

Interessanterweise läuft auch Timer 1 und ruft eine Prozedure auf. Dort 
gibt es kein Problem.

Vielen Dank

Geri

von (prx) A. K. (prx)


Lesenswert?

Interessant wären noch:
- ISR_ENTRY, ISR_EXIT
- der erzeugte Code von timer0ISR

Ist TestProc so leer wie hier dargestellt?

von Stefan ++ (Gast)


Lesenswert?

Geri schrieb:
> static void timer0ISR(void) __attribute__((naked));

warum "naked" und nicht

_attribute_ ((interrupt("IRQ")));

bei "naked" sollte man innerhalb der Routine nur asm-Befehle verwenden, 
sonst nichts

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Stefan ++ schrieb:
> Geri schrieb:
>> static void timer0ISR(void) __attribute__((naked));
>
> warum "naked" und nicht
>
> _attribute_ ((interrupt("IRQ")));
>
> bei "naked" sollte man innerhalb der Routine nur asm-Befehle verwenden,
> sonst nichts

Sehr viele mit WinARM gelieferte Beispiele stammen noch aus der Zeit 
kurz nach der Erfindung des Rades. Auf das IRQ-Attribut konnte man sich 
nicht verlassen, gab u.a. Probleme mit Interwork. Ob das bei neueren 
Compilerversionen repariert wurde, weiß sich nicht, benutze selbst bei 
"richtigen" Anwendungen auf für ARM7TDMI mit GNU-Tools nur noch 
Assembler-Wrapper für Exceptions.

Die Makros ISR_ENTRY und ISR_EXIT sind ein paar 
Inline-Assembler-Anweisungen, analog zu denen, die der Compiler bei 
funktionierendem IRQ-Attribut automatisch einsetzen sollte (u.a. 
Rücksprungadresse "richtig" biegen). Um zu verhindert, das der Compiler 
selbstständig Code für eine "normale" Funktion einfügt, dient das 
naked-Attribut.

Zur Frage des OP und nur "Glaskugel": IRQ-Stack-Size im Startup-Code 
erhöhen.

von Geri (Gast)


Lesenswert?

Hallo zusammen


Danke für eure schnelle Rückmeldung! ISR-ENTRY und ISR_EXIT sehen 
folgendermassen aus:
1
#define ISR_ENTRY() asm volatile(" sub   lr, lr,#4\n" \
2
                                 " stmfd sp!,{r0-r12,lr}\n" \
3
                                 " mrs   r1, spsr\n" \
4
                                 " stmfd sp!,{r1}")
5
6
7
#define ISR_EXIT()  asm volatile(" ldmfd sp!,{r1}\n" \
8
                                 " msr   spsr_c,r1\n" \
9
                                 " ldmfd sp!,{r0-r12,pc}^")

@A. K.
Ich meine das Problem nun gefunden zu haben. Es lag nicht an der ISR 
sondern daran, dass ich zu viel RAM-Speicher bei einer Felddefinition 
verwendet habe. Der Compiler hat mir beim Compilieren aber nichts 
mitgeteilt. Der Fehler trat beim Debuggen dummerweise immer gerade in 
der ISR auf, weil diese mit sehr hoher Priorität läuft und genau dort 
auf die s.w. ungültige Speicherzelle zugegriffen wird. Hoffe, zumindest, 
dass es dar war.

Habe mir auf eure Anregung dein Startup-File aus einem anderen Thread 
geladen:) Verstehen tue ich die Grundidee, bin aber kein ASM-Crack.
Darf man dein File für Projekte nutzen und falls ja, muss man bitte noch 
bestimmte Compiler-Direktive setzen und / oder benötigt man noch eine 
startup.c, damit man es sinnvoll nutzen kann? CODE_IN_RAM kann ich noch 
gut nachvollziehen.


@Steffan: Es ist wie Martin Thomas schreibt. Habe den Code als Referenz 
verwendet und bisher hat er immer einwandfrei funktioniert.

@Martin Thomas & A.K
Habe mir von A.K. aus einem anderen Thread das Startup-File geladen.
Sieht


Kann man sich auf Attribute inzwischen verlassen.


Beste Grüsse und vielen Dank für Eure rasche Hilfe!


Geri

von (prx) A. K. (prx)


Lesenswert?

Geri schrieb:

> Darf man dein File für Projekte nutzen und falls ja, muss man bitte noch
> bestimmte Compiler-Direktive setzen und / oder benötigt man noch

Ein Link wäre hilfreich ...

von Geri (Gast)


Lesenswert?


von (prx) A. K. (prx)


Angehängte Dateien:

Lesenswert?

Kannst du verwenden. Separater C-Code für den Startup ist nicht 
vorgesehen. Es wird aber keine Initialisierung der Taktversorgung 
durchgeführt, auch wenn ein Kommentar darin dies suggeriert. Dies, wie 
auch die Intialisierung vom MEMMAP, muss im Rahmen der üblichen 
Intialisierung am Anfang von main() geschehen.

Voraussetzung sind ein paar vom Linker-Script definierte Symbole. Siehe 
Anhänge. Da gehören ein *.ld für den Controllertyp und entweder ROM.ld 
oder RAM.ld jeweils zusammen.

Verwendet wurde das von mir für LPC2106/LPC2119/LPC2129.

Wer hierüber stolpert und Codesourcery verwendet, der müsste in den 
Linker-Scripten vielleicht irgendwelche Sections anpassen. Das Zeug ist 
schon einige Jahre alt und stammt aus der WINARM Ära.

von (prx) A. K. (prx)


Lesenswert?

Geri schrieb:

> Kann man sich auf Attribute inzwischen verlassen.

Da WINARM ja vor einigen Jahren eingestellt wurde wird sich darin 
seither kaum etwas verändert haben.

In Verbindung mit diesem Startup sind die Attribute unnötig, d.h. die 
ISRs sind normale unattributierte C Funktionen, ähnlich wie bei den 
Cortex-Mx. Interrupt-Nesting ist zulässig.

von Geri (Gast)


Lesenswert?

@A.K. Vielen Dank für dein Zuvorkommen!

Und gerade noch ein Frage zum ganz o.g. Problem:

Kann es sein, dass der Compiler bei dieser ISR ein Problem mit der 
lokalen Variable "Code" hat? Wenn ich sie "static" definiere, dann habe 
ich das ganz oben beschriebene Problem nicht. Ohne "static" nach dem 
Rücksprung aus der ISR kommt es zu einem Abbruch.

1
static void timer0ISR(void) __attribute__((naked));
2
static void timer0ISR(void) 
3
{
4
  uint8_t Code;           // P-Adr-Abort
5
  // static uint8_t Code;  // so geht's
6
7
  ISR_ENTRY();
8
  
9
  if ( APPparams.CmdBuffer.Count > 0)  // Befehl vorhanden ?
10
  {
11
      // hole Kommando und verabeitet es
12
      Code  = APPparams.CmdBuffer.CurrentCmd.Code; // <---- hier passiert was
13
            // zumindest wird kein Wert nach Code geschrieben
14
            // im Debugger sieht man, dass die Variable nicht richtig beschrieben wird, die Quelle aber den richtigen Wert enthält
15
    // snip...
16
  }
17
  T0IR  = 0x01; 
18
  VICVectAddr = 0;
19
  ISR_EXIT();
20
}


Bin ich, wenn ich WINARM verwende bei den Saurier und macht es eurer 
Ansicht nach Sinn mal umzusteigen:)? Fall ja, auf was bitte?
gcc finde ich im Prinzip für meine Bedürfnisse schon brauchbar.

von (prx) A. K. (prx)


Lesenswert?

Geri schrieb:

> Bin ich, wenn ich WINARM verwende bei den Saurier und macht es eurer
> Ansicht nach Sinn mal umzusteigen:)? Fall ja, auf was bitte?
> gcc finde ich im Prinzip für meine Bedürfnisse schon brauchbar.

GCC Varianten gibts reichlich, als freie Version beispielsweise Yagarto. 
Kostenfrei kommerziell mitsamt IDE von Atollic, wenn man kein C++ 
braucht. Als reine Kommandozeilenversion gibts CodeSourcery Lite. Zu 
überschaubaren Kosten für nichtkommerzielle Projekte gibts Rowley 
Crossworks.

von (prx) A. K. (prx)


Lesenswert?

Geri schrieb:

>             // zumindest wird kein Wert nach Code geschrieben
>             // im Debugger sieht man, dass die Variable nicht richtig
> beschrieben wird, die Quelle aber den richtigen Wert enthält

Debugging von optimiert übersetztem Code ist für manche Überraschung 
gut. Auch dies könnte so ein Effekt sein.

von Geri (Gast)


Lesenswert?

@A.K.: Vielen Dank


Meine Compilerparameter sehen folgendermassen aus:
-c -mcpu=arm7tdmi -gdwarf-2 -MD -Wall -O0 -mapcs-frame -mthumb-interwork 
-I.\examples -I..\RT_Sched -I..\Controller -I..\Misc -IC:\Program

> Debugging von optimiert übersetztem Code ist für manche Überraschung
> gut. Auch dies könnte so ein Effekt sein.
Dann kann ich Optimierung mal gleich vergessen - oder?


>GCC Varianten gibts reichlich, als freie Version beispielsweise Yagarto.
>Kostenfrei kommerziell mitsamt IDE von Atollic, wenn man kein C++
>braucht. Als reine Kommandozeilenversion gibts CodeSourcery Lite. Zu
>überschaubaren Kosten für nichtkommerzielle Projekte gibts Rowley
>Crossworks.
Danke, dann bin ich wenigstens halbwegs auf dem gleichen Stand. -Ausser 
Atollic kannte ich nicht. Wäre ja schon sehr lehrreich, wenn man sieht, 
was der Analyzer angeblich so alles kann. Wenn der Compiler am Ende dann 
aber lustige Sachen macht, dann nutzt es einem das beste Tool nichts:)

Yagarto habe ich auch installiert. WINARM eben bis jetzt immer gut 
funktioniert. Beim Wechsel tappt man dann immer wieder in neue Sachen 
rein:) und "alter" Code lasst sich nicht mehr ohne Handanlegen 
compilieren.

von (prx) A. K. (prx)


Lesenswert?

Geri schrieb:

> Dann kann ich Optimierung mal gleich vergessen - oder?

Beim Debugging fährt man ohne besser.

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.