40-HTTP_Server-Library (STM32F4)

Mit dieser Library kann man mit dem STM32F4-Discovery-Board und einem extern angeschlossenen PHY (von Texas Instruments “DP83848C”) und einer RJ45-Buchse einen HTTP-Webserver realisieren.

Die Webseite(n) müssen zuvor mit einem PC-Programm in ein C-File gewandelt werden, das dann im Sourcecode eingebunden wird. Eine Anleitung dazu findet sich im Netz.

Es können CGI-Befehle in die Webseite integriert werden um z.B. GPIOs zu schalten oder Messwerte auszulesen. (Im Beispiel können die 4 LEDs vom Board geschaltet werden und der Spannungswert an PA3 wird zyklisch angezeigt)
Diese Funktionen können auch deaktiviert werden, wenn man sie nicht braucht.

Als IP-Stack wird der OpenSource “LwIP” in der Version 1.3.2 benutzt. Und als Schnittstelle zum PHY wird der RMII-Mode benutzt (der MII-Mode funktioniert beim Discovery-Board nicht, weil die benötigten Pins nicht vorhanden sind)

Falls DHCP aktiviert ist, holt sich das Modul die IP-Adresse vom Router, falls nicht kann eine statische IP im H-File eingetragen werden.

BUG HINWEIS : im File “stm32f4x7_eth_bsp.c” wird bei der Initialisierungs-Funktion “ETH_MACDMA_Config” ein Software-Reset ausgelöst und mit einer While-Schleife gewartet bis der Reset fertig ist. Bei meinen Tests hat diese Funktion nicht immer sauber funktioniert (k.A. warum) und blieb in einer Endlosschleife hängen. Ich habe dann als Workaround einen Timeout-Counter hinzugefügt.
(laut suche im Internet ist dieser Fehler bei mir kein Einzelfall)
Abhilfe beim auftreten des Fehlers waren bei mir :
1. nochmal am Board einen Reset per Push-Button auslösen.
2. Die Ethernet-Clock-Enable Zeile NACH dem Reset machen (und nicht davor).
3. Den GPIO PA8 als MCO zu initialisieren (obwohl der gar nicht benutzt wird)

Beispielbilder :

Benutzte Pins :

1
2
3
4
5
6
7
PA1  = RMII_Ref_Clk       PC1 = ETH_MDC
PA2  = ETH_MDIO           PC4 = RMII_RXD0
PA7  = RMII_CRS_DV        PC5 = RMII_RXD1
PB11 = RMII_TX_EN
PB12 = RMII_TXD0 
PB13 = RMII_TXD1
PB14 = RMII_INT

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : GPIO, SYSCFG, EXTI, MISC
Benutzte Librarys : keine

Enumerationen :

1
2
3
4
5
typedef enum {
  HTTP_SERVER_OK =0,
  HTTP_SERVER_ETH_MACDMA_ERR,
  HTTP_SERVER_ETH_PHYINT_ERR
}HTTP_SERVER_STATUS_t;

Funktionen :

1
2
HTTP_SERVER_STATUS_t UB_HTTP_Server_Init(void);  // zum init vom Server
void UB_HTTP_Server_Do(void);                    // muss zyklisch aufgerufen werden

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//--------------------------------------------------------------
// File     : main.c
// Datum    : 12.05.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.0
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der HTTP-Server Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_http_server.h"
#include "stm32_ub_led.h"
 
int main(void)
{
  HTTP_SERVER_STATUS_t check;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // LEDs initialisieren
  UB_Led_Init();
 
  // HTTP-Server initialisieren
  check=UB_HTTP_Server_Init();
  if(check==HTTP_SERVER_OK) {
    // wenn Server ok
    UB_Led_On(LED_GREEN);
  }
  else {
    // bei einem Fehler
    UB_Led_On(LED_RED);
  }
 
  while(1)
  {
    // HTTP-Server zyklisch aufrufen
    UB_HTTP_Server_Do();
  }
}

Hier die Library zum Download :

ub_stm32f4_http_server_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_40_HTTP_Server

39 Antworten auf 40-HTTP_Server-Library (STM32F4)

  1. lungfish sagt:

    Erstmal danke für den Code. Ich habe bislang kein anderes Coocox / STM32F4 / Ethernet Beispiel gefunden, das auf Anhieb compilierbar wäre! Meine Testplattform ist ein Olimex STM32F4-E407. Leider hat uns Olimex einen KS8721 auf die F4-Boards gesetzt, so dass es erstmal geheißen hat “such den Unterschied”.
    Der größte Unterschied liegt im der RMII-Interrupt Behandlung. Die Register des KS8721 bieten mehr Interrupt Quellen und Flags. Zum Testen habe das Interrupt-Handling erstmal deaktiviert.
    Zu meinem krassen Erstaunen läuft der lwip trotzdem, komplett mit CGI.
    Nun gilt es eigene Seiten zu basteln und die Software auf Herz und Nieren zu testen.
    Nochmal – Danke für die Codebasis!

    • admin_ub sagt:

      Kein Problem, hört man gerne wenn etwas gleich funktioniert. Schön wäre es, wenn man die Seiten von SD-Karte laden könnte und nicht erst wandeln und ins Flash packen müsste. Hab aber leider im Moment andere “Baustellen”. Gruss

  2. lungfish sagt:

    Ich habe gerade einen Bugfix-Vorschlag zum Thema SSI-Performance beim lwip geposted (langsame Abarbeitung von mehr als einem Tag). Vielleicht hilft jemandem die Info weiter:
    https://savannah.nongnu.org/bugs/?31948

  3. lungfish sagt:

    Ich bin die Tage auf gewaltigen Widerstand gestoßen, als ich den HTTP-Server auf ein MountaineerETH-Board portieren wollte.

    Die Boards sind eigentlich Basis für .NET Gadgeteer: http://www.netmf.com/gadgeteer
    http://www.mountaineer-boards.com/home/ethernet-mainboard/

    Die Besonderheit ist, dass die Boards das große, pinfressende MII-Interface verwenden, statt des RMII. Die PHY ist ein 78Q2123.

    Frage: hat evtl. jemand einen erfolgreichen Port durchführen können?

  4. Bastler sagt:

    Ich habe den Webserver am laufen.
    Leider sind meine Pings im Bereich von 100 – 400ms.
    Ich habe den PB14 = RMII_INT nicht anngeschlossen.
    Geht dieser an den Pin7 vom PHY? Liegt es daran?

    • admin_ub sagt:

      Ja, PB14 geht an Pin7. Keine Ahnung ob diese fehlende Leitung schuld ist. Hast du einen Router oder Switch dazwischen oder eine direkt Verbindung vom PC zum PHY ?

  5. Fabi sagt:

    Hallo Uwe,
    großes Kompliment für deine tolle Seite + Library. Sie hat mir schon bei vielen Projekten weiterhelfen können.
    Habe mir nun das stmF4Discovery Board + Base Board zugelegt und dein HTTP_Server-Demoprogramm drauf geladen. Allerdings kann ich das Board nicht anpingen… Habe nur die IP Adresse auf 192.168.2.10 und das Gateway auf 192.168.2.1 geändert. Den Rest so gelassen wie er ist.
    Hast du mir einen Tipp was ich falsch mache?

    Besten Dank,
    Fabi

    • admin_ub sagt:

      leuchtet die grüne LED zum zeichen das der Server läuft ?. Häng die Platine mal per CrossOver-Ethernet-Kabel direkt an deinen PC (also ohne Switch oder Router) und achte darauf das dein PC auch im Adressraum 192.168.2.x liegt. Versuch dann den Ping nochmal.

      • Fabi sagt:

        Hallo,
        1. mein Fehler dass ich diese Demoversion verwendet habe… Das Base Board hat den LAN8720 verbaut.
        2. Habe nun das Show4_Projekt aufgespielt mit SD Karte, LED Leuchtet grün, abermals kein PING.
        Habe #define F4D in stm32_ub_http_server.h gesetzt. Muss ich sonst noch was beachten?

        • admin_ub sagt:

          Vorsicht der Define “F4D” muss in den Compiler Settings gemacht werden (weil er in mehreren Files abgefrag wird) also bei CoIDE unter “Configuration” den Define “F4D” hinzufügen !! und laut einem Bugreport von “Holger” fehlt dann anscheined noch die Systick-Konfig, hab das aber selbst nicht gepüft.

          • Fabi sagt:

            Danke, Problem war mit dem korrekten Define von F4D gelöst!

          • MartinSt sagt:

            Mich würde nur der Vollständigkeit halber interessieren, wo das #define F4D vorkommt, ich kann die Zeichenkette “F4D” in der Bibliothek nirgendwo finden.
            Kann jemand erklären wofür das gebraucht wird/wurde?

          • admin_ub sagt:

            in meiner LIB kommt dieser Define gar nicht vor, der war im Original-Beispiel von ST vorhanden.

  6. Jo sagt:

    Moin Moin,

    bei mir funktioniert irgendwie leider nichts. Weder IP noch MAC wird erkannt. Pingen kann ich dementsprechend auch nicht. Hab den PHY direkt über ein Crossover an meinem Laptop. LaptopRechner über das Crossover funktioniert.
    PB14 = RMII_INT ist allerdings nicht angeschlossen. Ist bei meinem Phy auch nicht rausgeführt. Ich habe mich an die Verkabelung von http://blog.tkjelectronics.dk/2012/08/ethernet-on-stm32f4discovery-using-external-phy/ gehalten. Die ist bis auf PB14 identisch.
    Hab schon diverse Librarys usw. und steh nun auf dem Schlauch.
    Die Kabellängen zwischen Board und PHY sind 10cm. Liegt es daran?
    Das Board ist das normale STM32F4Discovery und als PHY wird der von Waveshare verwendet. Mit dem DP83848

    Viele Grüße
    Jo

    • Jo sagt:

      So,
      Probleme konnten behoben werden. Habe die Kabel von 10 cm auf ca 6cm gekürzt und wieder verkabelt. Jetzt läuft er.

  7. Michi sagt:

    Hi,
    auf Anhieb kompilierbar, die Grüne LED leuchtet. PB14 = RMII_INT kann ich nicht anschließen weil es den Pin auf meinem DP83848 nicht gibt. Hab dieses Projekt probiert: http://blog.tkjelectronics.dk/2012/08/ethernet-on-stm32f4discovery-using-external-phy/ und es funktioniert. Verstehe nur nicht warum deines nicht geht … Woran könnte es liegen?
    Die Verbindungen wären schön kurz ca 5cm!
    Grüße
    Michi

    • admin_ub sagt:

      kannst du das board auf “192.168.0.10″ pingen ?
      In meinem Beispiel ist “DHCP” aus !

      • Michi sagt:

        Geht auch nicht kommt die Meldung: Zeitüberschreitung der Anforderung.

        • admin_ub sagt:

          liegt dein PC im gleichen Adressraum ?

          • Michi sagt:

            Ja beides hängt an meinem router!

          • admin_ub sagt:

            der Router vergibt die Adressen normalerweise per DHCP kontrolliere nochmal am PC per “ipconfig” ob dieser wirklich eine Adresse “192.168.0.x” besitzt ich vermute eher was mit “192.168.178.x”
            dann kannst du noch zwei sachen probieren
            1. den PC direkt an die Platine anschließen und am PC manuell eine IP vergeben
            2. Im H-File “DHCP” einschalten

  8. Michi sagt:

    DHCP ein, und läuft! Danke
    Gruß
    Simon

  9. malte sagt:

    Hallo,

    kann mir jemand sagen ob und wenn für was RMII_INT verwendet wird. Ich mache gerade eine Platine und würde den Pin PB14 gerne für etwas anderes nutzen. Bei anderen Projekten die ich gefunden habe wird dieser Pin nicht verbunden.

    Im Datenblatt des DP…. heißt es:
    The Power Down and Interrupt functions are multiplexed on pin 7 of the device. By default, this pin functions as a power down input and the interrupt function is disabled. Setting bit 0 (INT_OE) of MICR (0x11h) will configure the pin as an active low interrupt output.

    Jetzt konnte ich in den Sourcen zwar finden das PB14 verwendet wird, wird aber auch der Interrupt initialisiert? Falls nein, dann würde mir doch ein Pullup reichen um den Phy Aktiv zu halten?
    POWER DOWN: The pin is an active low input in this mode and should be asserted low to put the device in a Power Down mode.

    Grüße
    Malte

  10. joof sagt:

    Hallo zusammen,

    hat schon mal jemand mit einem anderen Phy dieses Beispiel zum laufen gebracht?
    Ich habe hier einen eigenen Aufbau mit dem micrel KSZ8081RNB und komme leider nicht weiter :(

    Gruß joof

  11. Matt sagt:

    Hallo,

    in der Funktion tcp_send_empty_ack und tcp_keepalive sind die Zeilen tcphdr = tcp_output_set_header jeweils auskommentiert. In den Originalsourcen sind sie aber drin. Diese Zeilen füllen den TCP header z.B. für leere ACK-Pakete aus. Wenn man die auskommentiert läßt und z.B. den Stack anders benutzen will um große Datenmengen zu empfangen gibt es korrupte ACK – Pakete und die Übertragung geht nicht. Wenn ich das wieder mit reinnehme geht alles, warum sind die also hier auskommentiert?

    Matthias

    • admin_ub sagt:

      Uhhh…das ist zu lange her, kann ich mich nicht erinnern. Vermutlich mein Fehler bei copy&paste.

  12. Flip sagt:

    Hallo,

    ich habe den Webserver mit dem STM32E407 zum laufen gebracht.
    Einwandfrei muss ich sagen.
    Jetzt möchte ich aber wissen, wie ich mittels diesem Webserver weitere GPIOs ansprechen kann. Ich habe leider noch keine Ahnung, wie/wo die Webserverkommunikation im C-Code stattfindet, könntest du mir da bitte weiter Helfen.

    Des Weiteren, könntest du mir die Dateien, die du mittels dem Tool “makefsdata.exe” zur “fsdata.c” gewandelt hast zur Verfügung stellen, vielleicht werde ich daraus schlauer, wie ich weitere Funktionen einfügen und entfernen kann.

    Vielen Dank schoneinmal im Voraus

    Grüße
    Phil

    • admin_ub sagt:

      die files sind alle in der library enthalten. Im Unterordner “ub_lib/http_server/doc”

      • Flip sagt:

        ah, besten Dank. Habe ich wohl übersehen.

        Könntest du mir noch sagen, in welcher c-source-file dann die Checkboxen der http für die LED abgefragt werden und in welcher c-source-file diese dann ein-/ausgeschaltet werden.
        Würde mir auf die schnelle einiges erleichtern. Vielen Dank
        Gruß Phil

  13. Jens sagt:

    Hallo,

    ich versuche mit dieser Webserver Demo, weitere “ADC_Handler” zu implementieren, aber es funktioniert einfach nicht.
    Dabei passe ich die Datei “httpd_cgi_ssi.c” sowie die “xxxx.shtml” Seite an. Auf was muss ich alles achten, um mehrere Handler hinzubekommen? Mit dem LED Handler funktionieren mehrere soweit ganz gut.

    Danke, MFG J

    • admin_ub sagt:

      hab ich mich noch nicht mit beschäftigt

  14. Hand sagt:

    Ich habe das gleiche Problem wie Joof,


    hat schon mal jemand mit einem anderen Phy dieses Beispiel zum laufen gebracht?
    Ich habe hier einen eigenen Aufbau mit dem micrel KSZ8081RNB und komme leider nicht weiter :(

    Ich bekomme den KSZ8081 ebenfalls nicht zum laufen, habe vorher einen ST802RT1A verwendet, der lief einwandfrei. Muss ich noch was in den Headerfiles ändern? In dem “stm32f4x7_eth_conf.h” finde ich PHY anhängige Register, muss da etwas angepasst werden?

    Gruß joof

    • Hand sagt:

      In dem Header-File finde ich folgende Zeile:

      #define PHY_SR ((uint16_t)17) /* Value for ST802RT/STE101P PHY */

      Muss ich da was anpassen?

  15. Jens sagt:

    Hallo,

    ich habe den Webserver lokal zum laufen bekommen. Also ich kann innerhalb meines eigenen Netzwerkes mittels fester IP-Adresse auf das Board zugreifen und eine Weboberfläche aufrufen/steuern.

    Jetzt möchte ich aber nicht lokal darauf zugreifen können, sondern mittels Internet.
    – Ist das mit diesem Webserver möglich?
    – Auf was muss ich achten/anpassen, dass dies funktioniert?
    – Gibt es Examples hierfür?

    Viele Grüße und Danke für die Mühen.
    Jens

    • admin_ub sagt:

      das muss am Router eingestellt werden. Thema : Portweiterleitung

      • Jens sagt:

        wenn ich versuche DHCP zu aktivieren, bekomme ich keine Verbindung mit dem Port.

        Was muss ich da alles aktivieren (wie z.B. #define USE_DHCP)??

        Wie kann ich danach auf den Server zugreifen? IP (die ich dann nicht kenne)? oder wie funktioniert dies dann?

        Danke :)

        • Jens sagt:

          statt “port” meinte ich natürlcih “Board”

          • admin_ub sagt:

            schau am router nach, der vergibt die ip nummern,
            oder geb sie per UART oder LCD aus.

  16. Flo sagt:

    Hey,

    Server funktioniert ohne problem, wenn beim Starten des Boards das Netzwerkkabel angeschlossen ist.

    ABER,wenn ich das Board starte und es dabei nicht am Netzwerk angeschlossen ist, dann funktioniert der Server ja nicht. Jetzt habe ich eine Schleife eingebaut, bei dem nach dem Starten des Boards (Ethernetkabel beim Start noch nicht angeschlossen), solange in der Schleife (while) geblieben wird, bis ein bestimmter Button gedrückt ist, um nochmals die Funktion

    // HTTP-Server initialisieren
    check=UB_HTTP_Server_Init();

    aufzurufen. Wenn bei diesem erneuten Aufruf dann das Ethernet-Kabel angeschlossen ist, dann wird die while-Schleife erfolgreich verlassen, da

    check==HTTP_SERVER_OK;

    ist.

    Aber anschließend funktioniert der Server trotzdem nicht. Es wird zwar dies zyklisch aufgerufen:

    //HTTP-Server zyklisch aufrufen
    UB_HTTP_Server_Do();

    aber nach ein paar mal schon nichtmehr. (bleibt irgendwo hängen oder so,… aber genau weis ich es auch nicht).

    Was muss ich bei dieser Aktion alles beachten? Irgendwelche Funktionen, GPIOs, etc…. zurücksetzen/deinitialisieren??

    Vielen Dank.

    Gruß Flou


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert