2021-06-17 02:46 AM
Hello,
Sorry in advance for my English. I am also very new to embedded systems and softwares worlds.
I am currently trying the lwIP TCP/IP stack on a STM32756G-EVAL2 (STM32F756NGH) board. On one end, I have a Red Hat PC with a network interface used specifically to connect with the board through Ethernet. On the other end, the board linked to the PC with RJ-45 cable. I use STM32CubeIDE v1.5.0 as the IDE for developping my softwares, and the board is connected to the PC via ST-LINK v2.1. I am able to flash and debug my binaries without any issues.
My PC is network-configured with a static IP address (192.168.0.2), a netmask (255.255.255.0), a gateway (192.168.0.1) and a MAC address. The board is configured with a static IP address (192.168.0.10), a netmask (255.255.255.0), a gateway (192.168.0.1) and a MAC address (by default 00:80:E1:00:00:00).
To reproduce the issue as stated in the title (I will explain more specifically the issue below), here is what I do:
...
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/opt.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"
#include "lwip/ip4_addr.h"
#include "netif/etharp.h"
#include "ethernetif.h"
/* USER CODE END Includes */
...
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
extern struct netif gnetif;
extern ip4_addr_t ipaddr;
extern ip4_addr_t netmask;
extern ip4_addr_t gw;
extern uint8_t IP_ADDRESS[4];
extern uint8_t NETMASK_ADDRESS[4];
extern uint8_t GATEWAY_ADDRESS[4];
/* USER CODE END PV */
...
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 */
char str[] = "Hello UDP World!";
err_t err = 0;
ip_addr_t dstaddr;
ip_addr_t srcaddr;
IP4_ADDR(&dstaddr, 192, 168, 0, 2);
IP4_ADDR(&srcaddr, 192, 168, 0, 10);
struct udp_pcb * pcb;
struct pbuf * pb;
pcb = udp_new();
err = udp_bind(pcb, &srcaddr, 55151);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
err = 0;
pb = pbuf_alloc(PBUF_TRANSPORT, sizeof(str), PBUF_REF);
pb->payload = str;
pb->len = pb->tot_len = sizeof(str);
err = udp_bind(pcb, &srcaddr, 55151);
err = udp_connect(pcb, &dstaddr, 55151);
err = udp_sendto(pcb, pb, &dstaddr, 55151);
udp_disconnect(pcb);
udp_remove(pcb);
pbuf_free(pb);
HAL_Delay(1000);
MX_LWIP_Process();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
...
nc -ul 192.168.0.2 55151
Thus, I do not really understand why it is not working. I tried to change a lot of settings of the ETH and LWIP in the ioc, as well as doing some little debugging with breakpoints and running through each functions. No errors returned also. I tried with Netconn API and FreeRTOS, same problem: ping requests and responses work but not UDP or TCP. I did not tried sockets but i thought that if RAW API and Netconn API didn't worked, I will be more successful with socket API.
Do you have any ideas or solutions for this kind of issue?
Solved! Go to Solution.
2021-06-21 12:58 AM
Hello,
After debugging my program along with Netcat, I figured out what was the cause of the problem and now I can send and receive UDP packets.
The first thing I did was to activate the debug messages. About that, I had to manually define LWIP_DEBUG, as STM32CubeMX doesn't want to define it via the automatic generation.
I modified my code as this:
...
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/opt.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"
#include "lwip/ip4_addr.h"
#include "netif/etharp.h"
#include "ethernetif.h"
/* USER CODE END Includes */
...
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
extern struct netif gnetif;
extern ip4_addr_t ipaddr;
extern ip4_addr_t netmask;
extern ip4_addr_t gw;
extern uint8_t IP_ADDRESS[4];
extern uint8_t NETMASK_ADDRESS[4];
extern uint8_t GATEWAY_ADDRESS[4];
/* USER CODE END PV */
...
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 */
char str[] = "Hello UDP World!";
err_t err = 0;
ip_addr_t dstaddr;
ip_addr_t srcaddr;
struct eth_addr dstmac;
struct eth_addr srcmac;
IP4_ADDR(&dstaddr, 192, 168, 0, 2);
IP4_ADDR(&srcaddr, 192, 168, 0, 10);
struct udp_pcb * pcb;
struct pbuf * pb;
pcb = udp_new();
dstmac.addr[0] = 0x98;
dstmac.addr[1] = 0xDE;
dstmac.addr[2] = 0xD0;
dstmac.addr[3] = 0x01;
dstmac.addr[4] = 0x2C;
dstmac.addr[5] = 0x8A;
srcmac.addr[0] = 0x00;
srcmac.addr[1] = 0x80;
srcmac.addr[2] = 0xE1;
srcmac.addr[3] = 0x00;
srcmac.addr[4] = 0x00;
srcmac.addr[5] = 0x00;
etharp_add_static_entry(&dstaddr, &dstmac);
etharp_add_static_entry(&srcaddr, &srcmac);
err = udp_bind(pcb, &srcaddr, 55151);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
err = 0;
pb = pbuf_alloc(PBUF_TRANSPORT, sizeof(str), PBUF_RAM);
memcpy(pb->payload, str, sizeof(str));
err = udp_bind(pcb, &srcaddr, 55151);
err = udp_connect(pcb, &dstaddr, 55151);
err = udp_sendto(pcb, pb, &dstaddr, 55151);
MX_LWIP_Process();
udp_disconnect(pcb);
udp_remove(pcb);
pbuf_free(pb);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
...
As you can see, I attached the MAC addresses to source and remote IPv4 address structures. I also modified the allocation of the buffer by using RAM then a memcpy function to copy the string to the buffer payload.
Using Netcat, I changed my receive command by this one which works better as it is less ambiguous than the previous command: "$nc -u -s 192.168.0.2 -p 55151 192.168.0.10 55151" for the reception command and "$echo -e 'Hello\0' | nc -u4 -w 1 -s 192.168.0.2 -p 55151 192.168.0.10 55151" for the sending command.
Finally, the main error was to disconnect then to remove the udp_pcb before the call of MX_LWIP_Process() function. Thus, when the programm was trying to send UDP packets (or on other programs that try to receive UDP packets), the udp_pcb was unusable.
2021-06-18 04:17 AM
Hi @Community member ,
As this is not my area of expertise, I don't have a solution for your issue but I have a proposal: as you are using STM32756G-EVAL2 which is an ST board, why don't you select a ready to use example from STM32CubeF7 package and run it on your side? If all is working fine and as described in the readme.txt file, then you can update the example depending on your needs.
If you agree with that proposal, then look to the examples available under STM32Cube_FW_F7\Projects\STM32756G_EVAL\Applications\LwIP.
Please keep me informed if there is any progress.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2021-06-21 12:58 AM
Hello,
After debugging my program along with Netcat, I figured out what was the cause of the problem and now I can send and receive UDP packets.
The first thing I did was to activate the debug messages. About that, I had to manually define LWIP_DEBUG, as STM32CubeMX doesn't want to define it via the automatic generation.
I modified my code as this:
...
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/opt.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"
#include "lwip/ip4_addr.h"
#include "netif/etharp.h"
#include "ethernetif.h"
/* USER CODE END Includes */
...
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
extern struct netif gnetif;
extern ip4_addr_t ipaddr;
extern ip4_addr_t netmask;
extern ip4_addr_t gw;
extern uint8_t IP_ADDRESS[4];
extern uint8_t NETMASK_ADDRESS[4];
extern uint8_t GATEWAY_ADDRESS[4];
/* USER CODE END PV */
...
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 */
char str[] = "Hello UDP World!";
err_t err = 0;
ip_addr_t dstaddr;
ip_addr_t srcaddr;
struct eth_addr dstmac;
struct eth_addr srcmac;
IP4_ADDR(&dstaddr, 192, 168, 0, 2);
IP4_ADDR(&srcaddr, 192, 168, 0, 10);
struct udp_pcb * pcb;
struct pbuf * pb;
pcb = udp_new();
dstmac.addr[0] = 0x98;
dstmac.addr[1] = 0xDE;
dstmac.addr[2] = 0xD0;
dstmac.addr[3] = 0x01;
dstmac.addr[4] = 0x2C;
dstmac.addr[5] = 0x8A;
srcmac.addr[0] = 0x00;
srcmac.addr[1] = 0x80;
srcmac.addr[2] = 0xE1;
srcmac.addr[3] = 0x00;
srcmac.addr[4] = 0x00;
srcmac.addr[5] = 0x00;
etharp_add_static_entry(&dstaddr, &dstmac);
etharp_add_static_entry(&srcaddr, &srcmac);
err = udp_bind(pcb, &srcaddr, 55151);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
err = 0;
pb = pbuf_alloc(PBUF_TRANSPORT, sizeof(str), PBUF_RAM);
memcpy(pb->payload, str, sizeof(str));
err = udp_bind(pcb, &srcaddr, 55151);
err = udp_connect(pcb, &dstaddr, 55151);
err = udp_sendto(pcb, pb, &dstaddr, 55151);
MX_LWIP_Process();
udp_disconnect(pcb);
udp_remove(pcb);
pbuf_free(pb);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
...
As you can see, I attached the MAC addresses to source and remote IPv4 address structures. I also modified the allocation of the buffer by using RAM then a memcpy function to copy the string to the buffer payload.
Using Netcat, I changed my receive command by this one which works better as it is less ambiguous than the previous command: "$nc -u -s 192.168.0.2 -p 55151 192.168.0.10 55151" for the reception command and "$echo -e 'Hello\0' | nc -u4 -w 1 -s 192.168.0.2 -p 55151 192.168.0.10 55151" for the sending command.
Finally, the main error was to disconnect then to remove the udp_pcb before the call of MX_LWIP_Process() function. Thus, when the programm was trying to send UDP packets (or on other programs that try to receive UDP packets), the udp_pcb was unusable.
2021-06-21 02:11 AM
Heu @Community member ,
Glad to see that you resolved your issue and thanks for sharing the solution.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2021-07-17 08:26 AM
Static ARP entries and whatnot... The selected "solution" is not a solution and is beyond ridiculous!