AnsweredAssumed Answered

stm32f407 discovery ethernet ping fails after some time

Question asked by vnv on Dec 4, 2015


I've created basic code with stm32cube with lwip.
I would like to have some basic tcp server to output data when connected to it.
Problem is that while I successfully connect to my setup and ping it,after a while if I want to ping or connect to system, it doesn't respond.
For some reason just not touching the system and letting it be makes it die.

I am using stm32f407 discovery board with stm32f4 expansion board (ethernet/serial).


In the lwip.c code there is note saying that "MX_LWIP_Process(void)" function should be put in some while(1).
I am running FreeRTOS so I've put it into separate thread.
All threads have same priority, is this correct? Does this function has to be inside thread with greater priority then all other threads?

Could someone please give a hint on it please.


Here is the code:


freertos.c

    /* Includes ------------------------------------------------------------------*/
    #include "FreeRTOS.h"
    #include "task.h"
    #include "cmsis_os.h"
    
    /* USER CODE BEGIN Includes */
    #include "gpio.h"
    /* USER CODE END Includes */
    
    /* Variables -----------------------------------------------------------------*/
    osThreadId defaultTaskHandle;
    osThreadId myTask01Handle;
    
    /* USER CODE BEGIN Variables */
    
    /* USER CODE END Variables */
    
    /* Function prototypes -------------------------------------------------------*/
    void StartDefaultTask(void const * argument);
    void StartTask01(void const * argument);
    
    extern void MX_LWIP_Init(void);
    void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
    
    /* USER CODE BEGIN FunctionPrototypes */
    #include "lwip/opt.h"
    #include "lwip/arch.h"
    #include "lwip/api.h"
    #include "lwip/inet.h"
    #include "lwip/sockets.h"
    /* USER CODE END FunctionPrototypes */
    
    /* Hook prototypes */
    
    /* Init FreeRTOS */
    
    void MX_FREERTOS_Init(void) {
        /* USER CODE BEGIN Init */
    
        /* USER CODE END Init */
    
        /* USER CODE BEGIN RTOS_MUTEX */
        /* add mutexes, ... */
        /* USER CODE END RTOS_MUTEX */
    
        /* USER CODE BEGIN RTOS_SEMAPHORES */
        /* add semaphores, ... */
        /* USER CODE END RTOS_SEMAPHORES */
    
        /* USER CODE BEGIN RTOS_TIMERS */
        /* start timers, add new ones, ... */
        /* USER CODE END RTOS_TIMERS */
    
        /* Create the thread(s) */
        /* definition and creation of defaultTask */
        osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
        defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
    
        /* definition and creation of myTask01 */
        osThreadDef(myTask01, StartTask01, osPriorityNormal, 0, 128);
        myTask01Handle = osThreadCreate(osThread(myTask01), NULL);
    
        /* USER CODE BEGIN RTOS_THREADS */
        /* add threads, ... */
        /* USER CODE END RTOS_THREADS */
    
        /* USER CODE BEGIN RTOS_QUEUES */
        /* add queues, ... */
        /* USER CODE END RTOS_QUEUES */
    }
    
    /* StartDefaultTask function */
    void StartDefaultTask(void const * argument) {
        /* init code for LWIP */
        // reset du PHY on the  STM32F4DIS-BB  board
        HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
        osDelay(50);
    
        HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET);
        osDelay(50);
    
          MX_LWIP_Init();
    
           int sock, newconn, size;
            struct sockaddr_in address, remotehost;
          unsigned char buffer[]="\n\n ovo je neki podatak\n\n";
    
    
           /* create a TCP socket */
            if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
            {
              printf("can not create socket");
              return;
            }
    
            /* bind to port 80 at any interface */
            address.sin_family = AF_INET;
            address.sin_port = htons(80);
            address.sin_addr.s_addr = INADDR_ANY;
    
            if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
            {
              printf("can not bind socket");
              return;
            }
    
            /* listen for incoming connections (TCP listen backlog = 5) */
            listen(sock, 5);
    
            size = sizeof(remotehost);
    
    
        /* Infinite loop */
        for (;;) {
    
            newconn = accept(sock, (struct sockaddr *)&remotehost, (socklen_t *)&size);
            write(newconn, buffer, (size_t) strlen(buffer));
    
            /* Close connection socket */
            close(newconn);
    
    
        }
        /* USER CODE END StartDefaultTask */
    }
    
    /* StartTask01 function */
    void StartTask01(void const * argument) {
        /* USER CODE BEGIN StartTask01 */
        /* Infinite loop */
        for (;;) {
            //osDelay(1);
            MX_LWIP_Process();
        }
        /* USER CODE END StartTask01 */
    }
    
    /* USER CODE BEGIN Application */
    
    /* USER CODE END Application */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


lwip.c

    /* Includes ------------------------------------------------------------------*/
    #include "lwip.h"
    #include "lwip/init.h"
    #include "lwip/netif.h"
    
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /* ETH Variables initialization ----------------------------------------------*/
    
    /* USER CODE BEGIN 1 */
    
    /* USER CODE END 1 */
    
    /* Variables Initialization */
    struct netif gnetif;
    struct ip_addr ipaddr;
    struct ip_addr netmask;
    struct ip_addr gw;
    uint8_t IP_ADDRESS[4];
    uint8_t NETMASK_ADDRESS[4];
    uint8_t GATEWAY_ADDRESS[4];
    
    /* USER CODE BEGIN 2 */
    
    /* USER CODE END 2 */
    
    /* init function */
    void MX_LWIP_Init(void)
    {
      IP_ADDRESS[0] = 192;
      IP_ADDRESS[1] = 168;
      IP_ADDRESS[2] = 1;
      IP_ADDRESS[3] = 4;
      NETMASK_ADDRESS[0] = 255;
      NETMASK_ADDRESS[1] = 255;
      NETMASK_ADDRESS[2] = 255;
      NETMASK_ADDRESS[3] = 0;
      GATEWAY_ADDRESS[0] = 192;
      GATEWAY_ADDRESS[1] = 168;
      GATEWAY_ADDRESS[2] = 1;
      GATEWAY_ADDRESS[3] = 1;
       
      tcpip_init( NULL, NULL );    
     
      IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
      IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
      IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);  
      
    
      /* add the network interface */
      netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
     
     
      /*  Registers the default network interface */
      netif_set_default(&gnetif);
    
      if (netif_is_link_up(&gnetif))
      {
        /* When the netif is fully configured this function must be called */
        netif_set_up(&gnetif);
      }
      else
      {
        /* When the netif link is down this function must be called */
           netif_set_down(&gnetif);
      }  
      
    
    /* USER CODE BEGIN 3 */
    
    /* USER CODE END 3 */
    }
    
    /* USER CODE BEGIN 4 */
    /**
     * ----------------------------------------------------------------------
     * Function given to help user to continue LwIP Initialization
     * Up to user to complete or change this function ...
     * Up to user to call this function in main.c in while (1) of main(void)
     *-----------------------------------------------------------------------
     * Read a received packet from the Ethernet buffers
     * Send it to the lwIP stack for handling
     * Handle timeouts if NO_SYS_NO_TIMERS not set and without RTOS
     */
    void MX_LWIP_Process(void)
    {
      ethernetif_input(&gnetif);
           
      /* Handle timeouts */
      #if !NO_SYS_NO_TIMERS && NO_SYS
        sys_check_timeouts();
      #endif
        
    }
    /* USER CODE END 4 */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


EDIT1:

Ok, so looking at the code I've found "ethernetif_input" function and to start debugging begin printing + when netif->input returns OK and - when it doesn't.


After pinging from the computer:


    C:\Users\uer>ping 192.168.1.4
    
    Pinging 192.168.1.4 with 32 bytes of data:
    Reply from 192.168.1.4: bytes=32 time<1ms TTL=255
    Reply from 192.168.1.4: bytes=32 time<1ms TTL=255
    Reply from 192.168.1.4: bytes=32 time<1ms TTL=255
    Reply from 192.168.1.4: bytes=32 time<1ms TTL=255
    
    Ping statistics for 192.168.1.4:
        Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
    Approximate round trip times in milli-seconds:
        Minimum = 0ms, Maximum = 0ms, Average = 0ms
    
    C:\Users\uer>ping 192.168.1.4
    
    Pinging 192.168.1.4 with 32 bytes of data:
    Reply from 192.168.1.4: bytes=32 time<1ms TTL=255
    Request timed out.
    Request timed out.
    Request timed out.
    
    Ping statistics for 192.168.1.4:
        Packets: Sent = 4, Received = 1, Lost = 3 (75% loss),
    Approximate round trip times in milli-seconds:
        Minimum = 0ms, Maximum = 0ms, Average = 0ms
    
    C:\Users\uer>


Pattern in Serial Wire Viewer shows: ++++++++--------------

So it is obvious that something makes it stop receiving packet, but what is
strange is that interrupt gets called (because of printed -).

Here is the function from ethernetif.c:




    /**
     * This function should be called when a packet is ready to be read
     * from the interface. It uses the function low_level_input() that
     * should handle the actual reception of bytes from the network
     * interface. Then the type of the received packet is determined and
     * the appropriate input function is called.
     *
     * @param netif the lwip network interface structure for this ethernetif
     */
    void ethernetif_input( void const * argument )
     
    {
     
      struct pbuf *p;
      struct netif *netif = (struct netif *) argument;
      
      for( ;; )
      {
        if (osSemaphoreWait( s_xSemaphore, TIME_WAITING_FOR_INPUT)==osOK)
        {
          do
          {   
            p = low_level_input( netif );
            if   (p != NULL)
            {
              if (netif->input( p, netif) != ERR_OK )
              {
                pbuf_free(p);
                ITM_SendChar('-');
              }else{
                ITM_SendChar('+');
              }
            }
    
          } while(p!=NULL);
        }
     
      }
    }





Outcomes