Nucleo not receiving UDP messages

17 Jul 2019

I'm currently working on a project that involves sending Open Sound Control (OSC) data over UDP to a STM32 Nucleo F767ZI board. I was running into issues with messages not arriving at the Nucleo, so I created a test program to print a serial message every time a UDP packet arrives at the Nucleo. I also created a Python script to send messages from my computer to the Nucleo.

The script is sending 100 packets, one every 0.01 seconds. Each packet contains 592 bytes (634 bytes on the wire when including ethernet and IP headers). This comes out to a rate of 507200 bits/second.

I can verify that all of the packets are being sent using Wireshark, and that the timing and packet size are correct.

The problem is that the Nucleo only reports receiving 47 of the 100 packets. I have tried increasing and decreasing the packet size as well as increasing and decreasing the number of packets sent per second. The Nucleo is still only receiving 50 packets per second.

Is this a bug with the mbed ethernet interface? A hardware problem with the F767ZI? If not, what could I try to make the Nucleo receive data at higher rates than I'm seeing right now?

Nucleo Code

#include <mbed.h>
#include "Thread.h"
#include "EthernetInterface.h"

/* ---------------------------------------------------------------------------------------- */

#define PORT 8001
//#define VERBOSE 0

typedef char byte;

/* ---------------------------------------------------------------------------------------- */

enum {
	OSC_SIZE_ADDRESS = 64,
	OSC_SIZE_FORMAT = 16,
	OSC_SIZE_DATA = 512
};

typedef struct {
	char address[OSC_SIZE_ADDRESS];			// The OSC address indicating where to dispatch
	char format[OSC_SIZE_FORMAT];			// Format specifier for the contained byte array
	byte data[OSC_SIZE_DATA]; 				// The byte array containing the data
	int data_size;							// The size of the data array
} OSCMessage;

/* ---------------------------------------------------------------------------------------- */

void onUDPSocketEvent(void* buffer, size_t size, int count) {
  printf("UDP event detected %d\n", count);     
}

void udp_main() {
  int count = 0;
  // Open Ethernet connection
  EthernetInterface eth;   
  eth.set_network("192.168.2.200","255.255.255.0","192.168.2.1");                       
  eth.connect();

  // Create an UDP socket for listening to the broadcast
  UDPSocket s;
  s.open(&eth);
  s.bind(PORT);

  //printf("Socket Open\r\n");

  void* recvBuffer = malloc(sizeof(OSCMessage*));

  printf("Ready\r\n");

  while (1) {
    // this blocks until next packet comes in
    nsapi_size_or_error_t size = s.recvfrom(NULL, recvBuffer, sizeof(OSCMessage));
    if (size > 0) {
      count++;
      onUDPSocketEvent(recvBuffer, size, count);
    }
  }
}

/* ---------------------------------------------------------------------------------------- */

int main() {
  
  Thread t;
  t.start(&udp_main);

  while (1) {
    wait(osWaitForever);
  }
}

Python Script

#!/bin/python3

import socket
import time
import random
import string

def randomString(len):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(len))

numPackets = 100
packetLen = 592

IPADDR = '192.168.2.200'
PORTNUM = 8001

PACKETDATA = randomString(packetLen)


s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)

s.connect((IPADDR, PORTNUM))


for i in range(numPackets):
	s.send(bytes(PACKETDATA,'utf-8'))
	print(i+1)
	time.sleep(1/numPackets);

s.close()


print("Sent " + str(numPackets) + " packets")
print(str(packetLen) + " bytes each (" + str(packetLen+42) + " bytes on the wire)")
print("Sent every " + str(1/numPackets) + "  seconds")
print(str(numPackets*(packetLen+42)*8) + " bits/second")