//Logo Image
作者:甘凱文(2006-01-20);推薦:徐業良(2006-01-20)

使用PIC單晶片儲存FAT16檔案資料

本文件說明如何使用PIC單晶片於多媒體儲存裝置寫入與Microsoft作業系統相容的檔案資料。本文首先針對Microsoft檔案配置表(File Allocation Table, FAT)的架構與檔案搜尋方作初步介紹,接著說明如使用PIC單晶片來存取或寫入FAT相容的檔案資料至MMC中,最後再以簡單的範例程式應用做說明。

1.     檔案配置表

檔案配置表(File Allocation Table, FAT)Microsoft1977所提出的一個檔案系統,適用於Microsoft的作業系統如DOSWindows等,依磁碟容量大小與配置的限制可區分成FAT12FAT16FAT32等幾種常見的配置,以下將以FAT16為例來對檔案配置與限制做初步的介紹。

1.1 基本磁碟結構

磁碟儲存最小單位為sector,每一個sector包含了512bytes的資訊內容。但用sector當單位來儲存效率會很差,一般不會以一個sector當作存取檔案的單位,而是以cluster為一基本檔案單位,每一個cluster是架構在sector2次方倍數上。假定連續的8sector所構成一個cluster,其大小就為512×8=4096bytes(4K),如此在存取資料時會以8sector連續讀取而提升了相對效率。但並不是讓單位cluster越大越好,因為cluster越大相對的可能會浪費許多磁碟空間,例如設定以4K為一個cluster而要儲存的檔案內容只有1K,但這個小檔案還是佔用掉一個cluster的空間,其他3K就浪費掉了。所在考慮cluster的規劃時,需要同時考慮到檔案讀取的效能與檔案大小是否會浪費硬碟空間。

另外cluster總數目的大小也會受限於磁碟機本身的容納與FAT型態而有所不同,以FAT16來說,根據定義其本身最大的cluster數目必須小於等於65526個,所以當格式化一張128MB的記憶卡,其每一個cluster至少必須要包含4sector,不然會超出65526cluster的限制(127,901,696/512/4=62,452clusters),所以每一cluster大小為512×4=2048(2K)。表1為三種格式的cluster數目限制範圍。

1. FAT格式的cluster數目限制範圍

 

FAT12

FAT16

FAT32

# of clusters

n~4085

4085~65526

65526~4177918

1.2 FAT的檔案配置架構

Microsoft的作業系統檔案與資料夾的配置架構如圖1,最底層為其根目錄資料夾(Root directory),內容紀錄第一層的次資料或是檔案之資訊,每一個次資料夾(Sub folder)相同記錄其下面一層的次資料夾或檔案資訊。例如圖1Root directory記錄著file1-1.datSub folder1-1、與Sub folder1-2的資訊,而Sub folder1-2記錄著Sub folder1-2file2-2.dat的資訊,以此類推下去。每一個資料夾所能記錄檔案或次資料夾數量有一定的限制,包含Root directory也是一樣,這個數量限制在做完磁碟格式時就已經確定了,除非使用磁碟管理軟體去更改,所以在做檔案規劃時也需注意資料夾與檔案的數目。

1. 檔案與資料夾配置架構

當要寫入或讀取某一資料夾下的檔案,則必須去尋求這個檔案在硬碟或磁碟的cluster位置並計算其對應的實體位置。在說明如何去尋找檔案在磁碟的物理位置前必須先了解FAT的組織架構。不管是FAT12FAT16、或FAT32的架構都如同圖2所示,假如這個多媒體的儲存裝置或磁碟沒有開機資訊(Master Boot Root, MBR),那其最初的磁區位置為“partition boot sector”,為記錄一些磁碟的資訊,當作完磁碟格式化後,相關資訊就已經寫入到這個位置上。圖3為商用軟體對一張已用FAT16格式化的MMC(128MB),所得到的boot sector資訊,由圖可以清楚的了解這張MMC的每一個sector512bytes,總共有250,336sector,以4sector為一個cluster,為FAT16格式的檔案系統,與檔案系統中包含了2FAT。圖2FAT1FAT22FAT是記錄著每一個檔案或次資料夾在磁區的那一個cluster位置之資訊,FAT1FAT2所包含的資料內容是相同的,因為FAT2主要是用來備份FAT1資料,以防止FAT1毀損時而遺失檔案的cluster位置,而Root directory如前述為其檔案的根目錄,由圖3Root entries可知此記憶卡的根目錄資料夾可最多放置共512個資料夾或檔案於第一層,除了partition boot sectorFAT、與Root directory,剩下的cluster都是檔案或次資料夾的磁區。

2. FAT組織架構

3. boot sector資訊

要找出檔案在磁碟的實體位置,首先要告知檔案的路徑。現在假設有檔案file_1-1.datRoot底下,其路徑為//Root/file_1-1.dat,最初會到Root底下找尋file_1-1.dat的相關資訊如圖2,並在資訊中運算出其在FAT1中的實體位置,接著在FAT1實體位置中取得file_1-1.dat相關cluster資訊,由圖2得知file_1-1.dat所占的第一個cluster51且指向52這個cluster,表示此檔案大過一個cluster,接著52又指向70,此時這第70cluster呈現一個EOF(End of File)訊息,在FAT16中應是以0xFFFF表示這個cluster為檔案結束的cluster,由此可知file_1-1.dat所占的clusters分別為5152、和70等三個cluster,最後再依據這三個cluster的真正實體位置去取得檔案的內容,完成讀file_1-1.dat檔的流程。有關於詳細計算方法或是細部的說明可參考微軟網頁所提供的FAT32 File System Specification白皮書。

2.     PIC單晶片存取FAT16檔案資料

Progressive Resources LLC提供一套FlashFile的整合套件,它是一套可相容於MCDOS的原碼封裝程式,程式內容為將上述的FAT檔案配置搜尋與讀寫模式封裝起來,只需將它匯入於CCS中便可使用標準C的檔案函數庫命令來使PIC單晶片存取FAT16檔案資料於MMCSD等中。

使用此檔案系統首先要匯入MMC設定檔如圖4所示,如果要使用檔案格式就將I_WANT_MMC_FILE_SYSTEM則定義為1,如果不使用則定義為0,當I_WANT_MMC_FILE_SYSTEM定義為1會將mmcFileSystem.h匯入於程式中,mmcFileSystem.h是設定MMC一些性質之參數與將原碼封裝程式一併匯入CCS中,設定的參數包括了是否使用MMC的除錯功能,開啟多重檔案功能與file system real time clock的使用等,而匯入的原碼封裝程式為mmcFileSystem.c.encrypted這個加密的封裝檔,所以並須要將mmcFileSystem.hmmcFileSystem.c.encrypted這兩個檔案放在同一個目錄,在這是放在mmcFileSystem目錄下,此外建議將要編輯的程式(MMC_test.c)mmcFileSystem目錄放在同一個主目錄下,在這裏使用的主目錄為MMC_test,整體如圖5所示。另外使用這個檔案系統基本會占用10~30K的程式空間,且目前所支援的晶片為18Fxxxx系列的晶片。

4. 匯入MMC設定檔

5. 編輯目錄放置樣式

2為檔案格式常用的指令集與其語法的使用說明,要注意的一點在第一次執行MMC存取動作時前,必須要做初始化也就是initialize_media(void)這個指令,而做完存寫動作後一定要關閉該編輯的檔案也就是fclose(FILE *rp)這個指令。

2. 檔案格式常用指令集

指令

說明

initialize_media(void)

MMC卡需初始化方可讀寫,如初始化成功會在終端機顯示MMC的相關資訊

fquickformat(void)

MMC做快速格式化

read_directory(void)

讀取目錄內資料,讀回的資訊會顯示在終端機上

mkdir(schar *F_PATH)

建立新的目錄資料夾,*F_PATH為目錄名稱,語法如下

strcpy(foldname,”TESTFOLD”);

mkdir(foldname);

chdir(schar *F_PATH)

改變目錄路徑,*F_PATH為改變目錄路徑的目錄名稱,語法如下

strcpy(foldname,”TESTFOLD”);

chdir(foldname);

*FILE fcreate(uchar *NAME, uchar MODE)

建立一個新檔,*NAME為檔名,語法如下

FILE *fp

strcpy(filename,”TEST.TXT”);

fp=fcreate(filename, 0);

fclosed(fp);

*FILE fopen(uchar *NAME, uchar MODE)

開啟檔案,*NAME為檔名,MODE包括READ, WRITE, APPEND

READ-只讀取檔案內容

WRITE-從頭開始寫入內容

APPEND-從上次寫入的最後一個字開始寫入

strcpy(filename,”TEST.TXT”);

fp=fopen(filename, READ);

fclose(FILE *rp)

關閉檔案,FILE *rp為檔案的指標,語法如下

strcpy(filename,”TEST.TXT”);

fp=fcreate(filename, 0);

fclosed(fp);

fgetc_(FILE *rp)

讀取檔案中的一個字元,語法如下

strcpy(filename,”TEST.TXT”);

fp=fopen(filename, READ);

C=fgetc_(fp);

fputc_(uchar file_data,FILE *rp)

寫入一個字元,file_data為欲輸入之字元,語法如下

strcpy(filename,”TEST.TXT”);

fp=fopen(filename, WRITE);

fputc_(‘c’, fp);

fgets(schar *buffer, sint n, FILE *rp)

讀取檔案中n個字元或讀到換行的字元(’\n’)則停止,語法如下

uchar data_buff[20];

uchar *pntr;

strcpy(filename,”TEST.TXT”);

fp=fopen(filename, READ);

pntr=fgets(data_buff, 20, fp);

20字元到data_buff

fputs_(uchar *file_data, FILE *rp)

寫入一行字串,語法如下strcpy(inputstring,”Hello”);

strcpy(filename,”TEST.TXT”);

fp=fopen(filename, WRITE);

fputs_(inputstring, fp)

寫入HelloTEST.TXT

feof(FILE *rp)

用於判斷是該字元否是檔案的結尾

如為回傳1表示為檔案的結尾

如為回傳0表示不為檔案的結尾

6為一個簡單範例程式,內容包含建立一個檔案、並寫入資料於檔案中、以及讀取方才寫入的檔案內容資料。範例中的1~12行程式為單晶片與使用檔案格式的初始定義設定,14~16行程式為設定使用的參數,包括了檔案名稱、檔案的指標、與使用的暫存器。主程式的21行在對MMC作初始化,這是一個必要步驟,如程式一開始沒做此動作,MMC可能無法存取,假如初始化成功電腦終端會呈現該MMC相關的資訊,否則會出現“Init ERROR!!!”的資訊。接著在24~25行程式內容為建立一個新的“grade.txt”空文字檔,而28~36行內容為開啟剛才建好的文字檔並設為寫入模式,接著程式34行將在電腦終端輸入文字寫入該文字檔中,直到輸入的字元為ESC(‘0x1b’)時才停止並關閉檔案。最後39~43為讀取檔案內容部分,首先在程式40行為開啟檔案並設為讀取模式,接著程式42行開始讀取檔案內容並呈現在電腦終端上,一直讀到該檔案的結尾feof()=1才停止並關閉檔案。

6. 程式範例

3.     整合應用範例

7為常開門門禁系統的架構圖,應用在一個開放且高流量的管理門上,能夠辨識人員的進出狀況、與該人員是否俱備有ID,並將狀況記錄在分散式資料伺服器(Distributed Data Server, DDS)MMC中,必要時也可以發送事件訊息給以特定人員。而MMC所要記錄的資料包括了人員的ID及進出該門的狀況與時間,由於記錄的方式為隨機性,所以記錄的檔案便以天為單位,也就是一天一個文字檔,而每日的午夜12DDS就會自動建立一個新文字檔,文字檔的檔名為月份與日期,實際檔案樣式與儲存記錄內容之格式如圖8所示。

7. 常開門門禁系統的架構圖

8. 實際檔案樣式與儲存記錄內容

此外此系統除了記錄門禁狀況外,外部管理者可以透過客製的VB管理介面來下載記錄資料以做資料備份或是後續管理,圖9為一簡易的VB下載介面,Client端的使用者只需輸入DDSHost_IPPort位置以及所需要下載的日期,如1224為下載1224當天的記錄,便可透過網路的TCP介面將DDSMMC儲存資料傳回至Client端,此外也可以輸入手機號給DDS,讓它儲存在MMC中,如有特定事件發生便可將它讀出並且透過SMS模組來發送事件簡訊。

9. VB下載介面