cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet+sdcard transfer speed problem on stm32f407

Amr Elsayed
Associate II
Posted on August 25, 2015 at 19:49

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 : 

 

&sharpdefine PLL_M      8

&sharpdefine PLL_N      336

/* SYSCLK = PLL_VCO / PLL_P */

&sharpdefine PLL_P      2

/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */

&sharpdefine PLL_Q      7

/* PLLI2S_VCO = (HSE_VALUE Or HSI_VALUE / PLL_M) * PLLI2S_N

   I2SCLK = PLLI2S_VCO / PLLI2S_R */

&sharpdefine PLLI2S_N   192

&sharpdefine PLLI2S_R   5

also for the sd card transfer speed :

 

&sharpdefine SDIO_INIT_CLK_DIV                ((uint8_t)0x76)

/** 

  * @brief  SDIO Data Transfer Frequency (25MHz max) 

  */

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

&sharpdefine MEMP_NUM_PBUF           60

/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One

   per active UDP ''connection''. */

&sharpdefine MEMP_NUM_UDP_PCB        1

/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP

   connections. */

&sharpdefine MEMP_NUM_TCP_PCB        10

/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP

   connections. */

&sharpdefine MEMP_NUM_TCP_PCB_LISTEN 6

/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP

   segments. */

&sharpdefine MEMP_NUM_TCP_SEG        12

/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active

   timeouts. */

&sharpdefine MEMP_NUM_SYS_TIMEOUT    3

/* ---------- Pbuf options ---------- */

/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */

&sharpdefine PBUF_POOL_SIZE         10

/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */

&sharpdefine PBUF_POOL_BUFSIZE       512

//&sharpdefine PBUF_POOL_BUFSIZE       1024

/* ---------- TCP options ---------- */

&sharpdefine LWIP_TCP                1

&sharpdefine TCP_TTL                 255

/* Controls if TCP should queue segments that arrive out of

   order. Define to 0 if your device is low on memory. */

&sharpdefine TCP_QUEUE_OOSEQ         0

/* TCP Maximum segment size. */

&sharpdefine TCP_MSS                 (1500 - 40)  /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */

/* TCP sender buffer space (bytes). */

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

&sharpdefine TCP_SND_QUEUELEN        (2* TCP_SND_BUF/TCP_MSS)

/* TCP receive window. */

&sharpdefine 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

#ethernet #sdcard #stm32f
2 REPLIES 2
Posted on August 25, 2015 at 21:36

It's not hard to benchmark SDIO speed independently. Writing is significantly slower then reading, because erasing/writing NAND is slow. The card hides a lot of the ugliness, but the underlying NAND probably has 128KB page sizes, and you need to consider this so your code uses it efficiently.

SDIO+FATFS is going to be slow if you use small unaligned blocks. Try to read/write at least 8KB. The sweet-spot is likely to be closer to 32KB. Consider using buffering schemes that get you to larger sizes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Amr Elsayed
Associate II
Posted on August 26, 2015 at 14:47

Thank you Clive , It works , I copied the data from pbuf pools 

to a larger buffer 32kB and wrote it once to the SD card , 

Now I reach 1.6 MB/s. 

I think I wasted alot of memory , I was trying to expand pbuf buffers instead of copying 

data to another buffer but I Failed ,as they are small buffers connected on a chain and I can only 

take 1460 byte at a time from Ethernet then I have to free the pbuf buffer before taking more data,

Do you have a solution ?