Servus allerseits
Seit gestern fische ich im Trüben und komme nicht vom Fleck.
D.h., das "wo" konnte ich ermitteln, aber ich weiss nicht das "wieso"
und befürchte, dass da prizipiell was in der Schieflage ist.
- STM32F407
- Em::Blocks mit arm-none-eabi v4.7.3
- ChibiOS v2.6.5
- St-Link V2 (aber dasselbe mit J-Link)
- Prg-Size z.Zt. 120kB
Ich arbeite z.Zt. an einem Program für ein STM32F407-Board und setze zum
ersten mal ChibiOS ein.
Dabei waehle ich SRAM als Target, wobei ich so alle paar Tage das Ganze
mit Flash-Debug und Flash-Release teste.
Gestern habe ich das Programm um eine zusaetliche Funktion erweitert.
SRAM-Debug : keine Probleme sowohl in Single-Step als auch in Run-Mode
Flash-Debug: in Single-Step keine Probleme, aber in Run-Mode haengt sich
das Program auf, sobald ich diese Funktion aufrufe
Release : das Program haengt sich auf
Nach unzaehligen Try-and-Error Versuchen stellte ich fest, dass die
Lib-Funktion memset die Ursache ist. Und tatsaechlich: wenn ich diese
ausklammere, dann funktioniert das Ganze so wie gehabt. Kann ja wohl
nicht sein, wo doch memset in anderen Funktionen ohne Probleme zum
Einsatz kommt! Also habe ich memset zu Testzwecken gleich als 1.
Anweisung im main() gesetzt. Also noch bevor ChibiOs und die Hardware
initialisiert werden.
Und wieder: im Sgl-Step keine Probleme, aber sobald ich Run drücke,
haengt sich das Program auf.
Neugierig geworden habe ich mit menset etwas herumgespielt. Heraus kam:
1
//========================
2
// main
3
//========================
4
intmain(void)
5
{
6
staticuint8_ttest_buf[64];
7
8
// memset(test_buf, 0x00, 1); // okay
9
// memset(test_buf, 0x00, 2); // okay
10
// memset(test_buf, 0x00, 3); // okay
11
// memset(test_buf, 0x00, 4); // okay
12
// memset(test_buf, 0x00, 5); // okay
13
// memset(test_buf, 0x00, 16); // okay
14
// memset(test_buf, 0x00, 24); // okay
15
memset(test_buf,0x00,25);// okay
16
// memset(test_buf, 0x00, 26); // Crash
17
// memset(test_buf, 0x00, 27); // Crash
18
// memset(test_buf, 0x00, 28); // Crash
19
// memset(test_buf, 0x00, 29); // Crash
20
// memset(test_buf, 0x00, 31); // Crash
21
// memset(test_buf, 0x00, 32); // Crash
22
// memset(test_buf, 0x00, 62); // Crash
23
// memset(test_buf, 0x00, 63); // Crash
24
// memset(test_buf, 0x00, 64); // Crash
25
26
:
27
hierkommendieverschiedenenInits
28
:
29
}
Haengt sich auf heisst: hin und wieder lande ich im
"_unhandled_exception" interrupt. Aber meist ist halt nur Funkstille.
Wenn ich Glück habe, kann ich von der IDE aus reseten, sonst halt
Debug-Session beenden und neu starten.
Help! \o/
Hm...
Ich habe zwar keine Lösung, würde aber variieren, um den Fehler
einzugrenzen:
1. Das Feld mal nicht static machen und in der Größe ändern
2. eine eigene memset()-Version (geht ja schnell) probieren, wenn es
damit klappt hat das memset() einen Schuß weg?
Diese Punkte hatte ich schon alle durchgekaut, aber vergass, sie zu
erwaehnen. Sorry
- static, nicht static, global: keine Aenderung des Verhaltens.
- Beim Einsatz eines eigenen memset kommt es zu keinem Haenger
1
for(unsignedi=0;i<64;i++)
2
test_buf[i]=0x00;// Okay
Mit der Grösse hatte ich noch nicht herumexperimentiert. Hat aber keine
Wirkung zur Folge gehabt.
test_buf auf 128 vergrössert und versucht, mit memset(test_buf, 0x00,
64) zu initialisieren: Haenger!
Also dass memset einen Fehler haben sollte ... na, ich weiss nicht :)
Kompiliere das Programm mal als Release und starte das im Debugger. Die
Kombination ist oben nicht erwähnt?
Falls das nichts bringt (kein Crash), dann:
Mehmet Kendi schrieb:> Haengt sich auf heisst: hin und wieder lande ich im> "_unhandled_exception" interrupt.
So einen Interrupt gibt es nicht. Es gibt nur eine Funktion in deinem
Code diesen Namens, die als Handler für alle Interrupts eingetragen ist,
für die sonst keiner im Code angegeben ist. Gebe in dieser Funktion mal
über UART oder so den Stack, die Register IPSR, CFSR, MMFSR, BFSR, UFSR
aus.
Wäre es ein simpler bug in memset() müsste der auch mit Debugger
auftreten.
Release hatte ich immer separat geflasht.
Hab's nun aber mit dem Debugger gemacht, aber auch hier hat es sich
aufgehaengt.
Werde versuchen an die Registerinhalte heranzukommen.
Mehmet Kendi schrieb:> Hab's nun aber mit dem Debugger gemacht, aber auch hier hat es sich> aufgehaengt.
Das ist doch super, da kannst du mit dem Debugger ja genau gucken was
verkehrt ist.
Ein normales 'memset()' löst doch keinen Interrupt aus. :-/ Nichtmal
einen falschen...
Ich würde wo anders suchen:
- Stacküberlauf
- anderer Speicherzugriffsfehler
Dr. Sommer schrieb:> Das ist doch super
Irgendwas scheine ich verpasst zu haben: im Release-Mode habe ich doch
gar keinen Zugriff auf den Debugger.
Ich habe nun im Flash-Debug Mode die gewünschten Infos herausgefischt:
1
staticvolatileuint32_tx_cfsr;
2
staticvolatileuint32_tx_ipsr;
3
4
//====================================
5
// __get_IPSR siehe core_cmFunc.h in CMSIS
6
//====================================
7
static__inlineuint32_t__get_IPSR(void)
8
{
9
staticvolatileuint32_t__regIPSR__asm("ipsr");
10
return(__regIPSR);
11
}
12
13
//====================================
14
// _unhandled_exception
15
//====================================
16
void_unhandled_exception(void)
17
{
18
x_cfsr=(*((volatileuint32_t*)(0xE000ED28)));
19
x_ipsr=__get_IPSR();
20
21
}
x_ipsr: 0x00
0xE000ED28 0x00010000
MMFSR: 0x00
BFSR : 0x00
UFSR : 0x0001 -> UNDEFINSTR the processor has attempted to execute an
undefined instruction
Ralf G. schrieb:> - Stacküberlauf
Der Meinung war ich anfaenglich auch. Und habe alle möglichen Werte
erhöht und erhöht. Denn dies ja bei RTOS der Lieblingsfehler. Hat nichts
gebracht.
Aber ohne memset funktioniert ein ziemlich komplexes Program ohne
irgendwelche Zicken.
Werde diesbezüglich nochmals über die Bücher gehen.
Mehmet Kendi schrieb:> Irgendwas scheine ich verpasst zu haben: im Release-Mode habe ich doch> gar keinen Zugriff auf den Debugger.
Wieso das denn nicht? Nur weil der Compiler mit Optimierungen
kompiliert heißt das doch nicht dass der Debugger nicht funktioniert?!
Mehmet Kendi schrieb:> UFSR : 0x0001 -> UNDEFINSTR the processor has attempted to execute an> undefined instruction
Sehr verdächtig. Klingt als wäre die memset() Funktion verkehrt
kompiliert worden, sodass da ungeeignete Instruktionen drin sind. Schaue
mal ins Disassembly des Programmimages und in die Disassembly der
Funktion wenn sie im Speicher des Prozessors ist. Verwende den Stack um
herauszufinden, an welcher Stelle genau die Exception aufgerufen wird.
Versuche mal einen anderen Compiler, zB den neuesten gcc-arm-embedded (
https://launchpad.net/gcc-arm-embedded ), bei dem ist die memset
Funktion vielleicht korrekt kompiliert.
Dr. Sommer schrieb:> Wieso das denn nicht? Nur weil der Compiler mit Optimierungen> kompiliert heißt das doch nicht dass der Debugger nicht funktioniert?!
Genau dafür habe ich mein Target Flash-Debug :)
Dass es am memset liegen könnte, ziehe also echt nicht in Betracht.
Waere es dem so, müsste dieser Fehler nicht auch im Target SRAM
auftreten?
Und im SRAM laeuft die Kiste absolut stabil.
Werde aber trozdem mal mein Glück mit dem neueren gcc-arm-embedded
versuchen.
Danke für all die Antworten. Hat zwar nichts gebracht, aber man fühlt
sich nicht ganz allein gelassen auf weiter Flur :)
Mehmet Kendi schrieb:> Danke für all die Antworten. Hat zwar nichts gebracht, aber man fühlt> sich nicht ganz allein gelassen auf weiter Flur :)
Wir sind Alle bei Dir :-)
Probiere auch mal, die Flash wait-states auf maximalen Wert zu setzen.
Die Pferde vor der Apotheke können ein Lied davon singen!
Mehmet Kendi schrieb:> Genau dafür habe ich mein Target Flash-Debug :)
Ja hoffentlich ist dann auch mit Release Einstellungen kompiliert, also
mit Optimierungen. Bringt ja nichts wenn du nur ohne Optimierungen
debuggst, aber mit Optimierungen der Fehler auftritt.
Mehmet Kendi schrieb:> Dass es am memset liegen könnte, ziehe also echt nicht in Betracht.
Nicht unbedingt an memset() selbst. Möglicherweise aber daran, wie dein
memset (libc) kompiliert wurde!
m.n. schrieb:> Probiere auch mal, die Flash wait-states auf maximalen Wert zu setzen.> Die Pferde vor der Apotheke können ein Lied davon singen!
DAS ist eine sehr gute Idee...
Dr. Sommer schrieb:>> Probiere auch mal, die Flash wait-states auf maximalen Wert zu setzen.>> Die Pferde vor der Apotheke können ein Lied davon singen!> DAS ist eine sehr gute Idee...
Wie ginge das? Würde mich auch interessieren!
m.n.!!! Ich weiss zwar nicht wie schwer Du bist, und besonders kraeftig
bin ich auch nicht; aber zumindest auf virtueller Ebene hast Du es
verdient auf die Schulter genommen und 'ne Ehrenrunde gedreht zu
bekommen.
Herzlichen Dank!
War auf auf 5 Waitstates. Habe es auf 6 erhöht ... und alles laeuft wie
es soll.
So im nachhinein, eigentlich ganz logisch. Im SRAM, mit schnellem
Zugriff, laeuft es ohne Probleme. Und im Flash, wo man natürlich ganz
schnell vergisst, dass es sowas wie Waitstates gibt, knallt man an die
Mauer und weiss nicht warum.
Okay, das reicht. Runder von meinen Schultern! :)
Mehmet Kendi schrieb:> So im nachhinein, eigentlich ganz logisch.
Es ist leider überhaupt nicht logisch, dass der STM32 seine
Spezifikationen nicht einhält! Für mich war es eine sehr mühevolle
Erfahrung, unergründliche Fehler zu beseitigen, die spontan an
unmöglichen Stellen auftraten.
Daher freut es mich sehr, dass ich Dir helfen konnte.
Zur Ehrenrettung von ST sollte ich vielleicht erwaehnen, dass ich mit
einer A-Serie MCU arbeite und nicht Z-Serie.
Ist mir aber auch erst jetzt aufgefallen.
m.n. schrieb:> Es ist leider überhaupt nicht logisch, dass der STM32 seine> Spezifikationen nicht einhält!
Welche genau ist denn hier verletzt? zB bei 2.3V und 154MHz werden 7
Waitstates benötigt laut Spezifikation. Und da wir nicht wissen welche
Frequenz & Spannung der OP verwendet...
Dr. Sommer schrieb:> Und da wir nicht wissen welche Frequenz & Spannung der OP verwendet...
168Mhz @ 3.3V
Aber wie gesagt: mein MCU ist einer von der A-Serie und das Problem war
nebst den Waitstaites, dass bei dieser Serie der Data- und Instruction
Cache nicht aktiviert werden darf.