Forum: Mikrocontroller und Digitale Elektronik STM32F4 Checksummenberechnung: Hard Fault


von Ff (Gast)


Lesenswert?

Hallo,
Ich versuche gerade Ulrich Radigs DMX-ARTNET-Interface 
www.ulrichradig.de/home/index.php/avr/dmx-avr-artnetnode nachzubauen. 
Ich möchte es auf einem STM32F429 zum laufen zu bringen. In der 
Berechnung der Checksumme im TCP-Stack gibt es ein Problem: Nach einigen 
Durchläufen wird in der ersten While-schleife der Funktion checksum() 
der Hard-Fault-Handler aufgerufen, ich kann mir nicht erklären wieso. 
Hat jemand eine Idee? Hat es was damit zu tun, das der Code von einem 8 
Bit-Prozessor kommt?

Hier die Funktion checksum()
1
unsigned int checksum (unsigned char *pointer, unsigned int result16, unsigned long result32)
2
{
3
  unsigned int result16_1 = 0x0000;
4
  unsigned char DataH;
5
  unsigned char DataL;
6
  
7
  //Jetzt werden alle Packete in einer While Schleife addiert
8
  while(result16 > 1)
9
  {
10
    //schreibt Inhalt Pointer nach DATAH danach inc Pointer
11
    DataH=*pointer++;
12
13
    //schreibt Inhalt Pointer nach DATAL danach inc Pointer
14
    DataL=*pointer++;
15
16
    //erzeugt Int aus Data L und Data H
17
    result16_1 = ((DataH << 8)+DataL);
18
    //Addiert packet mit vorherigen
19
    result32 = result32 + result16_1;
20
    //decrimiert Länge von TCP Headerschleife um 2
21
    result16 -=2;
22
  }
23
24
  //Ist der Wert result16 ungerade ist DataL = 0
25
  if(result16 > 0)
26
  {
27
    //schreibt Inhalt Pointer nach DATAH danach inc Pointer
28
    DataH=*pointer;
29
    //erzeugt Int aus Data L ist 0 (ist nicht in der Berechnung) und Data H
30
    result16_1 = (DataH << 8);
31
    //Addiert packet mit vorherigen
32
    result32 = result32 + result16_1;
33
  }
34
  
35
  //Komplementbildung (addiert Long INT_H Byte mit Long INT L Byte)
36
  result32 = ((result32 & 0x0000FFFF)+ ((result32 & 0xFFFF0000) >> 16));
37
  result32 = ((result32 & 0x0000FFFF)+ ((result32 & 0xFFFF0000) >> 16));  
38
  result16 =~(result32 & 0x0000FFFF);
39
  
40
  return (result16);
41
}

von Peter II (Gast)


Lesenswert?

Ff schrieb:
> Hat jemand eine Idee? Hat es was damit zu tun, das der Code von einem 8
> Bit-Prozessor kommt?

sicher das du die Funktion mit den richtigen Parametern aufrufst?

Wenn im 1. oder 2.Prameter Unsinn steht kommt es zu einer 
Zugriffsverletzung.

von rag einfügen: Rechtsklick (Gast)


Lesenswert?

CM4 liefert ziemlich extensive Informationen im Falle eines Faults 
(Fault Address, Fault Status) etc.

Wahrscheinlich läuft Dein pointer Amok.

PS: Deine Variablenbenamsung und Komentierung
sind ziemlich unsinnig.

von (prx) A. K. (prx)


Lesenswert?

rag einfügen: Rechtsklick schrieb:
> PS: Deine Variablenbenamsung und Komentierung
> sind ziemlich unsinnig.

Das ist Radig'scher Code. Bei dessen TCP/IP Code kann man glatt zum 
Moby-Apologeten werden. Will hoffen, dass es sein erstes C Programm war.

von Little B. (lil-b)


Lesenswert?

Peter II schrieb:
> sicher das du die Funktion mit den richtigen Parametern aufrufst?
>
> Wenn im 1. oder 2.Prameter Unsinn steht kommt es zu einer
> Zugriffsverletzung.

Seh ich auch so. Ein Hard Fault auf einem M4 entsteht in den meisten 
Fällen durch eine Zugriffsverletzung.

Nimm mal dieses Programm mit rein, vieleicht gibt dir das mehr 
Informationen zum Fault:
Beitrag "STM32F4 Fault Handling"

von Max (Gast)


Lesenswert?

Benutzt du ein Discovery Bord mit STLinkv2?

Falls ja, könntest du openocd als gdb server starten und dann mit dem 
arm-none-eabi-gdb dich mit dem target verbinden.

Dann kannst du einen breakpoint im Hardfault handler setzen, das target 
resetten (`monitor reset`).
Wenn du im Hardfault handler gelandet bist, kannst du mit `where` einen 
Stacktrace ausgeben lassen und mit `frame` die stack frames 
zurueckspringen.
Damit kann man eigentlich gut den Befehl finden, der den Hardfault 
handler ausgelöst hat.

Wenn du Stacktrace und den Befehl, der den Hardfault handler ausgelöst 
hat postests, dann können wir dir viel besser helfen, als wenn wir nur 
den C Code zu sehen bekommen.

von Ff (Gast)


Lesenswert?

Problem war, dass der int-Typ als 32 Bit Variable angelegt wurde. Habe 
die unsigned int und long durch uint16_t bzw. uint32_t ersetzt und es 
der Hard Fault-Interrupt ist weg.

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.