电子工程师名片——FAT16文件系统
???????? 從8月8號開始,連續(xù)一個月利用每天下班時間和周末的時間終于初步完成了一個電子工程師的電路板名片,就像U盤一樣,不過這個FLASH只有64KB的大小,用的單片機(jī)是C8051F320,是一個USB型的單片機(jī)。
??????? 這次獲取的教訓(xùn)是一開始想好要做什么事,無論如何要堅(jiān)持下來,也許困難有很大,但是和困難磨磨突然會發(fā)現(xiàn)原來眼前的困難也是有解決的辦法的,突然的豁然開朗。
??????? 整體結(jié)構(gòu)如下:
????????? 我打算把自己所做的按照我自己調(diào)試的過程寫下來,會連續(xù)發(fā)幾篇博客,歡迎關(guān)注我哦。FAT16文件系統(tǒng)是在最后才搞出來,趁熱打鐵,把它作為第一篇先記下來
電子工程師電路板名片之FAT16文件系統(tǒng)
??????
??????? FAT16文件系統(tǒng)的介紹在這篇博客介紹比較詳細(xì):http://blog.csdn.net/menghnhhuan/article/details/4270168
??????? FAT16文件系統(tǒng)在U盤、MMC卡、SD卡、以及一些小型系統(tǒng)上用的比較多,我在MX25L512這個64KB的FLASH安裝的文件系統(tǒng)如下:
???????
注:第一個8*512中包含DBR區(qū)共一個512 Bytes,其余7個512 Bytes內(nèi)容為0,但這8個512 Bytes都是保留扇區(qū)
一、DBR區(qū)(DOS BOOT RECORD):即操作系統(tǒng)引導(dǎo)區(qū),本身只占512Bytes,但是從0地址開始有8個保留扇區(qū)(包括DBR區(qū)),所以FAT1的起始地址為8×512Bytes
注:BPB區(qū)記錄本分區(qū)的起始扇區(qū),結(jié)束扇區(qū),文件存儲格式,磁盤介質(zhì)描述符,根目錄大小,FAT個數(shù),分配單元大小等。
下面是我程序中具體去設(shè)置DBR的512個字節(jié)
code unsigned char DBR[512] = {0xeb,0x3c,0x90, //跳轉(zhuǎn)指令,跳轉(zhuǎn)到0x3c+2的引導(dǎo)程序代碼處 0x4d,0x53,0x44, 0x4f, 0x53, 0x35, 0x2e, 0x30, //廠商標(biāo)志和OS版本號//BPB(BIOS parameter block)0x00,0x02, //扇區(qū)字節(jié)數(shù)512(合法的有512,1024,4096),C8051F單片機(jī)是大端模式0x01, //每簇扇區(qū)數(shù)(合法的有1,2,4,8,16,32,64,128)0x08,0x00, //保留扇區(qū)數(shù),這樣可以知道FAT1區(qū)起始地址,為8×5120x02, //FAT數(shù)目0x00,0x02, //根目錄數(shù),典型為512個目錄,每個文件或文件夾名長度為32 bytes0x80,0x00, //小扇區(qū)數(shù),(對于大于65536個扇區(qū)的分區(qū),本字段為0,采用大扇區(qū)表示,)0xf8, //媒體描述符,0xf8表示硬盤,0xf0表示3.5寸軟盤0x08,0x00, //每個FAT占用的扇區(qū)數(shù)0x3F,0x00, //每道扇區(qū)數(shù)0xFF,0x00, //磁頭數(shù)0x00,0x00,0x00,0x00, //隱藏扇區(qū)數(shù)0x00,0x00,0x00,0x00, //大扇區(qū)數(shù),如果小扇區(qū)字段為0,本字段就包含了FAT16中的總扇區(qū)數(shù)//如果小扇區(qū)字段不為0,那么本字段為0//BPB擴(kuò)展字段0x80, //物理驅(qū)動器,硬盤被標(biāo)志為0x80,軟盤驅(qū)動器被標(biāo)志為0x000x00, //保留字段0x29, //擴(kuò)展引導(dǎo)標(biāo)簽,要有能被windows 2000所識別的0x28或0x290xA8, 0x8B, 0x36, 0x52, //卷序號,在格式化磁盤時所產(chǎn)生的一個隨機(jī)號,助于區(qū)分磁盤0x4E, 0x4F, 0x20, 0x4E, 0x41, 0x4D, 0x45, 0x20, 0x20, 0x20, 0x20, //卷標(biāo)0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, //文件系統(tǒng)類型FAT16//操作系統(tǒng)引導(dǎo)代碼 0xf1, 0x7d,0xfa, 0x33, 0xc9, 0x8e, 0xd1, 0xbc, 0xfc, 0x7b, 0x16, 0x07, 0xbd, 0x78, 0x00, 0xc5, 0x76, 0x00,0x1e, 0x56, 0x16, 0x55, 0xbf, 0x22, 0x05, 0x89, 0x7e, 0x00, 0x89, 0x4e, 0x02, 0xb1, 0x0b, 0xfc,0xf3, 0xa4, 0x06, 0x1f, 0xbd, 0x00, 0x7c, 0xc6, 0x45, 0xfe, 0x0f, 0x8b, 0x46, 0x18, 0x88, 0x45,0xf9, 0xfb, 0x38, 0x66, 0x24, 0x7c, 0x04, 0xcd, 0x13, 0x72, 0x3c, 0x8a, 0x46, 0x10, 0x98, 0xf7,0x66, 0x16, 0x03, 0x46, 0x1c, 0x13, 0x56, 0x1e, 0x03, 0x46, 0x0e, 0x13, 0xd1, 0x50, 0x52, 0x89,0x46, 0xfc, 0x89, 0x56, 0xfe, 0xb8, 0x20, 0x00, 0x8b, 0x76, 0x11, 0xf7, 0xe6, 0x8b, 0x5e, 0x0b,0x03, 0xc3, 0x48, 0xf7, 0xf3, 0x01, 0x46, 0xfc, 0x11, 0x4e, 0xfe, 0x5a, 0x58, 0xbb, 0x00, 0x07,0x8b, 0xfb, 0xb1, 0x01, 0xe8, 0x94, 0x00, 0x72, 0x47, 0x38, 0x2d, 0x74, 0x19, 0xb1, 0x0b, 0x56,0x8b, 0x76, 0x3e, 0xf3, 0xa6, 0x5e, 0x74, 0x4a, 0x4e, 0x74, 0x0b, 0x03, 0xf9, 0x83, 0xc7, 0x15,0x3b, 0xfb, 0x72, 0xe5, 0xeb, 0xd7, 0x2b, 0xc9, 0xb8, 0xd8, 0x7d, 0x87, 0x46, 0x3e, 0x3c, 0xd8,0x75, 0x99, 0xbe, 0x80, 0x7d, 0xac, 0x98, 0x03, 0xf0, 0xac, 0x84, 0xc0, 0x74, 0x17, 0x3c, 0xff,0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0xeb, 0xee, 0xbe, 0x83, 0x7d, 0xeb, 0xe5,0xbe, 0x81, 0x7d, 0xeb, 0xe0, 0x33, 0xc0, 0xcd, 0x16, 0x5e, 0x1f, 0x8f, 0x04, 0x8f, 0x44, 0x02,0xcd, 0x19, 0xbe, 0x82, 0x7d, 0x8b, 0x7d, 0x0f, 0x83, 0xff, 0x02, 0x72, 0xc8, 0x8b, 0xc7, 0x48,0x48, 0x8a, 0x4e, 0x0d, 0xf7, 0xe1, 0x03, 0x46, 0xfc, 0x13, 0x56, 0xfe, 0xbb, 0x00, 0x07, 0x53,0xb1, 0x04, 0xe8, 0x16, 0x00, 0x5b, 0x72, 0xc8, 0x81, 0x3f, 0x4d, 0x5a, 0x75, 0xa7, 0x81, 0xbf,0x00, 0x02, 0x42, 0x4a, 0x75, 0x9f, 0xea, 0x00, 0x02, 0x70, 0x00, 0x50, 0x52, 0x51, 0x91, 0x92,0x33, 0xd2, 0xf7, 0x76, 0x18, 0x91, 0xf7, 0x76, 0x18, 0x42, 0x87, 0xca, 0xf7, 0x76, 0x1a, 0x8a,0xf2, 0x8a, 0x56, 0x24, 0x8a, 0xe8, 0xd0, 0xcc, 0xd0, 0xcc, 0x0a, 0xcc, 0xb8, 0x01, 0x02, 0xcd,0x13, 0x59, 0x5a, 0x58, 0x72, 0x09, 0x40, 0x75, 0x01, 0x42, 0x03, 0x5e, 0x0b, 0xe2, 0xcc, 0xc3,0x03, 0x18, 0x01, 0x27, 0x0d, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x79,0x73, 0x74, 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0xff, 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b,0x20, 0x49, 0x2f, 0x4f, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xff, 0x0d, 0x0a, 0x52, 0x65, 0x70,0x6c, 0x61, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2c, 0x20, 0x61,0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e,0x79, 0x20, 0x6b, 0x65, 0x79, 0x0d, 0x0a, 0x00, 0x49, 0x4f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,0x53, 0x59, 0x53, 0x4d, 0x53, 0x44, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x53, 0x59, 0x53, 0x80, 0x01,0x00, 0x57, 0x49, 0x4e, 0x42, 0x4f, 0x4f, 0x54, 0x20, 0x53, 0x59, 0x53, 0x00, 0x00,//扇區(qū)結(jié)束標(biāo)志0x55, 0xaa };二、FAT16文件系統(tǒng)
??? FAT(File Allocation Table)文件分配表,是微軟在FAT文件系統(tǒng)中用于磁盤數(shù)據(jù)文件索引和定位引進(jìn)的一種鏈?zhǔn)浇Y(jié)構(gòu),有兩個,另一個是備份。FAT文件系統(tǒng)之所以有12、16、32不同的版本之分,其根本在于FAT表用來記錄任意一簇鏈接的二進(jìn)制位數(shù)。以FAT16為例,每一簇在FAT表中占據(jù)兩個字節(jié)(二進(jìn)制16位)。所以,FAT16最大可以表示的簇號為0xFFFF,以32K為一簇的大小,FAT16可以管理的最大磁盤空間為:32KB×65536=2048B,所以FAT16最大支持2GB的分區(qū)。
??? 因此FAT表以2個字節(jié)為一個記錄項(xiàng),通常第1、2個記錄項(xiàng)用作介質(zhì)描述(0xF8、0xFF、0xFF、0xFF),從第3個記錄項(xiàng)開始記錄除根目錄外的其他文件夾的簇鏈情況。具體FAT16表如何用很多個簇號鏈接表示見 http://bbs.ednchina.com/BLOG_ARTICLE_226477.HTM,一個文件結(jié)尾的簇號為0xFFFF。
三、文件目錄
??? 跟目錄的位置緊隨FAT2表之后,系統(tǒng)以32個字節(jié)為單位進(jìn)行目錄文件所占簇的分配,文件目錄必須占據(jù)32個扇區(qū)
0x1A~0x1B為文件開始簇號,例如簇號為02 00,因?yàn)槭鞘褂眯《四J?#xff0c;轉(zhuǎn)化后簇號為00 02,根據(jù)這個可以找到文件第一個簇號在FAT1中的位置,0x1000H+02H*02H=1004H,因此可以計算文件第一簇數(shù)據(jù)存放地址為56×512(用戶數(shù)據(jù)起始地址)+(02H-02H)×512(1簇占1個扇區(qū)),而在FAT1表1004H的地址上的數(shù)據(jù)為03 00,轉(zhuǎn)換后為00 03,那么可以計算第二簇的數(shù)據(jù)存放地址為56×512(用戶數(shù)據(jù)起始地址)+(03H-02H)×512(1簇占1個扇區(qū)),一直到FAT1表的某兩個字節(jié)為FF FF時代表文件結(jié)束。
四、處理PC端發(fā)來的讀寫文件系統(tǒng)的固件程序
U盤固件提供的功能:當(dāng)主機(jī)要求讀取某個扇區(qū),定位到該扇區(qū),從扇區(qū)里面讀出內(nèi)容,并輸出給主機(jī),他不需知道U盤是什么文件,只需把數(shù)據(jù)讀出來,主機(jī)通過讀取的扇區(qū)的內(nèi)容來判斷是什么文件系統(tǒng)。
FLASH知識:
64kB的flash本身的sector為4kB,Page為256Byte
Page為寫入數(shù)據(jù)的最小單位,sector為數(shù)據(jù)擦除的最小單位。
而現(xiàn)在作為文件系統(tǒng),我已經(jīng)修改為:LBA(Logical BlockAddress)128個,每個Block的大小為512Byte,128*512B=65536B=64kB。
處理好LBA和Pagenum的關(guān)系
LBA指起始邏輯塊地址,即flash中的第幾個Block(512Byte)
Pagenum為有多少個邏輯塊地址,最大為上面計算的128個Block。
因?yàn)楝F(xiàn)在文件系統(tǒng)Block的大小為512Bytes,而flash的page大小為256,所以每次寫512字節(jié)要分兩次來寫。
SPI_Write_Page(buff,0,2*(LBA+Pagenum)-2);
SPI_Write_Page(buff,0,2*(LBA+Pagenum)-1);
case Read_10://回發(fā)MBR主引導(dǎo)扇區(qū)數(shù)據(jù)//sector:擦除數(shù)據(jù)的最小單位//page讀寫數(shù)據(jù)的最小單位// LBA:logical block address// PageNum:number of LBA// 16 sectors 1 sector=16 page 1 page=256 byteif(PageNum>0){for(i=1;i<=PageNum;i++){PageNumL=2*(LBA+i-1);SPI_READ_Page(0, PageNumL);for(t=0;t<4;t++){FIFO_Write(buff + t*MaxSize, FIFO1, MaxSize);SFR_Write(EINCSRL,0x01);while(SFR_Read(EINCSRL) & 0x01);}PageNumH=2*(LBA+i-1)+1;SPI_READ_Page(0, PageNumH);for(t=0;t<4;t++){FIFO_Write(buff + t*MaxSize, FIFO1, MaxSize);SFR_Write(EINCSRL,0x01);while(SFR_Read(EINCSRL) & 0x01);}}}csw=1;sendDebug(Read_10);sendDebug(LBA);sendDebug(PageNum); break; case Write_10://host向slave發(fā)數(shù)據(jù)并寫在U 盤里面if(PageNum>0){SPI_SECTOR_ERASE(LBA/8);for(i=1;i<=PageNum;i++){for(j=0;j<4;j++){for(t=0;t<64;t++)buff[64*j+t]=SFR_Read(FIFO1);SFR_Write(EOUTCRSL,0x00);}PageNumL=2*(LBA+i-1);SPI_WRITE_Page(buff, 0, PageNumL);for(j=0;j<4;j++){for(t=0;t<64;t++)buff[64*j+t]=SFR_Read(FIFO1);SFR_Write(EOUTCRSL,0x00);}PageNumH=2*(LBA+i-1)+1;SPI_WRITE_Page(buff, 0, PageNumH);}}flags.epin1=1;csw=1;sendDebug(Write_10);sendDebug(LBA);sendDebug(PageNum); break;
總結(jié)
以上是生活随笔為你收集整理的电子工程师名片——FAT16文件系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 4305 Lightning (
- 下一篇: 关于更改CENTOS 7服务器的默认远程