A PicoTCP demo app testing the ethernet throughput on the lpc1768 mbed board.

Dependencies:   PicoTCP lpc1768-picotcp-eth mbed-rtos mbed picotcp-demo-printf

This is a demo application, using the PicoTCP socket API, to show the performance of a TCP sender towards an endpoint connected via Ethernet.

This application runs on the NXP LPC1768 mbed board.

This demo should give you following output on the mbed lpc1768's serial port:

>>> Welcome 2 PicoTCP <<<
ip=192.168.100.1 - will connect to 192.168.100.2:4404 in 5 seconds...
PicoTCP Benchmark starting...
Opening socket...
tb> Connection established with server.
tb> TCPSIZ written
tb> Called shutdown()
tb> Transmitted 10485760 bytes in 6704 milliseconds
tb> average write throughput 12512 kbit/sec
tb> Socket closed. Exit normally. 

On the receiving side (e.g. linux computer) you could receive the packets sent by PicoTCP with netcat - e.g.:

ifconfig eth0 192.168.100.2
nc -l -p 4404 > /dev/null

main.cpp

Committer:
daniele
Date:
2013-05-17
Revision:
1:83d13ed71a38
Parent:
0:b3aca3c27ab6

File content as of revision 1:83d13ed71a38:

/******************************************************************************
PicoTCP. Copyright (c) 2012-2013 TASS Belgium NV. Some rights reserved.
See LICENSE and COPYING for usage. https://github.com/tass-belgium/picotcp

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License Version 2
as published by the Free Software Foundation;

Authors: Maxime Vincent

Purpose: This is a PicoTCP demo. It will try to connect a TCP socket at
         from 192.168.100.1 port 6666 to 192.168.100.2 port 4404
         and then send "TCPSIZ" a-characters there.
         When that succeeded, it prints the throughput on the serial output.

Libraries needed to get this up and running:
        PicoTCP, 
        lpc1768-picotcp-demo-eth,
        picotcp-demo-printf,
        mbed-rtos,
        mbed

******************************************************************************/

#include "mbed.h"

extern "C" {
// PicoTCP includes
#include "pico_dev_mbed_emac.h"
#include "pico_stack.h"
#include "pico_ipv4.h"
#include "pico_socket.h"
// CMSIS OS includes
#include "cmsis_os.h"
// other includes
#include "serial_api.h"
#include <stdio.h>
#include "printf.h"
}

// Send 10 MBs
#define TCPSIZ (10 * 1024 * 1024)

serial_t _serial;

DigitalOut myled1(LED1);    /* Tick */

void app_tcpbench(void);

void _putc(void *p, char ch)
{
    serial_putc(&_serial, ch);
}

int main() {
    struct pico_device *my_dev;
    struct pico_ip4 myaddr, mynetmask;
    
    // init serial output
    serial_init(&_serial, p9, p10);
    init_printf(NULL,_putc);
    mprintf(">>> Welcome 2 PicoTCP <<<\r\n");
    
    // init PicoTCP stack
    pico_stack_init();
    
    pico_string_to_ipv4("192.168.100.1", &myaddr.addr);
    pico_string_to_ipv4("255.255.255.0", &mynetmask.addr);
    my_dev = pico_emac_create("MBED-EMAC");
    
    pico_ipv4_link_add(my_dev, myaddr, mynetmask);
    
    mprintf("ip=192.168.100.1 - will connect to 192.168.100.2:4404 in 5 seconds...\r\n");
    osDelay(5000);
    mprintf("PicoTCP Benchmark starting...\r\n");
    app_tcpbench();
    
    // This is the IDLE task
    while(1) {
        static uint8_t led_tick;
        pico_stack_tick();
        //wait_ms(1); // wait a millisec...

        led_tick++;
        if (!(led_tick%200))
        {
            myled1 = !myled1;
            led_tick = 0;
        }
    }
}

/*** START TCP BENCH ***/

#define TCP_BENCH_TX  1
#define TCP_BENCH_RX  2

uint8_t  buffer0[2000]           __attribute__((section("AHBSRAM0"))); // To save some RAM

int tcpbench_mode = TCP_BENCH_TX;
struct pico_socket *tcpbench_sock = NULL;
static unsigned long tcpbench_time_start,tcpbench_time_end;

void cb_tcpbench(uint16_t ev, struct pico_socket *s)
{
  static int closed = 0;
  static unsigned long count = 0;

  static long tcpbench_wr_size = 0;
  long tcpbench_w = 0;
  double tcpbench_time = 0;
  unsigned int time_ms;

  count++;

  if (ev & PICO_SOCK_EV_RD) {
  }

  if (ev & PICO_SOCK_EV_CONN) { 
    if (tcpbench_mode == TCP_BENCH_TX)
      mprintf("tb> Connection established with server.\r\n");
  }

  if (ev & PICO_SOCK_EV_FIN) {
    mprintf("tb> Socket closed. Exit normally. \r\n");
  }

  if (ev & PICO_SOCK_EV_ERR) {
    mprintf("tb> Socket Error received: %s. Bailing out.\r\n", strerror(pico_err));
  }

  if (ev & PICO_SOCK_EV_CLOSE) {
    mprintf("tb> event close\r\n");
    pico_socket_close(s);
    return;
  }

  if (ev & PICO_SOCK_EV_WR) {
    
    if (tcpbench_wr_size < TCPSIZ && tcpbench_mode == TCP_BENCH_TX) {
      do {
        tcpbench_w = pico_socket_write(tcpbench_sock, buffer0, TCPSIZ-tcpbench_wr_size);
        if (tcpbench_w > 0) {
          tcpbench_wr_size += tcpbench_w;
          //mprintf("Written : %d \n",tcpbench_wr_size);
          //mprintf("tb> SOCKET WRITTEN - %d\r\n",tcpbench_w);
        }
        if (tcpbench_w < 0) {
          mprintf("tb> Socket Error received: %s. Bailing out.\r\n", strerror(pico_err));
          exit(5);
        }
        if (tcpbench_time_start == 0)
          tcpbench_time_start = PICO_TIME_MS();
      } while(tcpbench_w > 0);
      //mprintf("tcpbench_wr_size = %d      \r\n", tcpbench_wr_size);
    } else {
      if (!closed && tcpbench_mode == TCP_BENCH_TX) {
        tcpbench_time_end = PICO_TIME_MS();
        pico_socket_shutdown(s, PICO_SHUT_WR);
        mprintf("tb> TCPSIZ written\r\n");
        mprintf("tb> Called shutdown()\r\n");
        tcpbench_time = (tcpbench_time_end - tcpbench_time_start)/1000.0; /* get number of seconds */
        time_ms = (unsigned int)(tcpbench_time * 1000);
        mprintf("tb> Transmitted %u bytes in %u milliseconds\r\n",TCPSIZ, time_ms);
        mprintf("tb> average write throughput %u kbit/sec\r\n",( (TCPSIZ/time_ms) * 8) );
        closed = 1;
      }
    }
  }
}

void app_tcpbench(void)
{
  struct pico_socket *s;
  uint16_t port_be = short_be(4404);
  uint16_t local_port;
  struct pico_ip4 server_addr;
  struct pico_ip4 local_addr;
  memset(buffer0,'a',2000);
  tcpbench_mode = TCP_BENCH_TX;

  mprintf("Opening socket...\r\n");
  s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpbench);
  if (!s)
  {
    mprintf("Socket was not opened...\r\n");
    exit(1); 
  }
  
  local_port = short_be(6666);
  pico_string_to_ipv4("192.168.100.1", &local_addr.addr);
  pico_string_to_ipv4("192.168.100.2", &server_addr.addr);
  pico_socket_bind(s, &local_addr, &local_port);
  
  tcpbench_sock = s;
  pico_socket_connect(s, &server_addr, port_be);
  
  return;
}