本帖最后由 wowow 于 2015-4-22 17:13 编辑
前言:ST官方提供的STM32Cube大大减轻了开发的难度,不过bug还是有的。写下此文的目的一是感谢ST提供的开发包,二是为了提出自己发现问题期待改进,三是交流共同提高。时间有限,写得比较简略。
版本:CubeMX 4.7 + STM32Cube_FW_F4_V1.5.0生成的代码
配置:FreeRTOS + FatFS(SD卡) + FwIP + USB HID,其中FwIP和HID只做了初始化未使用。
本文主要记录要点和bug解决方案。要点:
1.STACK和HEAP大小
2.FatFS差一步f_mount()
3.多线程环境下读SD出现RX_OVERRUN Bug。
4.SD的DMA和中断相关设置
5.SDDMA中断服务程序中死锁的bug。
6读写性能
7疑问
1.用了文件系统STACK/HEAP和线程的STACK都要加大,否则会出溢出导致HardFault中断或其它奇怪的问题。具体要多大STACK待测,先弄大点。
2.FatFS+SD的使用:SD卡驱动已经跟一个盘绑定了,就差一步f_mount()就可以用了。基本的f_open,f_read, f_write例子很多不详叙。
3.Bug:反复读SD卡里的一个文件(360k大小)测试发现出错率很高(40%-60%,错了一定数量就一直是出错了)。关掉FwIP的线程就好很多(出错率0.1%-0.2%)。
最后发现SD_Read()调用的BSP_SD_ReadBlocks在多线程环境上会导致SD_RX_OVERRUN错误,需要将读写都改成DMA。
4 DMA设置:
中断设置:要开SDIO中断,缺省没开。
5死锁的bug:SD_DMA_RxCplt()一直在死等 while(hsd->SdTransferCplt == 0)
死锁原因:DMA的完成中断里死等SD完成的信号。此信号在SD中断里清除,而SD的中断跟DMA中断是同一优先级,无法抢占。
解决办法:
SD_DMA_RxCplt()里去掉 while(hsd->SdTransferCplt == 0)
SD_DMA_TxCplt()里去掉while(hsd->SdTransferCplt ==0)
为这点事调整中断优先级没必要。而且在中断里死等另一个信号这种写法本来就不可取。
6. 读写性能(主频168M,SD时钟48M分频到24M)
读速度测试,文件大小368,011,FreeRTOS无其它线程,DMA
一次读大小
| 测试次数
| 平均时间(ms)
| 最大时间
| 平均速度
| 512
| 231
| 326
| 327
| 1,128,868
| 1024
| 302
| 200
| 201
| 1,840,055
| 2048
| 2005
| 121
| 122
| 3,041,413
| 读写速度测试,文件大小368,011,FreeRTOS无其它线程,DMA
一次读写大小
| 测试次数
| 平均时间(ms)
| 最小时间
| 最大时间
| 平均速度
| 512
| 339
| 1871
| 未测
| 3351
| 393,384
| 512
| 246
| 1636
| 1353
| 3342
| 449,892
| 1024
| 254
| 1176
| 898
| 2846
| 625,870
| 2048
| 378
| 771
| 516
| 2460
| 954,633
| 看着最大时间和平均时间都有些高,实际JScope采集到的波形是这样的:(512第二次)
对比用USB读卡器在PC上测的结果:
读的速度512好一些,1024差一点,2k差了近25%。
写的速度差得太多。
7.疑问
1)DMA完成后 NDRT=FF7F或FF80,负数?但比较读写完生成的文件内容是对的。
2)SD 接收有128字节的FIFO,怎么这么容易就OVERRUN了?
3)SD读写的瓶颈在哪里?
|