發(fā)送數(shù)據(jù)前,需要先從SD 卡中讀取配置文件。所有文件在SD 卡中都是按照一定的格式來組織的,本方案默認(rèn)文件采用FAT16 格式進(jìn)行存儲(chǔ)。FAT16 格式下,SD 卡的結(jié)構(gòu)如下圖所示[3]。

?
主引導(dǎo)記錄中最重要的參數(shù)是邏輯扇區(qū)的起始地址。獲得該參數(shù)后即可以讀取BIOS 參 數(shù)數(shù)據(jù)塊(BPB)。BPB 中存儲(chǔ)了扇區(qū)(Sector)、簇(Cluster)、文件分配表(FAT)的 大小,以及分區(qū)總扇區(qū)數(shù)等參數(shù),是文件進(jìn)行操作時(shí)必不可少的。文件分配表則是指明了文 件存儲(chǔ)的位置,這些位置是以簇為單位的。每個(gè)簇包含的扇區(qū)數(shù)目在BPB 中說明。根文件 夾中存儲(chǔ)了各不同文件的文件名和起始簇以及文件大小等信息。
2.5 配置文件的讀取和發(fā)送
根據(jù)上述SD 卡存儲(chǔ)格式的說明,可以對(duì)存儲(chǔ)在其中的配置數(shù)據(jù)進(jìn)行讀取并發(fā)送出去。在本方案中,數(shù)據(jù)的讀取和發(fā)送是同時(shí)進(jìn)行的。
在對(duì) SD 卡進(jìn)行讀取時(shí),首先需要讀取主引導(dǎo)記錄(MBR),獲得邏輯扇區(qū)的位置,然 后根據(jù)該位置讀取BIOS 參數(shù)數(shù)據(jù)塊(BPB),得到文件分配表(FAT)的位置以及扇區(qū)大 小等參數(shù)。在讀取文件分配表之前,需要先讀取根文件夾來獲得文件的起始位置,然后再 通過文件分配表獲得后續(xù)數(shù)據(jù)的位置。
得到文件的起始簇號(hào)之后,在文件分配表中讀取對(duì)應(yīng)該起始簇的字節(jié),獲得文件存儲(chǔ)的 下一個(gè)簇的簇號(hào),這樣可以連續(xù)的進(jìn)行讀取。在讀取一個(gè)簇后,即將整簇的數(shù)據(jù)發(fā)送出去。 如果發(fā)現(xiàn)文件分配表中某一簇對(duì)應(yīng)的數(shù)值是0xFFFF,則說明是文件最后一個(gè)簇,這時(shí)該簇 的數(shù)據(jù)可以不足一個(gè)整簇,需要對(duì)其中的數(shù)據(jù)進(jìn)行取舍,以保證發(fā)送數(shù)據(jù)的正確性。
對(duì)配置文件讀取和發(fā)送的函數(shù)偽碼如下所示。
ReadSD_FAT16(){
讀取物理第0 扇區(qū)內(nèi)容,即MBR,獲取邏輯0 扇區(qū)的位置;
讀取邏輯0 扇區(qū)的內(nèi)容,獲取每扇區(qū)字節(jié)數(shù),每簇扇區(qū)數(shù),F(xiàn)AT 表占據(jù)的扇區(qū)數(shù)等參數(shù);
讀取根文件夾的內(nèi)容,根據(jù)配置文件的文件名獲取其起始簇號(hào)和文件長度;
將當(dāng)前簇設(shè)置為起始簇;
While(1){
讀取FAT 中對(duì)應(yīng)當(dāng)前簇的內(nèi)容,獲得下一個(gè)簇的簇號(hào);
FAT 表中對(duì)應(yīng)當(dāng)前簇的內(nèi)容為0xFFFF 時(shí),即說明當(dāng)前簇是最后一個(gè)簇,計(jì)算該簇內(nèi)的有效數(shù)據(jù),并進(jìn)行發(fā)送;
讀取當(dāng)前簇內(nèi)容,進(jìn)行發(fā)送;
當(dāng)前簇指向下一個(gè)簇;
}
}
3 結(jié)束語
在當(dāng)前FPGA 使用領(lǐng)域日趨廣泛的情況下,對(duì)現(xiàn)有的含有FPGA 的嵌入式產(chǎn)品進(jìn)行升 級(jí)更新成為了一項(xiàng)比較繁瑣的工作,特別是在產(chǎn)品數(shù)量較多的情況下。本方案提出了采用 SD 卡存儲(chǔ)配置數(shù)據(jù)的配置方案,使用了目前嵌入式系統(tǒng)中常見的ARM 微處理器和SD 卡, 不僅降低了成本,而且利用了現(xiàn)有資源,節(jié)省了電路板布線布局的空間。最重要的是使升級(jí) 過程更加簡潔,在進(jìn)行調(diào)試時(shí)也可以靈活使用。本文只給出了對(duì)Virtex FPGA 進(jìn)行配置的情 況,該方案也可以適用于Spartan 系列FPGA。
評(píng)論