Working on an embedded system using Ethernet interface, one day you may need to know about the performance of your system.
They are plenty tools which are able to run a data transfer test, but the most popular software is for sure Iperf. Iperf accepts a lot of parameters which allows you to run flexible tests of a target.
One stm32f107 – embedded device I’ve developed, was running widely used TCP/IP Stack: LwIP. To test the performance on the end of the day I wrote this code which is listening on TCP Port 5001, receive the data and sending back:
iperf.c
#include "iperf.h" #include "lwip/opt.h" #include "lwip/tcp.h" static err_t iperf_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { LWIP_UNUSED_ARG(arg); if (err == ERR_OK && p != NULL) { tcp_recved(pcb, p->tot_len); pbuf_free(p); } else if (err != ERR_OK && p != NULL) { pbuf_free(p); } if (err == ERR_OK && p == NULL) { tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); tcp_close(pcb); } return ERR_OK; } static err_t iperf_accept(void *arg, struct tcp_pcb *pcb, err_t err) { LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, iperf_recv); return ERR_OK; } void iperf_init(void) { struct tcp_pcb *pcb; pcb = tcp_new(); tcp_bind(pcb, IP_ADDR_ANY, 5001); // bind to iperf port pcb = tcp_listen(pcb); tcp_accept(pcb, iperf_accept); }
iperf.h
#ifndef __IPERF_H__ #define __IPERF_H__ void iperf_init(void); #endif /* __IPERF_H__ */
In Project main.c just include the iperf.h file and initialize the iperf to listen for TCP packets.
iperf_init();
My STM32F107 achieved 66MBit/s which is a good number for a microcontroller.
This only works with iperf2 as iperf3 uses controll channel too. So the command for test on PC side is:
iperf2 -c server_ip_address
hello,
i am confused that how should i achieve the reuslt, it would be grateful if you can tell the complete procedure
thanks
Raza, about which result are you talking? When you mean the bandwidth, it depends how your firmware is realized, which PHY you use and how do you access your PHY. DMA access makes it also faster and bigger buffer size reserved for LwIP are also a good point.
Artur.f thankfor reply , i have established a test setup, now i have a connection between infineon XMC4700 and my computer i am runing server on microcontroller and also performing dual test, now is the reading which i am achieving while communication between microcontroller and computer represent bandwidth of my LWIP stack ?, how to check the bandwidth of LWIP stack which i have implemted of microcontroller?
please reply
Thanks
When I did understood exactly, yes the test you made is representing the throughput to your uC. Since the uC is acting as a server, it says how many data you uC is able to receive within a second. If you want to perform a test from uC to Computer, you will need to implement an iperf client for LWIP Stack. I think it’s not necessary because the test in one direction is sufficient to check the throughput/bandwidth.
Thanks Once again you cleared alot, and i have performed also bidirectional test with option “-r” , the one in which my Computer act as a server does it mean that its the bandwidth of Computer or it is also related to uc somehow ? can you clear that too.. please?
I also want to measure sending throughput of uC
hey thanks for the great working iperf server!
I found a bug in iperf_recv( ):
if (err == ERR_OK && p != NULL) {
tcp_recved(pcb, p->tot_len);
pbuf_free(p);
} else {
pbuf_free(p); // THIS LINE IS CRITICAL
}
However if p == NULL pbuf_free() will be called on a non existing pbuf! Wich is leading to an assert in lwip pbuf_api.
Sven
Hi Sven, thank you. Fixed it…