Weisst einer was es fuer einen Grund geben kann damit der CH32 einen HardFaul IRQ wirft? Und falls es mehrere Gruende gibt, kann man die im Handler unterscheiden? Leider ist das Datenblatt an der Stelle sehr duenn. Vanye
Vanye R. schrieb: > Und falls es mehrere Gruende gibt, kann man die im Handler > unterscheiden? Ein Core Dump könnte dir einen Hinweis auf den Ort liefern. Meine Erfahrung/Wissen um den CH32V003 ist nahe Null. Aber einer der häufigsten Fehler sind Null Pointer. Oder eben Pointer welche in den Irrsinn zeigen.
Vanye R. schrieb: > Leider ist das Datenblatt an der Stelle sehr duenn. Verwöhnt von der VMS-Doku oder wie? Nicht ganz so dick, aber auch nicht sehr duenn: https://www.wch-ic.com/downloads/QingKeV2_Processor_Manual_PDF.html Edit: via https://www.mikrocontroller.net/articles/CH32V003
:
Bearbeitet durch User
> Ein Core Dump könnte dir einen Hinweis auf den Ort liefern. Du meinst der liegt irgendwo im 2k Ram? :-D > https://www.wch-ic.com/downloads/QingKeV2_Processor_Manual_PDF.html Okay, ich hatte nur das Referenzmanual und das Datesheet gelesen, dann hole ich das hier mal nach.... Vanye
Vanye R. schrieb: > Du meinst der liegt irgendwo im 2k Ram? :-D Ich dachte eher an den Stack.... Dein HardFault Handler sollte den Stackinhalt ausgeben können/sollen. Und schon solltest du einen Hinweis(Adresse) haben, wo dein HardFault geworfen wird.
:
Bearbeitet durch User
> Ich dachte eher an den Stack.... Ja, daran koennte man auch nochmal denken! Aber ich hab erstmal das Dokument von oben ueberflogen und lass mir mal das mcause Register ausgeben. Auch schon interessant weil ich das wohl mit einer LED rausmorsen muss und dabei hoffe das mein Programm nicht in einen funktionierenden Zustand kommt... Vanye
So, ich hab mir mal schnell was zusammengehackt um einen 32bit uint in 1200B seriell auszugeben. Hier der Source:
1 | #define BITTIME 740 /* fuer 1200Baud */ |
2 | #define BIT_DELAY myI=BITTIME; while(myI-- > 0)
|
3 | #define START_DELAY myI=790; while(myI-- > 0)
|
4 | #define BIT_LOW GPIOA->BSHR = (1<<16) | (1<<(16+2))
|
5 | #define BIT_HIGH GPIOA->BSHR = (1<<2)
|
6 | |
7 | void HardFault_Handler(void) |
8 | {
|
9 | |
10 | //Port PA2 als Ausgang für LED initialisieren
|
11 | RCC->APB2PCENR |= RCC_APB2Periph_GPIOA; |
12 | GPIOA->CFGLR &= ~(0xf<<(4*2)); |
13 | GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*2); |
14 | |
15 | loop:
|
16 | mymcause = __get_MCAUSE(); |
17 | // mymcause = 0x80808086; /* Gegencheck */
|
18 | //mymcause = 0x12345678; /* Testwert */
|
19 | // mymcause = 0x55555555; /* Baudratetest */
|
20 | |
21 | //Stattbit
|
22 | BIT_LOW; START_DELAY; |
23 | for (myCNT=0; myCNT<8; myCNT++) |
24 | {
|
25 | if (mymcause & 0x00000001UL) BIT_HIGH; else BIT_LOW; |
26 | mymcause = mymcause>>1; |
27 | BIT_DELAY; |
28 | };
|
29 | BIT_HIGH; BIT_DELAY; BIT_DELAY; BIT_DELAY; //Stopbit |
30 | |
31 | //Startbit
|
32 | BIT_LOW; START_DELAY; |
33 | for (myCNT=0; myCNT<8; myCNT++) |
34 | {
|
35 | if (mymcause & 0x00000001UL) BIT_HIGH; else BIT_LOW; |
36 | mymcause = mymcause>>1; |
37 | BIT_DELAY; |
38 | };
|
39 | BIT_HIGH; BIT_DELAY; BIT_DELAY; BIT_DELAY; |
40 | |
41 | //Startbit
|
42 | BIT_LOW; START_DELAY; |
43 | for (myCNT=0; myCNT<8; myCNT++) |
44 | {
|
45 | if (mymcause & 0x00000001UL) BIT_HIGH; else BIT_LOW; |
46 | mymcause = mymcause>>1; |
47 | BIT_DELAY; |
48 | };
|
49 | BIT_HIGH; BIT_DELAY; BIT_DELAY; BIT_DELAY; //Stopbit |
50 | |
51 | //Startbit
|
52 | BIT_LOW; |
53 | START_DELAY; |
54 | for (myCNT=0; myCNT<8; myCNT++) |
55 | {
|
56 | if (mymcause & 0x00000001UL) BIT_HIGH; else BIT_LOW; |
57 | mymcause = mymcause>>1; |
58 | BIT_DELAY; |
59 | };
|
60 | BIT_HIGH; BIT_DELAY; BIT_DELAY; BIT_DELAY; //Stopbit |
61 | |
62 | myI=100000; while(myI-- > 0); //Bessere Lesbarkeit am Oszi |
63 | |
64 | goto loop; |
65 | }
|
Die verwendeten Variablen sind alle global deklariert. Ich wollte nicht mit dem Stack rummachen soweit es sich vermeiden laesst. Ihr seht ich sende erst zwei Testwerte, also 0x12345678 und 0x55555555 die werden dann auch vom Oszi korrekt erkannt. Dann lese ich mcause aus und das Register ist 0x80808086 Zur Sicherheit habe ich diesen Wert auch nochmal bewusst ausgegeben und bekommen dann dasselbe Ergebnis. Laut der oben angefuehrten Doku sollte dann mcause[30:0] = 0x808086 sein. Wenn ich die Doku richtig verstehe dann sollte es so einen Wert aber garnicht geben. Da sollte sich doch alles im Bereich 0 bis 255 abspielen. Vanye
Wenn Bit 31 wie hier gesetzt ist, dann ist das doch ein Interrupt, keine Exception... Prüfe auch mal den erzeugten Binärcode, vielleicht wird das falsche CSR gelesen.
> Wenn Bit 31 wie hier gesetzt ist, dann ist das doch ein Interrupt, keine > Exception... Ja, darueber habe ich mich auch schon gewundert. Aber ich schalte doch keinen ein ausser Systick und dafuer gibt es einen Handler. > Prüfe auch mal den erzeugten Binärcode, vielleicht wird das falsche CSR > gelesen. Der Gedanke hat mich auch schon beschlichen. Muss ich noch machen. Ich dachte gestern aber noch was anderes. Wo ich doch schon mal einen Source habe der im HardFault eine Zahl ausgeben kann, dann koennte ich doch auch eine globale Variable ausgeben welche beim starten auf 1 initialisiert wird und die an verschiedenen Stellen erhoeht wird. So muesste man ja sehen wie weit das Programm kommt. Ergebnis war das ein Zufallswert ausgegeben wurde, also schon die Initialisierung im Startcode laeuft nicht. Ausserdem habe ich mein Programm mehrmals uebersetzt und getestet waehrend ich die Zuweisungen in das Programm eingefuegt habe. Es wurde also immer mal etwas laenger. Ergebnis war dann das ich manchmal ein lauffaehiges Programm hatte und dann wieder nicht. Ich wuerde also vermuten das es da irgendeinen Align fehler gibt falls Teil des Programms auf einer falschen Adresse liegt. Vanye
Problem ist gefunden. Loesung am ende von hier: Beitrag "CH32V003 gcc und Codegenerierung" Hatte mich da irgendwie gerade im Thread vertan. (Aerger) Beim finden des Problems war es SEHR hilfreich obigen HardFault Haendler zu haben der einem eine Variable ausgeben kann! Werde ich mir fuer die Zukunft gleich mal vormerken! Vanye
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.