段素平
(中國船舶重工集團有限公司第七一〇研究所,湖北 宜昌 443003)
當前,嵌入式技術(shù)發(fā)展越來越快,對大容量數(shù)據(jù)存儲的需求也越來越迫切。傳統(tǒng)的嵌入式系統(tǒng)或產(chǎn)品一般只帶有Flash、ROM等存儲器,只能存儲少量數(shù)據(jù),若嵌入式系統(tǒng)需要存儲大容量數(shù)據(jù),目前常用的存儲設(shè)備有 SD存儲卡、U盤、Flash芯片等。Flash芯片存儲容量小、價格高,且需要集成在PCB印制電路板上使用;U盤雖然存儲容量高,但設(shè)計相對比較復(fù)雜,占用空間比較大,連接可靠性不高[1];而SD存儲卡體積小、存儲容量高,支持SPI/SDMMC驅(qū)動,多種尺寸可供選擇滿足不同應(yīng)用需求,優(yōu)勢明顯[2-3]?;诖?,設(shè)計了一種以SD存儲卡作為存儲設(shè)備的嵌入式存儲系統(tǒng)。
本系統(tǒng)主要由微處理器、SD存儲卡接口電路、復(fù)位模塊、電源模塊以及時鐘模塊等組成,如圖1所示。其中復(fù)位模塊、電源模塊以及時鐘模塊設(shè)計比較簡單,也不是本系統(tǒng)設(shè)計重點,所以本文不作介紹。
圖1 系統(tǒng)組成示意圖Fig.1 Diagram of system composition
1)微處理器。
微處理器主要負責控制整個系統(tǒng)的處理操作、狀態(tài)監(jiān)測以及任務(wù)管理等功能,最重要的是實現(xiàn)大容量數(shù)據(jù)快速可靠的存儲和讀取。選擇STM32H743作為本系統(tǒng)的微處理器,該處理器是 ST 推出的基于 ARM Cortex M7 內(nèi)核的處理器,擁有高達1 060 KB 的片內(nèi) SRAM,并且支持 SDRAM內(nèi)存擴展。STM32H743工作頻率達到400 MHz,具有6級流水線,帶有指令和數(shù)據(jù)Cache,大大提高了性能。此外,STM32H743自帶豐富的外圍接口,其中就包括SDMMC接口控制器[4],利用該接口控制器可以很高效地實現(xiàn)SD存儲卡接口電路設(shè)計。
2)SD存儲卡接口電路。
STM32H743自帶SDMMC控制器,最高通信速度可達48 MHz[5],如圖2所示。本系統(tǒng)利用該控制器實現(xiàn)SD存儲卡接口電路設(shè)計。
圖2 SDMMC控制器示意圖Fig.2 Diagram of SDMMC controller
在 SDIO 模式下,只需要用到:SDMMC_CK、SDMMC_D[3︰0]、SDMMC_CMD 這幾根線即可正常驅(qū)動 SD 卡,電路設(shè)計原理圖如圖3所示。
圖3中,SDIO_D0-SDIO_D3為數(shù)據(jù)線,實現(xiàn)數(shù)據(jù)傳輸,所有的數(shù)據(jù)線都工作在推挽模式。SDIO_CLK為時鐘線,對應(yīng) SDMMC控制器的卡時鐘SDMMC_CK(每個時鐘周期在命令和數(shù)據(jù)線上傳輸1位命令或數(shù)據(jù)),在3.3 V信號電平下,該時鐘頻率最大可以達到50 MHz。需要注意的一點是,在 SD 卡剛剛初始化的時候, SDMMC_CK時鐘是不能超過 400 kHz 的,否則可能無法完成初始化,在初始化以后,就可以設(shè)置時鐘頻率到最大了[6]。SD_CD為SDMMC控制器通用命令信號線,對應(yīng)SDMMC控制器的SDMMC_CMD,SDMMC的所有命令和響應(yīng)都是通過 SDMMC_CMD 引腳傳輸?shù)模魏蚊畹拈L度都是固定為48 位[7]。
圖3 SD卡接口電路原理圖Fig.3 Schematic of SD card interface circuit
3)調(diào)試串口。
串口(串行通信接口)是指數(shù)據(jù)一位一位地順序傳送,其特點是通信線路簡單,只要一對傳輸線就可以實現(xiàn)雙向通信,從而大大降低了成本。RS232是最常用的一種串行通信接口,也稱標準串口[8],本系統(tǒng)使用RS232用作調(diào)試接口,實現(xiàn)系統(tǒng)狀態(tài)信息的打印輸出。
由于STM32H743輸出的都是TTL電平,即邏輯“平,對應(yīng)2~3.3 V,邏輯“邏輯對應(yīng)0~0.4 V,而 RS232標準采用負邏輯,即邏輯“1”對應(yīng)-5~-15 V,邏輯“0”對應(yīng)+5~+15 V[9]。為了實現(xiàn)兩者之間的串口通信,利用ADM3251芯片進行電平的轉(zhuǎn)換,電路設(shè)計如圖4所示。
圖4 調(diào)試串口電路原理圖Fig.4 Schematic of debugging serial circuit
為了提高系統(tǒng)的可靠性和抗干擾能力,在設(shè)計硬件平臺時完成了以下工作:
1)將數(shù)字地和模擬地分開設(shè)計,電源線、地線的走向和數(shù)據(jù)線的走向平行設(shè)計,以提高抗干擾能力。
2)電源線設(shè)計得盡可能寬,減少環(huán)路電阻。
3)分布在電路板正反兩面的信號線進行垂直處理,在需要拐彎的地方設(shè)計成135°角。
4)PCB板上的過孔會帶來一定的電容效應(yīng),設(shè)計的時候盡量減少過孔數(shù)量。
本系統(tǒng)軟件設(shè)計用到的工具主要是 MDK,MDK源自德國的KEIL公司,它使用 uVision5 IDE集成開發(fā)環(huán)境,是目前針對 ARM 處理器,尤其是 Cortex M 內(nèi)核處理器的最佳開發(fā)工具[10]。
對于存儲設(shè)備的管理,若采用傳統(tǒng)讀寫扇區(qū)的方式,不但會影響系統(tǒng)的性能,也無法發(fā)揮SD存儲卡的優(yōu)勢,因此本系統(tǒng)移植FatFS文件系統(tǒng)對存儲設(shè)備進行數(shù)據(jù)管理。FatFS文件系統(tǒng)是一個完全免費開源的 FAT文件系統(tǒng)模塊,該系統(tǒng)為應(yīng)用程序開發(fā)提供統(tǒng)一的、標準的API函數(shù),具有良好的可維護性和移植性[11]。FatFS 文件系統(tǒng)的層次結(jié)構(gòu)如圖5所示。
圖5 FatFS文件系統(tǒng)的層次結(jié)構(gòu)圖Fig.5 Hierarchy diagram of FatFS file system
最頂層是應(yīng)用層,使用者無需理會 FatFS 的內(nèi)部結(jié)構(gòu)和復(fù)雜的 FAT 協(xié)議,只需要調(diào)用FATFS模塊提供給用戶的應(yīng)用接口函數(shù),如 f_open,f_read,f_write 和 f_close 等,就可以像在 PC 上讀寫文件那樣簡單[12]。中間層 FATFS 模塊,實現(xiàn)了 FAT 文件讀寫協(xié)議,使用時只要將需要的頭文件包含進去即可。需要編寫移植代碼的是FatFS模塊提供的底層接口,它包括存儲媒介讀寫接口(diskI/O)和供給文件創(chuàng)建修改時間的實時時鐘。
FATFS 模塊在移植的時候,一般只需要修改源碼中ffconf.h 和 diskio.c 兩個文件。FATFS模塊的所有配置項都是存放在 ffconf.h 里面,通過配置里面的一些選項,來滿足系統(tǒng)的需求;diskio.c實現(xiàn)底層驅(qū)動,需要編寫如圖6所示的6個接口函數(shù)[13]。
圖6 FatFS底層驅(qū)動接口函數(shù)Fig.6 Interface function of FatFS underlying driver
disk_initialize( )函數(shù)實現(xiàn)磁盤驅(qū)動器的初始化;disk_status( )函數(shù)的功能是返回當前磁盤驅(qū)動器的狀態(tài);disk_read( )函數(shù)讀取磁盤驅(qū)動器上的數(shù)據(jù);disk_write( )函數(shù)是往磁盤驅(qū)動器上寫入數(shù)據(jù);disk_ioctl( )函數(shù)用來控制設(shè)備指定特性和除了讀/寫外的雜項功能;get_fattime( )函數(shù)用來獲取當前時間。
在成功移植FatFS文件系統(tǒng)基礎(chǔ)上,需要完成應(yīng)用程序的編寫,應(yīng)用程序完成的工作如下:
1)系統(tǒng)硬件初始化,包括配置系統(tǒng)時鐘、HAL庫初始化、使能Cache以及配置系統(tǒng)中斷等。
2)SD 存儲卡接口初始化,主要利用STM32H743自帶的SDMMC控制器對SD存儲卡接口進行初始化操作。
3)FatFS文件系統(tǒng)初始化,將SD存儲卡在磁盤的編號設(shè)置為0,并通過f_mount( )函數(shù)為SD存儲卡注冊一個工作區(qū)。
4)完成 SD卡存儲功能,先調(diào)用 f_open( )函數(shù)創(chuàng)建一個新文件或打開已存在的文件,然后調(diào)用f_write( )函數(shù)將緩沖區(qū)的內(nèi)容寫入到剛打開的文件中,最后調(diào)用f_close( )函數(shù)關(guān)閉已打開的文件。以上步驟即可完成SD卡的數(shù)據(jù)存儲。
5) 完成SD卡讀取功能,先調(diào)用f_open( )函數(shù)打開數(shù)據(jù)存儲文件,然后調(diào)用f_read( )函數(shù)將文件內(nèi)容寫入到緩沖區(qū),并作出相應(yīng)處理,最后調(diào)用f_close( )函數(shù)關(guān)閉已打開的文件。以上步驟即可完成SD卡的數(shù)據(jù)讀取。
SD存儲卡的較高讀寫速率可能會導(dǎo)致讀寫錯誤的發(fā)生,為了降低錯誤發(fā)生的概率,提高系統(tǒng)的可靠性,本系統(tǒng)軟件設(shè)計時采取以下措施:
1)讀寫數(shù)據(jù)采用校驗方式來檢驗數(shù)據(jù)的正確性,同時為了避免校驗和正確而數(shù)據(jù)錯誤的極其偶然情況發(fā)生,對數(shù)據(jù)層面進行再次檢驗,比如給加入數(shù)據(jù)幀頭,在讀寫數(shù)據(jù)時均對數(shù)據(jù)的幀頭加以判斷。只有當數(shù)據(jù)幀頭以及數(shù)據(jù)校驗和均正確,才會認為本次數(shù)據(jù)有效。
2)讀寫錯誤發(fā)生后,對數(shù)據(jù)進行循環(huán)讀寫,直到正確讀寫數(shù)據(jù)才跳出循環(huán)。
為了驗證系統(tǒng)的功能,設(shè)計了2組測試。第1組為基本功能測試。測試在 SD存儲卡中新建目錄或文件、在文件中讀寫數(shù)據(jù)等功能。在SD卡根目錄下新建根 SD_BasicFuctionsTest”目錄和“sd_test.txte文件,并在“sd_test.txte文件中寫入測試數(shù)據(jù)。之后讀取SD卡中所有信息,觀察是否含有“SD_BasicFuctionsTest”目錄和“sd_test.txtes文件。若存在該文件,讀取該文件數(shù)據(jù),觀察是否和之前寫入的數(shù)據(jù)一致。
第2組為系統(tǒng)性能測試。測試系統(tǒng)讀寫SD卡速度(大容量數(shù)據(jù)存儲系統(tǒng)中,數(shù)據(jù)讀寫速度是一個很重要的設(shè)計指標)以及讀寫可靠性。在 SD卡根目錄下新建“Speed.txt”文件,往該文件全速寫入2 048 kB數(shù)據(jù),計算其寫入速度;之后全速讀取“Speed.txt”文件中的數(shù)據(jù),計算文件讀取速度。同時將讀取的數(shù)據(jù)與之前寫入的數(shù)據(jù)進行比較,統(tǒng)計匹配度。
上述的測試步驟,本系統(tǒng)都通過調(diào)試串口打印相應(yīng)信息,如圖7所示。
圖7 調(diào)試串口打印的測試信息Fig.7 Test information printed by the serial port
圖7中的①表明系統(tǒng)成功創(chuàng)建了文件“sd_test.txt”,并成功寫入測試數(shù)據(jù);②說明系統(tǒng)成功創(chuàng)建了“SD_BasicFuctionsTest”目錄。之后讀取“sd_test.txt”文件數(shù)據(jù),該數(shù)據(jù)與之前寫入的數(shù)據(jù)一致,如圖中③所示。圖7中的④是系統(tǒng)性能測試時打印信息情況,可知SD存儲卡讀寫速度分別達到了44 Mbps和26 Mbps,可滿足大部分應(yīng)用需求。讀寫數(shù)據(jù)匹配度達到了100%,說明系統(tǒng)可靠性符合要求。
本文主要對嵌入式存儲系統(tǒng)進行了討論和研究,成功完成了系統(tǒng)的硬件設(shè)計和軟件設(shè)計。最后,通過2組試驗對系統(tǒng)的基本功能、讀寫速度以及可靠性進行了測試,測試結(jié)果充分驗證了本系統(tǒng)設(shè)計的正確性。