STM32 and LWIP help with CubeMX

Thread Starter

Gibson486

Joined Jul 20, 2012
355
Looking for help with the STM32 platform and LWIP when using CubeMX. I have been trying to find a demo that works. Unfortunately, all the demos are pre CubeMX. I have tried to reverse engineer it and use it in conjunction with CubeMX, but to no avail. All i am trying to is have my Nucleo board send a message as a client. My problem is that I am not even sure if the issue is me finding an incorrect address or my code is just not working. I tried just piggy backing off of the demo code in ST micros code base, but no dice.

Here is what i have done so far (it took me a few days to even get this far...do not judge!)....

I set up cubemx (yes, I set PHY to 0)....

I set up my own code.

Code:
/**
  ******************************************************************************
  * File Name          : main.c
  * Description        : Main program body
  ******************************************************************************
  * This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * Copyright (c) 2017 STMicroelectronics International N.V.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted, provided that the following conditions are met:
  *
  * 1. Redistribution of source code must retain the above copyright notice,
  *    this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. Neither the name of STMicroelectronics nor the names of other
  *    contributors to this software may be used to endorse or promote products
  *    derived from this software without specific written permission.
  * 4. This software, including modifications and/or derivative works of this
  *    software, must execute solely and exclusively on microcontroller or
  *    microprocessor devices manufactured by or for STMicroelectronics.
  * 5. Redistribution and use of this software other than as permitted under
  *    this license is void and will automatically terminate your rights under
  *    this license.
  *
  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
#include "lwip.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

struct udp_pcb *pcb;
__IO uint32_t message_count = 0;
u8_t   data[100];

//ip_addr_t DestIPaddrfornow;


/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

void udp_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
void udp_echoclient_send(void);
void udp_echoclient_connect(void);


/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration-----------------------------------------  -----------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LWIP_Init();

  /* USER CODE BEGIN 2 */

  udp_echoclient_connect();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
      MX_LWIP_Process();

      udp_echoclient_send();

      HAL_Delay(200);

      HAL_GPIO_TogglePin(GPIOB, LD3_Pin|LD2_Pin);

  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

    /**Configure the main internal regulator output voltage
    */
  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

    /**Initializes the CPU, AHB and APB busses clocks
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 180;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Activate the Over-Drive mode
    */
  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
     PD8   ------> USART3_TX
     PD9   ------> USART3_RX
     PA8   ------> USB_OTG_FS_SOF
     PA9   ------> USB_OTG_FS_VBUS
     PA10   ------> USB_OTG_FS_ID
     PA11   ------> USB_OTG_FS_DM
     PA12   ------> USB_OTG_FS_DP
*/
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, LD3_Pin|LD2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : USER_Btn_Pin */
  GPIO_InitStruct.Pin = USER_Btn_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : LD3_Pin LD2_Pin */
  GPIO_InitStruct.Pin = LD3_Pin|LD2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : STLK_RX_Pin STLK_TX_Pin */
  GPIO_InitStruct.Pin = STLK_RX_Pin|STLK_TX_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_PowerSwitchOn_Pin */
  GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_OverCurrent_Pin */
  GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : USB_SOF_Pin USB_ID_Pin USB_DM_Pin USB_DP_Pin */
  GPIO_InitStruct.Pin = USB_SOF_Pin|USB_ID_Pin|USB_DM_Pin|USB_DP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_VBUS_Pin */
  GPIO_InitStruct.Pin = USB_VBUS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USB_VBUS_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
void udp_echoclient_connect(void)
{
  ip_addr_t DestIPaddr;
  err_t err;

  /* Create a new UDP control block  */
  pcb = udp_new();

  if (pcb!=NULL)

      /*169.254.115.162*/
  {
    /*assign destination IP address */
    IP4_ADDR( &DestIPaddr, 169, 254, 115, 162);

    DestIPaddrfornow = DestIPaddr;

    /* configure destination IP address and port */
    err= udp_connect(pcb, &DestIPaddr, 444);

    if (err == ERR_OK)
    {
      /* Set a receive callback for the upcb */
      udp_recv(pcb, udp_receive_callback, NULL);
    }
  }
}

void udp_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{

  /*increment message count */
  message_count++;

  /* Free receive pbuf */
  pbuf_free(p);

// udp_echoclient_send();
}

void udp_echoclient_send(void)
{
  struct pbuf *p;

  sprintf((char*)data, "sending udp client message.................................... %d");

  /* allocate pbuf from pool*/
  p = pbuf_alloc(PBUF_TRANSPORT,strlen((char*)data), PBUF_POOL);

  if (p != NULL)
  {
    /* copy data to pbuf */
    pbuf_take(p, (char*)data, strlen((char*)data));

    /* send udp data */
    udp_send(pcb, p);

    /* free pbuf */
    pbuf_free(p);
  }
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void _Error_Handler(char * file, int line)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

/**
  * @}
  */

/**
  * @}
*/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Then I fired up Socket Test V3

Then I also fired up Wire Shark

Here is what I think should be happening. On Socket Test, I should just be see whatever I send. I do not.

All I see on Wire Shark is a few scattered udp packets here and there. I thought I should be seeing udp packet spamming my computer.

What I am confused about is this the whole address and port situation as well. How do I know which ports to pick? When I choose a port that it shows on wireshark, it says that it cannot bind to it.

Help would be greatly appreciated. I am ripping my hair out on this. I am new to ethernet, so do go easy on me!
 

Thread Starter

Gibson486

Joined Jul 20, 2012
355
Yeah, that was the first thing i read. I gives great detail if you were starting it from scratch (like no cube MX), but there is an assumption that you have working code to go with it. That, and echotool (what they say to use to verify it works) does not work with windows 10.
 
Hello Gibson,

now I have the same issue like you, I need to communicate with my PC (UDP) over the Stm32F4 board ( with Stm32F4-dis bb). All the examples are implemented in the standard libary. Did you get to work? Can You give an advice?

I am testing with stm32F4 - Router 8with DHCP) - PC. In the list of the router i can see the F4 with the right MAC / IP adress. But now I don't know how to configure my UDP messages.

Thank you!
 

NV64

Joined Feb 15, 2019
38
Some time ago I had the same problem. All examples for LWIP used the SPL library. After spending a lot of time I made CubeMX + LWIP work. I will try to find my project or at least information on how to do it. Because I forgot how I did it.
 

mcqtom

Joined Mar 2, 2020
1
Some time ago I had the same problem. All examples for LWIP used the SPL library. After spending a lot of time I made CubeMX + LWIP work. I will try to find my project or at least information on how to do it. Because I forgot how I did it.
Any chance you ever found this? Im battling the same problem right now
 

NV64

Joined Feb 15, 2019
38
Сould not find my example. Therefore made a new one.
The project was created for STM32F4Discovery + Lan8720. Connect directly to your computer. In Windows, you need to change the network settings: IP address 192.168.0.1, subnet mask 255.255.255.0
CubeMX Settings:2.PNG3.PNG4.PNG5.PNG6.PNG7.PNG8.PNG

main.c
Code:
void TskEthernet(void const * argument)
{
  /* USER CODE BEGIN TskEthernet */
  /* Infinite loop */
    struct netconn *conn, *newconn;
    err_t err, accept_err;
    /* Create a new TCP connection handle */
    osDelay(2);
    for(;;)
    {
        conn = netconn_new(NETCONN_TCP);
        if (conn!= NULL)
        {
            /* Bind to port 80 (HTTP) with default IP address */
            err = netconn_bind(conn, NULL, 80);
            if (err == ERR_OK)
            {
                /* Put the connection into LISTEN state */
                netconn_listen(conn);
                /* accept any icomingconnection */
                accept_err= netconn_accept(conn, &newconn);                   
                if(accept_err== ERR_OK)
                {
                    /* serve connection */
                    while (1)
                    {
                        netconn_write(newconn, (const unsigned char*)("test\r\n"), (size_t)6, NETCONN_COPY);vTaskDelay(1000);
                    }
                }
            }       
            
        }
    }
  /* USER CODE END TskEthernet */
}
We connect on the computer in the TCP terminal to our microcontroller at the address 192.168.0.10, port 80. And once a second get the message "test".
I can fully lay out the source code, but I don't know how to do it.
 

smittpitt

Joined Aug 11, 2023
1
Сould not find my example. Therefore made a new one.
The project was created for STM32F4Discovery + Lan8720. Connect directly to your computer. In Windows, you need to change the network settings: IP address 192.168.0.1, subnet mask 255.255.255.0
CubeMX Settings:View attachment 209771View attachment 209772View attachment 209773View attachment 209774View attachment 209775View attachment 209776View attachment 209777

main.c
Code:
void TskEthernet(void const * argument)
{
  /* USER CODE BEGIN TskEthernet */
  /* Infinite loop */
    struct netconn *conn, *newconn;
    err_t err, accept_err;
    /* Create a new TCP connection handle */
    osDelay(2);
    for(;;)
    {
        conn = netconn_new(NETCONN_TCP);
        if (conn!= NULL)
        {
            /* Bind to port 80 (HTTP) with default IP address */
            err = netconn_bind(conn, NULL, 80);
            if (err == ERR_OK)
            {
                /* Put the connection into LISTEN state */
                netconn_listen(conn);
                /* accept any icomingconnection */
                accept_err= netconn_accept(conn, &newconn);                
                if(accept_err== ERR_OK)
                {
                    /* serve connection */
                    while (1)
                    {
                        netconn_write(newconn, (const unsigned char*)("test\r\n"), (size_t)6, NETCONN_COPY);vTaskDelay(1000);
                    }
                }
            }    
         
        }
    }
  /* USER CODE END TskEthernet */
}
We connect on the computer in the TCP terminal to our microcontroller at the address 192.168.0.10, port 80. And once a second get the message "test".
I can fully lay out the source code, but I don't know how to do it.
Do you have the possibility to create a git repo or upload the project to google drive or similar? I am looking for exactly the same configuration with a STM32F407-Discovery Board anda LAN8720

Mod: added tag alert for @NV64
 
Top