SD卡文件读写
SD卡文件讀寫
象棋小子??? 1048272975
SD卡(Secure Digital Memory Card)具有體積小、容量大、數(shù)據(jù)傳輸快、可插拔、安全性好等優(yōu)點,被廣泛應(yīng)用于便攜式設(shè)備上。例如作為數(shù)碼相機(jī)的存儲卡,作為手機(jī)、平板多媒體擴(kuò)展卡用的TF卡(micro sd)等等。
1. SD卡概述
SD卡技術(shù)是在MMC卡的基礎(chǔ)上發(fā)展起來的,其尺寸與MMC卡一樣,只是比MMC卡厚了0.7mm,因此SD主機(jī)可以識別并存取MMC卡。SD卡接口除了保留MMC卡的7針外,還在兩邊加了2針,作為數(shù)據(jù)線,目的是通過把傳輸方式由串行變成并行,以提高傳輸速率。此時的規(guī)范為SD1.0版本,最高容量只能到4GB。為了跟進(jìn)產(chǎn)品的更新?lián)Q代,SD聯(lián)合協(xié)會在06年發(fā)布了容量更大、存儲更快的下一代SD卡規(guī)范SD2.0。該規(guī)范重新定義了SD卡的速度等級,分為三檔:Class 2、4、6,分別對應(yīng)寫入速度2MB/S、4MB/S、6MB/S。根據(jù)卡容量又分為標(biāo)準(zhǔn)卡(小于2GB)和高容量卡(2GB~32GB),目前市面上應(yīng)用的SD卡絕大部分都是SD2.0版本的卡。為了讓儲存卡更加迷你,通過SD卡規(guī)范標(biāo)準(zhǔn),又衍生了MiniSD卡和Micro SD卡,這些卡均比標(biāo)準(zhǔn)SD卡尺寸小,通過SD轉(zhuǎn)接套可以當(dāng)作一般的SD卡使用。尤其是Micro SD卡,可以算是最小的存儲卡了,超小的體積可以極大的節(jié)省消費電子產(chǎn)品內(nèi)部設(shè)計的空間,基本目前的Android手機(jī)均是選用Micro SD卡作為多媒體擴(kuò)展儲存卡。隨著科技的進(jìn)步,SD2.0規(guī)范SD卡也漸漸無法滿足應(yīng)用的需求,在10年SD聯(lián)合協(xié)會又發(fā)布了新的SD3.0規(guī)范,該規(guī)范定義了sdxc和uhs,并增加了Class10,容量范圍為32GB~2TB。在sdxc卡仍需進(jìn)一步坐等其價格下降的情況下,SD4.0規(guī)范已經(jīng)開始在緊張的制訂中,這已超出本文的討論范圍內(nèi)了。
2. SD卡驅(qū)動
SD卡共支持三種傳輸模式:SPI模式、1位SD模式、4位SD模式。所有的SD卡都必須支持較老的SPI/MMC模式,這個模式支持慢速的四線SPI接口,使很多微控制器都可以通過SPI或模擬SPI接口來讀寫SD卡。萬利的LPC5411x開發(fā)板通過SPI接口擴(kuò)展了一個TF卡槽,可以用SPI接口讀寫TF卡。
SD2.0標(biāo)準(zhǔn)定義了物理層相關(guān)規(guī)范以及主機(jī)控制器規(guī)范,SD卡驅(qū)動的編寫必須參考這兩個規(guī)范,遵循標(biāo)準(zhǔn)的SD卡均可以采用統(tǒng)一的軟件驅(qū)動實現(xiàn)數(shù)據(jù)訪問。NXP對于其全系列的芯片提供了sdmmc庫中間件用于支持SD/MMC卡的讀寫,可以在官網(wǎng)下載相應(yīng)的BSP,里面包含sdmmc庫,fsl_sdspi.h/fsl_sdspi.c即為SPI模式訪問SD卡的標(biāo)準(zhǔn)驅(qū)動,可以直接應(yīng)用到LPC5411x開發(fā)環(huán)境中。SD卡驅(qū)動最主要實現(xiàn)三個接口,分別是SD卡的識別初始化、SD卡的塊讀、SD卡的塊寫,具體實現(xiàn)可以參考fsl_sdspi.h/fsl_sdspi.c驅(qū)動文件。
3. Fatfs
數(shù)據(jù)往往以文件的形式保存在儲存設(shè)備中,對于SD卡,一般采用的是Fat32文件系統(tǒng),Fatfs由于其開源免費,支持Fat32,受到了廣泛的應(yīng)用。
Fatfs是由日本工程師ChaN所編寫的Fat文件系統(tǒng)模塊,從06年發(fā)布第一個Fatfs版本開始,作者就從未停止維護(hù)和更新。Fatfs的編寫遵循ANSI C,并且完全與磁盤I/O層分開。它不依賴于硬件架構(gòu),代碼和工作區(qū)占用空間小,使之可以嵌入到各個低成本的微控制器中,如AVR、8051、PIC、ARM、Z80、68K等。由于SD卡一般使用Fat32文件系統(tǒng),在使用到SD卡的系統(tǒng)中移植Fatfs,將很好地實現(xiàn)對SD卡文件的管理。
Fatfs模塊完全獨立于磁盤I/O層,因此底層磁盤I/O訪問并不屬于Fatfs的模塊部分,用戶必須自己實現(xiàn)這部分用來訪問存儲設(shè)備。通常在diskio.c中實現(xiàn)這幾個函數(shù)disk_initialize()、disk_status()、disk_read()、disk_wirte()、disk_ioctl()即可,如果使能了OS相關(guān)的特性,則還需額外實現(xiàn)進(jìn)程/內(nèi)存函數(shù)。其中disk_initialize()對應(yīng)SD卡驅(qū)動中的卡識別初始化接口,disk_read()對應(yīng)SD卡的塊讀接口,disk_wirte()對應(yīng)SD卡的塊寫接口。NXP對于其全系列的芯片提供了Fatfs中間件的支持,Fatfs對應(yīng)SD卡驅(qū)動接口的具體實現(xiàn)可以參考BSP中已移植好的Fatfs中間件。
4. 讀寫測試
移植好SD卡驅(qū)動以及Fatfs底層對應(yīng)接口后,就可以用Fatfs應(yīng)用編程接口讀寫SD卡里面的文件。應(yīng)用以2KB大小為讀寫單位,測試讀寫10MB大小文件的平均讀寫速度。
uint8_t TestBuffer[2048];
int main()
{
uint32_t i;
FATFS fs;
FIL file;
FRESULT Res;?????
uint32_t TimeCount;
uint32_t ByteWrite, ByteRead;
?
?/* Board pin, clock, debug console init */
?/*attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
/* enable clock for GPIO*/
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
?
BOARD_InitPins();
BOARD_BootClockFROHF96M();
BOARD_InitDebugConsole();????
?
Gpio_Init();
?
f_mount(&fs, "4:" , 0);??????
/*
Res = f_mkfs("", 0, 4096);
if (Res != RES_OK) {
?????? PRINTF("f_mkfs error %d\r\n",Res);
?????? while(1);
}
*/
PRINTF("Writing test.bin, file sise10MB\r\n");
?Res= f_open(&file, "4:test.bin", FA_WRITE | FA_CREATE_ALWAYS);
if (Res != RES_OK) {
?????? PRINTF("Createfile failed\r\n");
?????? while(1){
????????????? GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
????????????? Delay_ms(300);????????????????
?????? }
}
for (i=0; i<sizeof(TestBuffer); i++){
?????? TestBuffer[i]= i;
}
TimeCount =timer_get_current_milliseconds();
for (i=0;i<10*1024*1024/sizeof(TestBuffer); i++) {
?????? Res= f_write(&file, &TestBuffer, sizeof(TestBuffer), &ByteWrite);
?????? if(Res != RES_OK) {
????????????? f_close(&file);
????????????? PRINTF("Writefile error\r\n");
????????????? while(1){
???????????????????? GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
???????????????????? Delay_ms(300);
????????????? }
?????? }
}
f_close(&file);
PRINTF("Sd write speed %dKB/s\r\n", 10*1024*1024/(timer_get_current_milliseconds()-TimeCount));
??????
PRINTF("Reading test.bin, file sise10MB\r\n");
Res =?f_open(&file, "4:test.bin", FA_READ | FA_OPEN_EXISTING);
if (Res != RES_OK) {
?????? PRINTF("Openfile failed\r\n");
?????? while(1){
????????????? GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
????????????? Delay_ms(300);
?????? }
}
TimeCount =timer_get_current_milliseconds();
for (i=0;i<10*1024*1024/sizeof(TestBuffer); i++) {
?????? Res= f_read(&file, (unsigned char *)&TestBuffer, sizeof(TestBuffer),&ByteRead);
?????? if(Res != RES_OK) {
????????????? f_close(&file);
????????????? PRINTF("Readfile error\r\n");
????????????? while(1){
???????????????????? GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
???????????????????? Delay_ms(300);
????????????? }
?????? }
}
f_close(&file);
PRINTF("Sd read speed %dKB/s\r\n", 10*1024*1024/(timer_get_current_milliseconds()-TimeCount));
?
while(1) {
?????? GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
?????? Delay_ms(1000);
}
}
讀寫速度測試結(jié)果如下:
SD卡寫速度為872 KB/S,讀速度為1169 KB/S,SD卡通過SPI接口讀寫,SPI時鐘采用FRO 12M時鐘,因此這個讀寫速度是合適的。SD卡讀寫速度跟卡速度等級、數(shù)據(jù)傳輸速率有關(guān),讀寫多塊要比一塊一塊分多次讀寫快,此處測試一次性讀取8塊(512字節(jié)/塊),2048字節(jié),讀寫速度主要受限于SPI的傳輸速率,LPC5411x的SPI接口最高支持48M的時鐘,SPI可以通過采用PLL時鐘、內(nèi)部高速時鐘,進(jìn)一步提高SPI的傳輸速率,從而進(jìn)一步提高SD卡的讀寫速度。
5. 附錄
MDK工程,包含SPI模式的SD驅(qū)動,Fatfs文件系統(tǒng)模塊,SD卡讀寫速度測試應(yīng)用例程。
https://pan.baidu.com/s/1cMz1G6
?
總結(jié)
 
                            
                        - 上一篇: Caj转pdf有哪些不收费的转换方法?
- 下一篇: 极路由3-HC5861无拆机获取root
