劉人萍,汪 濤
(重慶大學(xué) 物理學(xué)院,重慶 401331)
NIOS下實(shí)現(xiàn)存儲(chǔ)速度可調(diào)的SD卡FAT文件系統(tǒng)
劉人萍,汪 濤
(重慶大學(xué) 物理學(xué)院,重慶 401331)
由于NIOS下自帶的SPI控制器,一旦建立,SPI clock(SCLK)的頻率在使用過(guò)程中是不允許被修改的,即SPI的讀取速度是不可改變的,這在很大程度上限制了SD卡的使用性能,因?yàn)樵诳ǔ跏蓟臅r(shí)候,SCLK時(shí)鐘最大不能超過(guò)400 kHz。使用軟件模擬SPI,通過(guò)示波器調(diào)試時(shí)序,并且移植了FATFS文件系統(tǒng)實(shí)現(xiàn)SD的存儲(chǔ)管理。最后通過(guò)存儲(chǔ)文件測(cè)試在不同速度下的存儲(chǔ)時(shí)間。
NIOS;軟件SPI;FATFS文件系統(tǒng);SD卡
與傳統(tǒng)處理器相比,NIOS II嵌入式系統(tǒng)在設(shè)計(jì)的時(shí)候可以根據(jù)不同的需求來(lái)增減外設(shè)的種類(lèi)和數(shù)量,在FPGA上面快速地搭建硬軟件平臺(tái)。再加上可以根據(jù)需要很方便地把FPGA并行處理的IP核嵌入到NIOS II系統(tǒng)中,而只需要簡(jiǎn)單的Avalon接口總線,所以其靈活的構(gòu)造方式越來(lái)越受到開(kāi)發(fā)人員的青睞。
嵌入式系統(tǒng)都需要用到大容量存儲(chǔ)設(shè)備,以備數(shù)據(jù)存儲(chǔ)。目前常用的存儲(chǔ)設(shè)備有U盤(pán)、Flash芯片、SD卡等,綜合比較,最適合嵌入式系統(tǒng)的可移動(dòng)存儲(chǔ)設(shè)備莫過(guò)于SD卡了。SD卡不僅容量可以做到32 GB以上,而且支持SPI,更換方便,編程簡(jiǎn)單,最高通信速度可以達(dá)到18 Mb/s,可滿足于一般的應(yīng)用要求。
然而在NIOS中使用SPI方式與SD卡通信的時(shí)候,由于在軟核的構(gòu)造過(guò)程中,系統(tǒng)已經(jīng)把SPI的時(shí)鐘頻率選定,在軟件編程時(shí)不可以再去修改SPI的速率,再加上SD卡在初始化過(guò)程時(shí)鐘最大不超過(guò)400 kHz[1],這樣在很大程度上限制了SD卡的使用性能。解決以上問(wèn)題的方法就是不使用NIOS II自帶的SPI控制器,利用軟件模擬的方式,可以隨時(shí)調(diào)整SPI的時(shí)鐘速率。
本文將從NIOS II軟核的構(gòu)建開(kāi)始,利用軟件模擬SPI,接著寫(xiě)SD的底層驅(qū)動(dòng),最后移植FATFS文件系統(tǒng)來(lái)管理SD卡,測(cè)量SD卡在不同的速率下寫(xiě)文件所需要的時(shí)間。
1.1 SOPC系統(tǒng)結(jié)構(gòu)簡(jiǎn)介[2]
為了盡可能簡(jiǎn)單地驗(yàn)證本文所述內(nèi)容,在硬件方面只選擇了所必需的硬件,其中包括處理器和支持處理工作的外圍設(shè)備以及4個(gè)通用的IO,具體如下:
(1)NIOS II 處理器。
(2)EPCS:FPGA的配置芯片,相當(dāng)于計(jì)算機(jī)的硬盤(pán)。由于FPGA掉電后,代碼和配置信息都會(huì)丟失,因此EPCS的功能一方面是保存NIOS II軟核的配置信息,另一方面是保存用戶需要運(yùn)行的程序代碼。
(3)DDR2 SDRAM: 程序運(yùn)行的地方。上電之后,系統(tǒng)會(huì)把EPCS中的代碼搬移到SDRAM中運(yùn)行。
(4)JTAG :第一是將編譯好的程序下載到開(kāi)發(fā)板中;第二是通過(guò)JTAG_UART來(lái)調(diào)試程序,打印程序的執(zhí)行結(jié)構(gòu)。
(5)4個(gè)通用IO : 由于用軟件來(lái)模擬SPI,因此只要4個(gè)通用IO,其中3個(gè)是輸出方向(SCLK,MOSI,CS),一個(gè)是輸入方向(MISO)。
1.2 NIOS II 軟核構(gòu)建流程[3]
(1)時(shí)鐘。時(shí)鐘是一個(gè)數(shù)字系統(tǒng)不可缺少的一部分,在嵌入式系統(tǒng)中尤為重要。時(shí)鐘信號(hào)的質(zhì)量也決定著嵌入式系統(tǒng)工作能否穩(wěn)定。在本次NIOS II軟核構(gòu)建中使用PLL來(lái)得到所希望的時(shí)鐘頻率。本文中所使用的開(kāi)發(fā)板的晶振頻率是50 MHz,希望得到的時(shí)鐘頻率也是50 MHz,按理說(shuō)是不需要PLL的,但是經(jīng)過(guò)PLL之后輸出的時(shí)鐘在穩(wěn)定性方面更好一些,所以就用PLL來(lái)生成一個(gè)頻率仍為50 MHz的時(shí)鐘。
(2)軟核及控制器構(gòu)建。這部分以NIOS II CPU為核心,包含了存儲(chǔ)單元的控制器和通用的IO接口。在CPU選擇過(guò)程中有三種類(lèi)型可供選擇,從資源消耗和工作速度的角度出發(fā),本文選擇了NIOSII/s。在選擇SDRAM控制器的時(shí)候,需要根據(jù)自己實(shí)際的硬件來(lái)進(jìn)行選擇,一般的數(shù)據(jù)在所使用芯片的DATASHEET中可以查到。然后是添加Flash控制器,這里使用的是EPCS,最后建立system ID和JTAG_UART。
(3)添加外圍設(shè)備。這里為了盡可能簡(jiǎn)單地驗(yàn)證本文功能,只添加了4個(gè)通用IO來(lái)模擬SPI時(shí)序。這里使用了三個(gè)輸出IO(CS,SCLK,MOSI)和一個(gè)輸入IO(MISO)。
2.1 SPI簡(jiǎn)介
SPI(Serial Peripheral Interface)是Motorola首先在其處理器上面定義的。SPI主要應(yīng)用在EEPROM、Flash、AD轉(zhuǎn)換等。SPI是一種高速的、全雙工、同步的通信總線,并且在芯片的引腳上只占用四跟線,既節(jié)約了芯片的引腳,也方便了PCB的布局布線。SPI接口一般使用四跳線通信:MISO:主設(shè)備輸入,從設(shè)備輸出;MOSI:主設(shè)備輸出,從設(shè)備輸入;SCLK:時(shí)鐘信號(hào),由主設(shè)備產(chǎn)生;CS:從設(shè)備片選信號(hào),由主設(shè)備產(chǎn)生。
2.2 SD卡相關(guān)介紹
SD卡(Secure Digital Memory Card)是一種基于半導(dǎo)體快閃記憶器的新一代記憶設(shè)備,它被廣泛地應(yīng)用在便攜式設(shè)備中。按容量可以把SD卡分為三類(lèi)[1]:SDSC(0~2 GB),SDHC(2~32 GB),SDXC(32 GB~2 TB)。
SD卡和SDHC卡協(xié)議基本兼容,但是同SDXC卡的區(qū)別比較大,本文主要介紹目前比較常用的SDHC卡的操作。SD的操作方式一般支持2種方式:SD卡模式和SPI模式,本文使用SPI模式。
從DATASHEET中可以知道SD卡每個(gè)命令是由6個(gè)字節(jié)組成的[1],第一個(gè)字節(jié)的最高兩位固定為01,然后緊接著是6個(gè)字節(jié)的命令號(hào),其中第2~5字節(jié)為命令參數(shù),如果有些命令沒(méi)有命令參數(shù)就設(shè)為0,第6字節(jié)的高7位是CRC,最低位恒為1。SD卡的通信采用發(fā)送應(yīng)答機(jī)制,每發(fā)送一個(gè)命令,SD卡都會(huì)給出一個(gè)應(yīng)答,以告知主機(jī)該命令的執(zhí)行情況,或者返回給主機(jī)需要獲取的數(shù)據(jù)。后面從示波器中可以看到SD卡具體的發(fā)送命令和接收應(yīng)答的相關(guān)時(shí)序。
2.3 軟件模擬速度可調(diào)的SPI
根據(jù)SD卡手冊(cè)的Bus Timing可以看出,SD卡底層的讀寫(xiě)時(shí)序是在時(shí)鐘的上升沿接收數(shù)據(jù),在時(shí)鐘的下降沿發(fā)出數(shù)據(jù)。所以根據(jù)這個(gè)時(shí)序要求,就可以通過(guò)軟件來(lái)模擬SD卡最底層的數(shù)據(jù)讀寫(xiě)。圖1右側(cè)是寫(xiě)一個(gè)字節(jié)的函數(shù),這個(gè)函數(shù)可以通過(guò)調(diào)節(jié)usleep(u32 nus)函數(shù)中的參數(shù)來(lái)調(diào)整SCLK的速度,從而達(dá)到了SPI寫(xiě)一個(gè)字節(jié)速度可調(diào)的目的。同理可以寫(xiě)出讀取一個(gè)字節(jié)的函數(shù),同樣可以根據(jù)usleep(u32 nus)中延時(shí)的參數(shù)不同來(lái)控制SPI讀取數(shù)據(jù)的速度。
圖1 SD Bus Timing 和 軟件SPI寫(xiě)一個(gè)字節(jié)
2.4 SD卡的初始化
圖2 DATASHEET復(fù)位時(shí)序和實(shí)際示波器測(cè)量對(duì)比
有了SD卡底層的讀寫(xiě)一個(gè)字節(jié)的函數(shù)之后,就可以與SD卡進(jìn)行通信了。根據(jù)SD卡的數(shù)據(jù)手冊(cè)可以總結(jié)出SD卡初始化的大致流程:首先需要給SD卡發(fā)送大于74個(gè)時(shí)鐘,這是因?yàn)镾D卡內(nèi)部有個(gè)供電電壓上升時(shí)間,大概為64個(gè)SCLK,剩下的10個(gè)SCLK用于SD卡同步,然后再發(fā)送CMD0使SD卡進(jìn)入IDLE狀態(tài);接著發(fā)送CMD8,檢查這個(gè)SD卡是否支持2.0協(xié)議;之后根據(jù)不同的應(yīng)答值檢查SD卡;最后初始化結(jié)束之后,需要多發(fā)8個(gè)SCLK使SD卡完成某些操作[4]。在完成初始化之后,就可以進(jìn)入SD卡的讀寫(xiě)數(shù)據(jù)了。在調(diào)試過(guò)程中利用示波器看到的波形圖如圖2所示。然后對(duì)比手冊(cè)給出的發(fā)送命令和返回相應(yīng)的時(shí)序圖,可以驗(yàn)證以上模擬的SPI時(shí)序是否正確可行。圖2(a)是SD卡手冊(cè)給出的部分復(fù)位時(shí)序圖,正常情況下在主機(jī)發(fā)送CMD0之后,SD卡會(huì)返回主機(jī)0x01。圖2(b)是實(shí)際在示波器上面看到的時(shí)序,根據(jù)SD卡命令形式可以看出,NIOS II主機(jī)發(fā)送的6個(gè)命令字節(jié)分別是:第1個(gè)字節(jié):0x40(命令第一個(gè)字節(jié)最高兩位必須為01),Command = 0;第2~5個(gè)字節(jié):0x00,0x00,0x00,0x00為命令的參數(shù);第6個(gè)字節(jié):0x95命令CRC校驗(yàn) + 最低位的“1”。
然后SD卡接收到NIOS II主機(jī)發(fā)送的CMD0命令之后,給出了一個(gè)0x01的應(yīng)答,從而可以看出,上述軟件模擬的SPI時(shí)序是正確的。
2.5 SD卡讀寫(xiě)功能測(cè)試
對(duì)SD卡初始化完成之后,就可以正常使用SD卡了。由于SD卡是存儲(chǔ)數(shù)據(jù)的設(shè)備,對(duì)SD的使用無(wú)非是讀數(shù)據(jù)和寫(xiě)數(shù)據(jù)。有了上面寫(xiě)命令和讀數(shù)據(jù)的基礎(chǔ)之后,就可以通過(guò)命令的形式來(lái)讀寫(xiě)SD卡了。
SD卡手冊(cè)規(guī)定,如果想讀SD卡某個(gè)扇區(qū)數(shù)據(jù),發(fā)送命令CMD17,參數(shù)為扇區(qū)數(shù),就可以讀出扇區(qū)內(nèi)的數(shù)據(jù)。寫(xiě)扇區(qū)通過(guò)發(fā)送CMD24來(lái)實(shí)現(xiàn)。這里使用了兩個(gè)函數(shù),分別為讀一個(gè)扇區(qū)和寫(xiě)一個(gè)扇區(qū)函數(shù):
SD_ReadDisk(buf,0,1)
//把扇區(qū)0的數(shù)據(jù)讀到buf中
SD_WriteDisk(buf,0,1)
//把buf中的數(shù)據(jù)寫(xiě)到扇區(qū)0中
由于SD卡是塊設(shè)備,在操作的時(shí)候需要一個(gè)扇區(qū)一個(gè)扇區(qū)地操作。在測(cè)試SD卡讀寫(xiě)功能的時(shí)候,先對(duì)SD卡初始化,接著讀出原來(lái)0號(hào)扇區(qū)的數(shù)據(jù),然后再寫(xiě)入數(shù)據(jù),最后再次讀出,經(jīng)過(guò)JTAG_UART的打印,可以看出是符合預(yù)期目標(biāo)的,所以讀寫(xiě)函數(shù)功能正常。
前面只是對(duì)SD卡一個(gè)扇區(qū)的讀寫(xiě),而且讀寫(xiě)都是數(shù)字。要真正有效地利用SD卡保存文件或者音樂(lè)等,必須使用文件系統(tǒng)管理。本文將使用FATFS來(lái)管理SD卡,實(shí)現(xiàn)SD卡文件的讀寫(xiě)。FATFS是一個(gè)完全免費(fèi)并且開(kāi)源的FAT文件系統(tǒng)模塊,用標(biāo)準(zhǔn)的C語(yǔ)言編寫(xiě),移植到各種嵌入式設(shè)備只需要進(jìn)行少量的修改。FATFS支持多個(gè)存儲(chǔ)媒介,有獨(dú)立的緩沖區(qū),可以對(duì)多個(gè)文件進(jìn)行讀寫(xiě)。使用者無(wú)需去關(guān)心FATFS內(nèi)部復(fù)雜的協(xié)議,只需要像調(diào)用其提供的其他一系列應(yīng)用接口函數(shù)那樣就可以了。
在移植使用的時(shí)候,只需要編寫(xiě)底層FATFS提供的接口函數(shù),它主要包括存儲(chǔ)設(shè)備的讀函數(shù)、寫(xiě)函數(shù)、初始化等,之后就可以輕松地使用。
3.1 FATFS移植步驟
(1)在官網(wǎng)下載源碼,解壓。本文所使用的Eclipse編譯環(huán)境中的數(shù)據(jù)類(lèi)型和源碼文件夾中integer.h里面的定義是一致的,所以不需要改動(dòng)。如果使用其他編譯器的數(shù)據(jù)類(lèi)型不和源碼中的相同,就需要根據(jù)編譯器定義好數(shù)據(jù)類(lèi)型。
(2)在ffconf.h頭文件中修改相關(guān)配置。這里根據(jù)自己的要求,改變某些變量的值,就可以配置出適合自己需求的文件系統(tǒng)。
(3)由于文件系統(tǒng)模塊完全與磁盤(pán)IO層分開(kāi),為了增加通用性,F(xiàn)ATFS的開(kāi)發(fā)者并不確定用戶所用的存儲(chǔ)設(shè)備是哪一類(lèi),所以需要用戶自己提供相應(yīng)的底層操作函數(shù)。在diskio.c文件里面,F(xiàn)ATFS已經(jīng)提供了函數(shù)接口,只需要根據(jù)自己的存儲(chǔ)設(shè)備類(lèi)型,把這些底層操作函數(shù)添加進(jìn)入即可。這里FATFS留出了6個(gè)函數(shù)接口。僅僅是為了驗(yàn)證本文的功能,本文只添加了三個(gè)函數(shù),其余函數(shù)都返回0。添加的函數(shù)為:disk_initialize,disk_read, disk_write。初始化函數(shù)和讀寫(xiě)扇區(qū)函數(shù)在前面都已經(jīng)使用和測(cè)試過(guò),只需要把這三個(gè)函數(shù)交給文件系統(tǒng)使用就可以了。
3.2 文件系統(tǒng)測(cè)試
本文對(duì)文件系統(tǒng)的測(cè)試,首先調(diào)用FATFS提供的接口函數(shù)f_getfree來(lái)測(cè)試SD卡的總?cè)萘亢褪S嗳萘?,然后在SD卡中創(chuàng)建一個(gè)文件,最后顯示SD卡的容量,判斷FATFS文件系統(tǒng)測(cè)試的結(jié)果和實(shí)際的結(jié)果是否一致,再在PC上查看SD卡中是否有剛才創(chuàng)建的文件。本文所用SD卡容量為4 GB,調(diào)用FATFS文件系統(tǒng)提供的接口f_getfree函數(shù)之后,得到了SD卡的容量為3 716 MB,如圖3所示,與實(shí)際的容量是相符合的。
圖3 調(diào)用文件系統(tǒng)函數(shù)測(cè)試SD卡容量
3.3 SD卡寫(xiě)文件速度測(cè)試
在移植文件系統(tǒng)之后,就可以輕松地使用SD卡來(lái)存儲(chǔ)文件了。這里限于硬件條件比較簡(jiǎn)單,所以只對(duì)SD卡寫(xiě)文件的速度做一個(gè)大致的測(cè)試和估算。如前所述可以通過(guò)改變usleep(u32 nus)這個(gè)函數(shù)的參數(shù)來(lái)改變SD卡的讀寫(xiě)速度。本文測(cè)試的方法是:向SD卡寫(xiě)入100 KB大小的文件,記錄在不同參數(shù)下所用的時(shí)間。最后通過(guò)測(cè)試發(fā)現(xiàn),使用usleep(10)函數(shù)寫(xiě)入100 KB的文件大致需要18 s;使用usleep(1)函數(shù)寫(xiě)入100 KB的文件大致需要3 s。通過(guò)初略的估算,usleep(10)的情況下,數(shù)據(jù)率約為50 kb/s=6.125 kB/s,寫(xiě)入100 KB內(nèi)容需要16.3 s,再加上SD卡初始化階段的一些通信命令和讀寫(xiě)命令的開(kāi)銷(xiāo)時(shí)間,可以認(rèn)為是在正常范圍。
本文在NIOS下利用軟件模擬SPI,對(duì)SD卡進(jìn)行了準(zhǔn)確的讀寫(xiě),然后移植FATFS文件系統(tǒng)來(lái)管理SD卡。提出了可以通過(guò)改變SPI SCLK的時(shí)鐘頻率來(lái)改變SD卡的讀寫(xiě)速率,并且測(cè)試了在不同速率下SD卡寫(xiě)文件的速率,可以解決在NIOS II下使用SPI不可改變SCLK速率的問(wèn)題。
[1] SD Group. SD specifications part1: physical layer simplified specification version 2.0[Z].2006.
[2] ALTERA. NIOS II processor Reference Handbook[Z].2014.
[3] 蔡偉剛. NIOS II 軟件架構(gòu)解析[M].西安:西安電子科技大學(xué)出版社,2007.
[4] 陳續(xù),鄧中亮.基于NIOS II的SD卡驅(qū)動(dòng)程序開(kāi)發(fā)[J].電子設(shè)計(jì)工程,2010,18(5):107-110.
Realization of storage speed adjustable SD card FAT file system in NIOS
Liu Renping,Wang Tao
(Physics Institute, Chongqing University, Chongqing 401331, China)
Once the NIOS II SPI controller is established, the frequency of the SPI clock (SCLK) is not allowed to be modified in the process of using. The SPI speed is immutable, which limits the use performance of the SD card, because when the SD card initializes, the frequency of the SCLK cannot exceed 400 kHz. The article uses the software to simulate SPI, through the oscilloscope debugging time sequence, by transplanting the FATFS file system to realize the SD storage management. At last, it measures the storage time under the different speeds by storing files.
NIOS;software SPI; FATFS file system;SD card
TP274
A
10.19358/j.issn.1674- 7720.2017.08.027
劉人萍,汪濤.NIOS下實(shí)現(xiàn)存儲(chǔ)速度可調(diào)的SD卡FAT文件系統(tǒng)[J].微型機(jī)與應(yīng)用,2017,36(8):85-87,91.
2016-11-21)
劉人萍(1991-),男,碩士研究生,主要研究方向:嵌入式底層驅(qū)動(dòng)。
汪濤(1972-),男,博士,碩士生導(dǎo)師,主要研究方向:光學(xué)儀器,光電檢測(cè)。
________________________