I am evaluating FreeRTOS (v10.1.1) and +FAT (160919) on the Altera (Intel) Cyclone V SoC kit. I created a project based on the “blinky” sample, added +FAT from 160919_FreeRTOS_Labs, and created a rudimentary (e.g. no DMA) ff_sddisk.c based on the examples from the other boards.
The problem is, I can only get about 49KB/s file write/read speeds. My wish is to get 5MB/s or above. But 49 kilobytes seems just too slow, even with my basic driver. The card is Kingston 16GB SDHC w/ UFS-I logo, so I believe it should at least be capable of 10MB/s.
I was wondering if anyone has tried it on the Cyclone V. Any help would be appreciated.
When I switched to RAM disk, I can get 94MB/s on writes and 142MB/s on reads. So, I believe the FreeRTOS core and +FAT are decently configured and running OK.
For the low-level drivers, I’m using Altera HWLib (13.1?) that came with the Cyclone V blinky sample. But since the included alt_sdmmc wasn’t quite useable, I had to swap it with EDS version 18.0’s.
Hi Hideki, great that you’re working on FreeRTOS+FAT on the Altera/Intel Cyclone V SoC. There already is a driver for FreeRTOS+TCP, but not a driver for +FAT.
I don’t know much about the SD/MMC interface that you’re using. But what I do know is that if you pass large “aligned” blocks of data to the +FAT driver, they will be passed directly to the low-level driver.
The larger the blocks, the higher the transmission speeds will be.
With “aligned” I mean that you should write/read with multiples of 512 bytes (sector size).
How is your card reader connected? Is it using 1, 4 of 8 bits?
Did you check the clocks that are related to the interface?
Are you using a module called alt_sdmmc.c ?
Are you using functions like alt_sdmmc_write() and alt_sdmmc_read()?
What’s the value of the size parameter?
Hein
Regarding alignment. The file write/read test functions simply pass the whole data buffer directly to the ff_stdio functions. The buffer address is aligned and I use byte sizes of N x 1024. The calling code looks something like:
/* Allocate the file buffer at a high-enough address. */
pcFileBuffer = ( void * ) 0x10000000; // 256M
...
xWritten = ff_fwrite( pcFileBuffer, 1, xSize, xFp );
According to the dev board’s manual: “This 4-bit data interface can sustain burst read operations at up to 50 MHz for a throughput of 25 MBps.”
I will check the clock and other settings today.
I am using alt_sdmmc.c, but the one from HWLib 18.0 because the one under the CORTEX_A9_Cyclone_V_SoC_DK demo lacked basic features like getting the max sectors, which is needed for initializing FF_Disk.
I do use alt_sdmmc_read() and alt_sdmmc_write(). I think that’s all they have for general read/write. I pass ulSectorCount x 512 for the size. Here’s what I use in prvFFWrite():
Good news, I got it working! I was able to achieve 6.9MB/s and 7.9MB/s on writes and reads, respectively. I am happy with these numbers.
As you mentioned checking the clock values, I dumped all card related values and saw these:
SD/MMC clock freq = 200MHz.
clock divider = 62.
card speed = 403225 (speed = 200^6 / 4 x 2 x clk_div).
card bus width = 1 (bit).
Apparently, the above settings are necessary for the card discovery during POR. But now the 49 kilobytes/s can be explained. Dividing the above speed by 8 bits gives you ~50KB/s.
I revisted the API document to see if I overlooked anything and found these functions, alt_sdmmc_card_speed_set() and alt_sdmmc_card_bus_width_set(). Calling them with 25Mbps and 4-bit width enabled the 6.9 & 7.9MB/s speeds. I also tried a value above 25Mbps, which, according to the code, switches to the high-speed (50MHz ) mode. But it didn’t make it any faster. I wonder if that is limited by the SD card itself.
To answer your questions, FF_SDDiskFormat() got 64 sectors/cluster. alt_sdmmc uses multiple block read/write.
Bad news is, alt_sdmmc only supports SD storage devices:( It was on the top page of the HWLib SD/MMC document… What I will eventually need for the production is eMMC interface. So, now I have a new, bigger problem. Not sure what to do now.