How can I use lwIP tcp/ip stack with microcontroller stm32f4 (client)

2

Core: Cortex-M4

Microcontroller: stm32f407 (stm32f4 discovery board)

IP Stack: lwIP 1.4.1

I am using this microcontroller to control an automate and I want to send some information to a separate web server via a HTTP request in the form of:

http://192.168.1.3/api/xdevices.json?SetR=01

lwIP has a http server for the microprocessor, but I'm after the opposite (microcontroller is the client).

I am not sure what i'm doing wrong but after TCP_Connect it always goes to tcp_error handler :

   #include "stm32f4xx.h"
   /* Include my libraries here */
   #include "defines.h"
   #include "tm_stm32f4_delay.h"
   #include "tm_stm32f4_disco.h"
   #include "tm_stm32f4_usart.h"
   #include "tm_stm32f4_ethernet.h"
   #include "tm_stm32f4_watchdog.h"
   #include <stdio.h>
   #include <stdlib.h>
   #include <lwip/tcp.h>
   #include <tcp.h>


  uint32_t tcp_send_packet(void);
  void tcpErrorHandler(void *arg, err_t err);
  err_t tcpSendCallback(void *arg, struct tcp_pcb *tpcb,u16_t len);

  err_t connectCallback(void *arg, struct tcp_pcb *tpcb, err_t err);

  struct   tcp_pcb *testpcb;

first Function is tcp_new :

    void tcp_setup(void)
    {
    uint32_t data = 0xdeadbeef;
    /* create an ip */
    struct ip_addr ip;
    IP4_ADDR(&ip,192,168,1,4);    //IP of my PHP server
    /* create the control block */
    testpcb = tcp_new();    //testpcb is a global struct tcp_pcb
                        // as defined by lwIP
    /* dummy data to pass to callbacks*/
    tcp_arg(testpcb, &data);
   /* register callbacks with the pcb */
   // tcp_recv(testpcb, tcpRecvCallback);
   tcp_sent(testpcb, tcpSendCallback);
   tcp_err(testpcb, tcpErrorHandler);
   /* now connect */
tcp_connect(testpcb, &ip, 21, connectCallback);
    TM_DISCO_LedOn(LED_ORANGE);
  }

My Callbacks :

    void tcpErrorHandler(void *arg, err_t err){
    TM_DISCO_LedOn(LED_BLUE);
    }


    err_t tcpSendCallback(void *arg, struct tcp_pcb *tpcb,u16_t len)
    {
    TM_DISCO_LedOn(LED_RED);                            
    }

    err_t connectCallback(void *arg, struct tcp_pcb *tpcb, err_t err)
    {
    TM_DISCO_LedOn(LED_RED);

    tcp_send_packet();
    return 0;
    }

my header :

    uint32_t tcp_send_packet(void)
    {
    char *string = "SetR=01\r\n\r\n ";
    uint32_t len = strlen(string);

     /* push to buffer */
    tcp_write(testpcb, string, strlen(string), TCP_WRITE_FLAG_COPY);
    /* now send */
    tcp_output(testpcb);

    return 0;
    }

    void    lwip_init();

Main function :

    int main(void) {
    /* Initialize system */
    SystemInit();
    lwip_init();
    /* Initialize delay */
    TM_DELAY_Init();
    /* Initialize leds on board */
    TM_DISCO_LedInit();

    /* Initialize button */
    TM_DISCO_ButtonInit();


    while(1) {

    tcp_setup();
    } }

Clearly i'm forgetting something i just don't know what it is .( i'm using Keil arm)

thank you

tcp
stack
microcontroller
lwip
stm32f4
asked on Stack Overflow Mar 28, 2017 by ELMahdi akrim

1 Answer

3
  • Init LwIP with lwip_init
  • Call tcp_setup outside while loop only once not in while loop to setup only one TCP connection, not unlimited
  • In while loop, process LwIP incoming data periodically. Since you are using my (TM Tilen Majerle) ethernet wrapper for STM32F4, you should add these lines inside your while loop

    /* Check if any packet received */
    if (LwIP_CheckFrameReceived()) { 
        /* Process received ethernet packet */
        LwIP_Pkt_Handle();
    }
    
    /* Handle periodic timers for LwIP */
    LwIP_Periodic_Handle(EthernetLocalTime);
    

Or call TM_ETHERNET_Update function from your library. Your choice, it works the same.

In your case:

int main() {
    ....
    lwip_init();
    tcp_setup();
    while (1) {
        TM_ETHERNET_Update();
    }
}
answered on Stack Overflow Mar 28, 2017 by tilz0R

User contributions licensed under CC BY-SA 3.0