[转]stm32 sdio写入速度 SD卡【好文章】[F1开发板通用] 战舰STM32F103开发板 SDIO写入速度测试(使用FATFS)

http://www.openedv.com/forum.php?mod=viewthread&tid=94284


http://www.openedv.com/forum.php?mod=viewthread&tid=94284

http://www.openedv.com/forum.php?mod=viewthread&tid=94284


有客户反馈,战舰STM32F103的SDIO写入速度很慢。最快才150多KB/S。果断是有问题才对,于是乎,写了一个测试代码,来研究下写入速度到底有多慢。
测试条件如下:
1,使用我们在售的SD卡(速度等级:Class4)
2,使用战舰STM32F103开发板
3,使用内部定时器,对固定大小的文件进行写入,然后计算速度。
4,需要在SD卡里面,新建一个TEXT文件夹。

测试核心代码如下:
[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#define FATFS_WR_SIZE     1024
#define FATFS_WR_CYCLE   8192
 
extern u32 wrtime; //1s计时单位
int main( void )
{               
         FIL* f_txt;       
         u8 key,res;
         u16 i;
         u8 *p;
          u8 *pname;                                        //带路径的文件名
         u8 *wbuffer;                                //写入缓冲
         u16 wt;
         
         Stm32_Clock_Init(9);                //系统时钟设置
         uart_init(72,115200);                //串口初始化为115200
         delay_init(72);                                    //延时初始化 
          usmart_dev.init(72);                //初始化USMART               
         TIM6_Int_Init(10000,7199);        //10Khz计数频率,1s中断一次
          LED_Init();                                          //初始化与LED连接的硬件接口
         KEY_Init();                                        //初始化按键
         LCD_Init();                                           //初始化LCD  
         W25QXX_Init();                                //初始化W25Q128
          my_mem_init(SRAMIN);                //初始化内部内存池
         exfuns_init();                                //为fatfs相关变量申请内存 
          f_mount(fs[0], "0:" ,1);                 //挂载SD卡
          f_mount(fs[1], "1:" ,1);                 //挂载FLASH.
         font_init();
          while (SD_Init())                        //检测不到SD卡
         {
                 LCD_ShowString(30,150,200,16,16, "SD Card Error!" );
                 delay_ms(500);                                       
                 LCD_ShowString(30,150,200,16,16, "Please Check! " );
                 delay_ms(500);
                 LED0=!LED0;                                //DS0闪烁
         }
         p=mymalloc(SRAMIN,50);                            
         pname=mymalloc(SRAMIN,30);        //为带路径的文件名分配30个字节的内存                   
         f_txt=(FIL *)mymalloc(SRAMIN, sizeof (FIL));        //开辟FIL字节的内存区域
         wbuffer=mymalloc(SRAMIN,FATFS_WR_SIZE);                //申请写入大小
         
         for (i=0;i<FATFS_WR_SIZE;i+=8)
         {
                 wbuffer[i]= 'T' ;
                 wbuffer[i+1]= 'e' ;
                 wbuffer[i+2]= 's' ;
                 wbuffer[i+3]= 't' ;
                 wbuffer[i+4]= '!' ;
                 wbuffer[i+5]= '!' ;
                 wbuffer[i+6]= '!' ;
                 wbuffer[i+7]= ' ' ;
         }
         LCD_Clear(WHITE);                           //清屏
         POINT_COLOR=RED;                        //设置字体为红色          
         Show_Str(30,50,200,16, "战舰STM32F103开发板" ,16,0);                                            
         Show_Str(30,70,200,16, "SDIO写入速度测试" ,16,0);                                            
         Show_Str(30,90,200,16, "KEY0:开始测试" ,16,0);       
         
         sprintf (( char *)p, "文件大小:%dKB" ,FATFS_WR_CYCLE*FATFS_WR_SIZE/1024);
         Show_Str(30,120,200,16,p,16,0);                                     
         POINT_COLOR=BLUE;                        
         while (1)
         {
                 key=KEY_Scan(0);
                 if (key==KEY0_PRES)
                 {
                         Show_Str(30,140,200,16, "写入耗时:           " ,16,0);
                         Show_Str(30,160,200,16, "平均速度:           " ,16,0);           
                         text_new_pathname(pname);                        //得到文件名       
                         TIM6->CNT=0;
                         wrtime=0;
                         wt=0;
                         res=f_open(f_txt,( const TCHAR *)pname,FA_WRITE|FA_CREATE_NEW); //模式0,或者尝试打开 
                         if (res==0) //打开成功.
                         {
                                 for (i=0;i<FATFS_WR_CYCLE;i++)
                                 {
                                         res=f_write(f_txt,wbuffer,FATFS_WR_SIZE,&bw); //写入BMP首部 
                                         if (res) break ;
                                         if (wt!=wrtime)
                                         {
                                                 wt=wrtime;
                                                 LCD_ShowNum(30+80,140,wt,3,16);
                                         }
                                 }
                         }
                         if (res==0)
                         {
                                 wt=FATFS_WR_CYCLE*FATFS_WR_SIZE/1024/wrtime;
                                 sprintf (( char *)p, "平均速度:%dKB/s" ,wt);
                                 Show_Str(30,160,200,16,p,16,0); 
                         } else printf ( "失败" );
                         f_close(f_txt);
                 }
                 delay_ms(10);
         }
}


此代码里面,通过修改:
#define FATFS_WR_SIZE         1024
#define FATFS_WR_CYCLE       8192
这两个宏,就可以控制写入文件大小( FATFS_WR_SIZE*FATFS_WR_CYCLE)和FATFS单次写入块大小(FATFS_WR_SIZE)


我们将文件大小固定为8192KB,8M字节(FATFS_WR_SIZE*FATFS_WR_CYCLE=8M字节)。
首先,我们设定单次写入块大小为1024字节,此时测试结果如下:
 
然后,我们设定单次写入块大小为2048字节,此时测试结果如下:
 

然后,我们设定单次写入块大小为4096字节,此时测试结果如下:
 

然后,我们设定单次写入块大小为8192字节,此时测试结果如下:
 

然后,我们设定单次写入块大小为16384字节,此时测试结果如下:
 
最后,来个猛的,我们设定单次写入块大小为32768字节(写入32M字节),此时测试结果如下:
 



可以看出,单次写入块越大,写入速度越快。
当写入块大小,到16KB的时候,速度可以达到4MB/S,基本到极限了。最后用32KB的写入块,速度也就4.6MB/S,提升不明显。

4MB的写入速度,一般应用应该都是足够了。
所以你的写入速度慢的时候,改大一下写入块,可以获得非常明显的提升。
 STM32F103 SDIO写入速度测试代码.rar (1.55 MB, 下载次数: 1564) 

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
微信公众平台:正点原子    点击扫码添加
 
   

  离线 

8

主题

750

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1970
金钱
1970
注册时间
2011-5-23
在线时间
873 小时
2#
  发表于 2017-2-14 12:04:01  |  只看该作者
本帖最后由 aozima 于 2017-2-14 12:06 编辑

碎片化的文件写入,除了大块外,做一下对齐也会好很多,比如当前文件大小为511字节,写1字节或513字节,就能对齐。
考虑到现在的大容量NAND,对齐到4K去可能会更好。

考虑到性能和写入的及时性,可以使用队列,在写入中对队列做拼接和对齐。
这样写入的实时性和总的写入速度都能得到保障。
在硬件设计能保证性能的情况下,轻松上C10的卡
 
   

  离线 

489

主题

9万

帖子

30

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
124871
金钱
124871
注册时间
2010-12-1
在线时间
1052 小时
3#
  楼主 |  发表于 2017-2-14 16:29:40  |  只看该作者
aozima 发表于 2017-2-14 12:04
碎片化的文件写入,除了大块外,做一下对齐也会好很多,比如当前文件大小为511字节,写1字节或513字节,就 ...

你们要多快的速度啊?
另外,airplay,搞定没有?什么时候搞个样品给我试试。

猜你喜欢

转载自blog.csdn.net/unsv29/article/details/80056925