AnsweredAssumed Answered

Ethernet+sdcard transfer speed problem on stm32f407

Question asked by Elsayed.Amr on Aug 25, 2015
Latest reply on Aug 26, 2015 by Elsayed.Amr
Hi I am building FTP server on stm32f4DIS-BB + stm32f407-discovery
I am using lwip ,and I am facing transfer speed issue.

I get max upload speed about 165KB/s.

this speed demonstrates two speeds 
(Ethernet + SD card writing speed)

if I removed writing to sd card from code , i.e 
only receving data from Ethernet and dropping it 
then the speed reach 300KB/s which demonstrate only 
the ethernet data transfer speed, is that speed is normal ?
how to improve it ? 

My Question is why my upload transfer is slow is that because of the 
sd card or the ethernet  ? 

I tried several ports for the sd card fafs driver , but same speed , 
previously the speed was only 125KB/s when I maximized sdclk to 48MHZ,
this improve the speed to 165KB/s. 

For the ethernet, can I improve it's speed , I notice that my board receive 1460 byte at 
a time which is the size of the TCP_MSS, I don't know if I can modify it 
but I think it's a standard value , I tried to increase the size of the pbuf pool 
and the pbuf itself , but still same speed , and only i receive 1460 BYTE at a time. 

I am sharing the code of receiving data and writing it to the sd card :

static err_t ftpd_datarecv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
     struct ftpd_datastate *fsd = arg;

     if (err == ERR_OK && p != NULL) {
          struct pbuf *q;
          u16_t tot_len = 0;

          for (q = p; q != NULL; q = q->next) {
               int len;
               len = vfs_write(q->payload, 1, q->len, fsd->vfs_file);
               tot_len += len;
               if (len != q->len)
          /* Inform TCP that we have taken the data. */
          tcp_recved(pcb, tot_len);

     if (err == ERR_OK && p == NULL) {
          struct ftpd_msgstate *fsm;
          struct tcp_pcb *msgpcb;

          fsm = fsd->msgfs;
          msgpcb = fsd->msgpcb;
          fsd->vfs_file = NULL;
          ftpd_dataclose(pcb, fsd);
          fsm->datapcb = NULL;
          fsm->datafs = NULL;
          fsm->state = FTPD_IDLE;
          send_msg(msgpcb, fsm, msg226);

     return ERR_OK;

can I do any modification on reception so that I can maximize the speed. 

Note that I get a higher download speed that reach 700KB/s which is wierd for me , why the upload is different than the download 

I will also share my clock settings as I tried to change them : 

#define PLL_M      8
#define PLL_N      336

#define PLL_P      2

/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      7

#define PLLI2S_N   192
#define PLLI2S_R   5

also for the sd card transfer speed :

#define SDIO_INIT_CLK_DIV                ((uint8_t)0x76)
  * @brief  SDIO Data Transfer Frequency (25MHz max) 
#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x0) 

also part of my lwipopt.h 

/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
   sends a lot of data out of ROM (or other static memory), this
   should be set high. */
#define MEMP_NUM_PBUF           60
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
   per active UDP "connection". */
#define MEMP_NUM_UDP_PCB        1
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
   connections. */
#define MEMP_NUM_TCP_PCB        10
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
   connections. */
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
   segments. */
#define MEMP_NUM_TCP_SEG        12
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
   timeouts. */

/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE         10

/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE       512
//#define PBUF_POOL_BUFSIZE       1024

/* ---------- TCP options ---------- */
#define LWIP_TCP                1
#define TCP_TTL                 255

/* Controls if TCP should queue segments that arrive out of
   order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ         0

/* TCP Maximum segment size. */
#define TCP_MSS                 (1500 - 40)       /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */

/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF             (4*TCP_MSS)

/*  TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
  as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */


/* TCP receive window. */
#define TCP_WND                 (2*TCP_MSS)

finally my stack and heap size :

Stack_Size      EQU     0x00000400

Stack_Mem       SPACE   Stack_Size

; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00015690

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
Heap_Mem        SPACE   Heap_Size