Hallo,
ich arbeite mit Embitz und debugge mich grad durch meine Funkanwendung.
Soweit so gut, die Daten kommen auch rein aber seltsamerweise hängt sich
die CPU dann irgendwie auf. D.h. Breakpoints im Hauptprogramm werden
nicht mehr erkannt aber die Interrupts die LEDs blinken lasse laufen
munter weiter.
Im Debug Mode lässt sich das Problem soweit einkreisen, wie im Bild zu
sehen. D.h. dsas Funkmodul hat gültige Daten empfangen, es wurde ein INT
ausgelöst und die CPU holt sich diese rein. Tippe ich mich bis zum Ende
durch ist bei der Klammer Schluss, danach ist er "weg". Kein gelber
Balken mehr, keine Reaktion auf Breakpoints. Callstack stimmt aber
soweit.
Ich habe beim Linken übrigens LTO eigeschaltet, benutze die Nano Lib.
Kennt das jemand?
Gruss,
Christian
DraconiX schrieb:> Den Interrupt Handler hast du ordnungsgemäß zurückgesetzt?!
Den Interrupt Handler kann man nicht zurücksetzen. Allenfalls
kann und sollte man ein Interrupt Flag zurücksetzen wenn es
gesetzt wurde.
Aruinoquäler schrieb:> DraconiX schrieb:> Den Interrupt Handler hast du ordnungsgemäß zurückgesetzt?!>> Den Interrupt Handler kann man nicht zurücksetzen. Allenfalls> kann und sollte man ein Interrupt Flag zurücksetzen wenn es> gesetzt wurde.
Ja gut, dann halt im Interrupt-Handler die Interrupt-Flag zurück
gesetzt. :-D
Und ja, wenn ein Int ausgelöst wurde, wurde die Flag ja auch sicherlich
gesetzt. Gibt es denn beim STM32 ein Interrupt der ausgelöst werden
kann, welcher nicht zurück gesetzt werden muss? Ist mir bis dato noch
nicht übern Weg gelaufen, wäre aber Interessant zu wissen.
Ich kapier es nicht!
In der for Schleife landet er im HardFault Handler! Das war doch vorher
nicht....
/* Startet die RTC */
void Init_RTC()
{
volatile uint32_t i;
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP,
ENABLE);
/* LSI clock stabilization time */
for(i=0;i<5000;i++);
DraconiX schrieb:> Den Interrupt Handler hast du ordnungsgemäß zurückgesetzt?! Die> Komplette ISR zur Posten wäre eventuell Sinnvoll. ;-)
Ähm...... Den setze ich nicht zurück, der soll ja zur Laufzeit umgebogen
sein. Ich setze nur die INT Flags zurück.....
Problem ist: Das Laufzeitverhalten ist anders als wenn ich rum debugge.
Mein Master sendet 150 Datensätze, die stehen beim "Run" im Debug Mode
auch alle fein im Array of struct drin, läuft nichts über etc. Alle 3
Timer lösen ihren Int aus, der RTC Int auch, die Dimmung über die PWM
Outsputs läuft auch.... setze ich einen roten Break Punkt klebt er
sofort da dran.
aber er ist aus main while (1) {...} einfach raus. Da kommt er gar nicht
mehr hin.
Der Stop Knopf zum Pausieren geht nicht mehr, da passiert gar nichts
mehr.
Habe testweise mal die Libs verändert, nehme ich die Link Time
Optimization raus schmiert er mit hardFault ganz ab.
Hier die Int Routine:
1
/* ====================== Interrupt Handler RF Modul ============================*/
2
3
voidIRQ_ROUTINE(void)
4
{
5
6
staticuint8_ttcnt=0;
7
8
if(EXTI_GetITStatus(IRQ_LINE)!=RESET)
9
{
10
// ISR Code.....
11
if(RF_DataReady())
12
{
13
SetRedLED(ENABLE);
14
// RF_CE_Enable(ENABLE); // TEST & FIXXXME !!!!
15
16
/* In welcher Pipe sind Daten? */
17
uint8_tpipe=RF_GetFilledPipe();
18
/* Wie viele Bytes sind da ?*/
19
uint8_tnrBytes=RF_GetPayloadSize();
20
21
if((pipe==1)&&(nrBytes<=sizeof(actual_data)))
22
{
23
f_RF_Timeout=false;
24
ReceivedDataBlocks++;
25
26
/* Daten auslesen */
27
RF_ReadPayload((uint8_t*)&actual_data,nrBytes);
28
29
if(actual_data.Feuchte_Now>90)
30
actual_data.Feuchte_Now=100;
31
32
/* ----- Sind es historische Daten? ------------ */
33
// Sind es historische Daten?
34
if(actual_data.command==RX_CMD_HISTORY)
35
{
36
// Neue Daten in Historie kopieren
37
uint8_tindex=actual_data.nrDataSet;
38
if(index<=HISTORY_MAX_IDX)
39
{
40
/* Zeit gelegentlich neu setzen */
41
if(++tcnt>=60){
42
Set_NewTime(actual_data.unix);
43
tcnt=0;
44
}
45
/* Daten aus Struct einsortieren usw */
46
Manage_RF_Data(index);
47
f_GotData=true;
48
}
49
}
50
51
/* ----- Sind es Daten für das E2PROM ? --------- */
52
// ......
53
}
54
55
/* Fifo löschen, egal was noch drin war */
56
RF_FlushRX();
57
RF_ClearStatus();
58
RF_CE_Enable(ENABLE);
59
60
SetRedLED(DISABLE);
61
}
62
63
EXTI_ClearITPendingBit(IRQ_LINE);// Remove LINE interrupt flag bit
Setz halt einen Brechpunkt in den Hardfaulthandler...
Dann kannst du dich mit den Moeglichkeiten beschaeftigen,
aus dem dort vorgefundenen Zustand auf den Fehler zu
schliessen.
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5105152:
> Dann kannst du dich mit den Moeglichkeiten beschaeftigen,> aus dem dort vorgefundenen Zustand auf den Fehler zu> schliessen.
Das lasse ich dann doch lieber sein, da ich mir dabei schon mal einen
abgebrochen habe. Bisher hat eine Umschreibung mancher Probleme auf eine
andere Art geholfen. Oder halt nested Interrupts verbieten, das
eleminiert auch schon viele Fehler.
Wenn ich das unten auskommentiere ist das problem weg. Also ist da was
strubbelig und sobald ich einen kaffee fertig habe geht die Nachtschicht
weiter. Habe ja Urlaub und das Wetter ist mies :-)
1
// Neue Daten in Historie kopieren
2
uint8_tindex=actual_data.nrDataSet;
3
if(index<=HISTORY_MAX_IDX)
4
{
5
/* Zeit gelegentlich neu setzen */
6
// if (++tcnt >= 60) {
7
// Set_NewTime(actual_data.unix);
8
// tcnt = 0;
9
// }
10
/* Daten aus Struct einsortieren usw */
11
// Manage_RF_Data(index);
PS:
Da liegt der Wurm drin... aber bisher lief die beanstandungsfrei
1
/* Zeit neu einstellen, läuft allein weiter per RTC ISR */
2
voidSet_NewTime(uint32_tnewtime)
3
{
4
/* Unix Zeit für localtime casten */
5
time_tvalue=(time_t)newtime;
6
7
/* Interne RTC auf Masterstation sychronisieren */
Einen Brechpunkt im Hardfaulthandler zu setzen ist nun keine
Raketenwissenschaft.
Von TI gibt es eine recht informative Appnote wie Mann mit
den Informationen im Hardfault umgeht:
http://www.ti.com/lit/pdf/SPMA043
Da das alles ARM Systemregister sind, gilt das was dort steht
ohne Einschraenkungen auch fuer den M3 von ST (von der
Driverlib im ROM mal abgesehen...).
Aus der Appnote:
"The Stellaris Cortex-M processor provides a powerful fault
handling system and several features to help you find the
cause of a fault. After debugging a few faults, you will be
more comfortable handling and troubleshooting faults as they
happen, and will be able to find the cause in a few minutes."
Denk mal drueber nach!
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5105189:
> Einen Brechpunkt im Hardfaulthandler zu setzen ist nun keine> Raketenwissenschaft.
Ich werde es mir mal anschauen, damals habe ich aber nur Bahnhof
verstanden vor gut 1 Jahr. Dazu braucht man ja erstmal einen Einstieg
und anschliessend "den Blick für das Wesentliche" um die Urache zu
finden. Einen hardFault Handler schreiben ist easy, der Roohbau ist ja
schon fertig.
PS: Habs! Auch ohne den Hardfault:
Diese Set_NewTime Routine rief localtime auf. Allerdings hatte ich in
dieser die RTC Ints nicht abgeschaltet, so dass immer mal einer
dazwischen haute. Die Routine ist nicht reentrant. Dachte der Compiler
merkt das. Jetzt sind die aus und erstmal läuft es :-)
Zum Hardfault Handler, da setzt man einen Breakpoint, greift sich den SP
und guckt nach, was an der Adresse SP+24 steht. Das ist nämlich die
Adresse, an der die Exception ausgelöst wurde.
Dann greift man sich das Mapfile und guckt, in welcher Funktion das ist.
Oder man ist bequem und lädt die Firmware per Debugger und klickt sich
dann zu der Adresse vor, dann sieht man auch gleich die Quelltextzeile.