PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Cortex M3, Exceptions bestätigen ?



Siro
27.10.2011, 15:26
Hallo,
ich habe eine Frage zu den Exceptions des LPC1768. Ich möchte eventuelle Softwarefehler abfangen.
Zum Beispiel einen unerlaubten Speicherzugriff, wie es z.B durch einen falsch initialisierten Pointer passieren könnte.
Der Exeption wird auch erkannt und die Software landet in meinem Handler. Das klappt alles einwandfrei.
Leider wird der Exception anscheinend nicht richtig bestätigt und alle Niederpriorisierten Interrupts treten dann nicht mehr auf.
Irgendwie fehlt anscheinend noch eine "Bestätigung" für die CPU. Sicherlich noch irgend ein Bit setzten/löschen oder was auch immer.
Oder anders gefragt: Wo ist das Interrupt Flag, welches anscheinend noch ansteht ?

Dazu mal eben mein Codeschnipsel



/*----------------------------------------------------------------------------*/
/* Abfangen eines unerlaubten Speicherzugriff */
/* wie er zum Beispiel so entsteht: */
/* int *p=0; ein Zeiger auf 0, also in den Flash Code Bereich */
/* *p=4; hier den Fehler auslösen, unerlaubtes schreiben */

void HardFault_Handler(void)
{ int* p = (int*)0xE000ED2C; /* HFSR - Register LPC1768 */

/* lediglich zum testen ob ich das richtige Bit erwischt habe */
/* und ob das FORCED bit im HFSR gesetzt wurde */
volatile int value = *p;

/* nach der nächsten Zeile müste der Wert von value wieder 0 sein */
value &=(~(1<<30));

/* das gleich tätige ich nun im CPU register */
/* aber !! Achtung!! the bit is sticky (klebrig ????) eine 1 löscht das bit */
*p |=(1 << 30); /* Bit im CPU Register löschen */

/* mal nachgucken ob es geklappt hat */
value = *p;
/* nochmal nachgucken ob es geklappt hat, wegen eventuellen Write Buffer */
value = *p;

/* alles okay, wie ich sehen konnte */
/* aber ich bekomme keine weiteren Interrupts mehr, meine Timer usw. scheinen zu stehen */
/* das liegt natürlich daran, daß sie eine geringere Priorität haben. */
/* Es fehlt also noch irgendwo ein BIT zu löschen um den Execption zu bestätigen */
/* Ich hab den ganzen Tag gesucht, aber bisher ohne Erfolg */
/* Ich habe leider auch im "Definitive Guide of the ARM-Cortex...." BISHER */
/* nichts für mein Problem gefunden. */
/* Wie muss ich meinen Exception beenden, daß er als abgearbeitet erkannt wird */

/* nun meine Fehlerbehandlung aufrufen */
do_error(ERR_HARD_FAULT);
}
/*----------------------------------------------------------------------------*/

Für Eure Hilfe wäre ich sehr dankbar.
Bis dahin suche, lese, probiere ich schonmal weiter.
Siro

PicNick
27.10.2011, 16:12
Da muss ich mich erst reinlesen. Denke, du musst dem Arm sagen, was er nun mit dem Task tun soll.

Vielleicht stehen da weisheiten drin, ich werd' auch mal gucken.

http://www.keil.com/appnotes/files/apnt209.pdf (http://www.keil.com/appnotes/files/apnt209.pdf)

Oder es find' sich ohnehin wer, der das auswendig weiss

Siro
27.10.2011, 21:45
Hallo PicNick,
der Weg scheint schon mal richtig.
Ich werd mir das Morgen mal genauer durchlesen.
Kann meiner Meinung nur ne Kleinigkeit sein.
Ich hab ja schon viele der Interrupts am Laufen.
Uart, ADC, SPI,Timer usw. Da kriegen wir wohl den ollen Hardware Fault auch noch hin....
Danke Dir für die Info.
Siro

Siro
28.10.2011, 09:10
Guten Morgen, da bin ich wieder....
Habe mir das Datenblatt von Keil mal angesehen und auch nochmal das Datenblatt des Controllers.

Wenn ich das richtig verstanden habe, laufen die Exceptions NICHT über den NVIC.
Im Datenblatt von Keil steht aber NVIC_SetPriority(BusFault_IRQn, 0x80) merkwürdig ??
Dann laufen die Exceptions doch über den NVIC ???

Ich habe beim Debuggen gesehen, daß nach meinem Exeption das IMPRECISERR im SCB->CFSR Register gesetzt wird, also habe ich es per Software gelöscht.
Das brachte aber auch noch keinen Erfolg.

Nun lese ich gerade im Datenblatt UM10360 folgendes:
Ein Bus Fault Exeption wird ausgelöst, wenn ein Schreibzugriff auf den Flashspeicher erfolgt, dafür sorgt der Flash Accelerator.

Nanu, meine Software landet im "HardFault" und nicht im BusFault. Bei folgendem Zugriff:

int *p=0;
*p=4; /* Exception ausloesen, unerlaubter Schreibzugriff auf den Flash */

Irgendwie bin ich jetzt etwas verwirrt und weis immer noch nicht wie ich die Interrupts wieder freigeben kann, nachdem der Exception kam.

Das Datenblatt von Keil führt lediglich eine while(1) Schleife ein, wenn der Exception auftrat. Ich wollte aber nicht stehen bleiben
in meiner Software, sondern eine Fehlermeldung ausgeben. Die Software läuft ja auch weiter, aber meine Timerinterrupts stehen....

Weiter unten im Datenblatt von Keil steht dann, was die Software nach einem Execption tun kann.
System Reset
Recovery (genau das will ich, leider fehlt hier ein Beispiel)
Task termination

Ich bin also noch nicht viel weiter gekommen.
Wo sind die Spezis, die mir helfen können ?

Siro

Renegr
21.12.2011, 05:50
Hallo,
beschäftige mich erst seit Neuestem mit dem M3 und Lowlevel-Programmierung. Hast du dein Problem gelöst? Wenn nicht, schau mal folgende Info (ARM Page)
HFSR [30] FORCED
Indicates a forced hard fault, generated by escalation of a fault with configurable priority that cannot be handles, either because of priority or because it is disabled:
0 = no forced HardFault
1 = forced HardFault.

When this bit is set to 1, the HardFault handler must read the other fault status registers to find the cause of the fault.
Könnte eine DataAccessViolation im MFSR ausgelöst worden sein?

Gruß René

Siro
21.12.2011, 14:46
Hallo Rene,
ersteinmal Danke, daß Du dieses Thema nochmal aufgegriffen hast.
Leider konnte ich bis heute mein Problem nicht lösen.
Ich habe mehr durch Zufall jedoch festgestellt, daß meine Software bei einem Stackoverflow auch in meinem HardFault Handler landet.

Dann habe ich noch so einiges probiert:


/* das bit BUSFAULTPEND im SCB->SHCSR register löschen */
p = (U32*)0xE000ED24;
value = *p; /* register lesen */
value &=(~(U32)(1<<14)); /* bit loeschen */
*p = value; /* registerwert zurück schreiben */

/* das bit IMPRECISERR im SCB->CFSR register löschen */
p = (U32*)0xE000ED28;
value = *p; /* register lesen */
value &=(~(U32)(1<<14)); /* bit loeschen */
*p = value; /* registerwert zurück schreiben */

ENABLE;

__asm ("CPSIE F");


Alles ohne Erfolg. Meine Interrupts nach dem HardFault sind nach wie vor komplett gesperrt.

Eine Nachfrage direkt bei NXP blieb leider ohne Rückmeldung.
Ich werde mich auch nochmal diesem Thema widmen. Sobald ich etwas in Erfahrung bringe werde ich es posten.

Siro