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)
                    break;
          }
          /* Inform TCP that we have taken the data. */
          tcp_recved(pcb, tot_len);


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


          fsm = fsd->msgfs;
          msgpcb = fsd->msgpcb;
          vfs_close(fsd->vfs_file);
          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


/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2


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


/* PLLI2S_VCO = (HSE_VALUE Or HSI_VALUE / PLL_M) * PLLI2S_N
   I2SCLK = PLLI2S_VCO / PLLI2S_R */
#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. */
#define MEMP_NUM_TCP_PCB_LISTEN 6
/* 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. */
#define MEMP_NUM_SYS_TIMEOUT    3




/* ---------- 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. */


#define TCP_SND_QUEUELEN        (2* TCP_SND_BUF/TCP_MSS)


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


finally my stack and heap size :

Stack_Size      EQU     0x00000400


                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp




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


Heap_Size       EQU     0x00015690


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


Outcomes