hi,歡迎來到華秋商城 收藏我們 客服熱線:400-990-8686
問答首頁 最新問題 熱門問題 等待回答標簽廣場
我要提問

技術交流單片機

振南的znFAT-單片機上的FAT32文件系統 研發手記

#1樓主:znFAT--單片機上的FAT32文件系統 之研發手記文章發表于:2009-12-05 22:04

  

znFAT--單片機上的FAT32文件系統  之研發手記

兩年前,我開始學習DIY MP3,剛開始我只是直接把MP3文件的數據放在單片機的FLASH中,讀取播放。但這樣受限于單片機FLASH的容量,使得根本裝不下整首的MP3數據,頂多能播放7、8秒鐘。這就需要一種大容量的存儲器,你可能會說:“用大容量的FLASH ROM芯片就可以了”。不錯,用諸如K9F、45DB系列的FLASHROM芯片容量是夠大了,但此時也許你也跟我一樣碰到了一個問題,MP3文件怎么放入到FLASH芯片中?你可能會說“用燒錄器就可以了!”。我要問的話,你見過商場里哪款MP3播放器是需要燒錄器的?基本都是通過USB直接拷的,或者是可以擴展存儲卡,如SD卡、CF卡,甚至U盤。要用USB把FLASH芯片作成U盤,可以用PDIUSBD12來實現(如果您對這個感興趣可以看看computer00的USB),對USB有一定了解的,都會知道想把U盤作出來,還是非常復雜的。所以最簡單的方法就是使用存儲卡,一方面可以使用讀卡器,直接在操作系統中把MP3拷入其中,另一方面單片機驅動SD卡的相關資料也比較全,便于研究。

    文件系統的引出就由此而生!!問題是這樣的,將MP3文件拷入到SD卡中以后,下面我們要作的就是用單片機來讀取SD卡上的數據,以便于播放,拷入的MP3文件數據在SD卡的哪里啊?到哪個扇區中去讀啊?我們使用U盤或SD卡等存儲設備拷貝電影啊,歌曲啊,都是最平常的事情,你想過沒有,這些文件的數據存在SD卡上的什么地方嗎?它為什么要存在那個地方?

    為了找到SD卡上的MP3數據,我開始研究相關內容,這些就是FAT32文件系統。研究起來以后,發現已經有很多現成的在單片機上或在ARM等芯片上用的FAT文件系統方案,比如FATFS(這個是最為著名的一個,用得也最多)等等,國內也有幾個,比如沁恒的文件系統庫(不過他不開源,是商業的東西)、ZLG/FS(他提供的還是應用于ARM上的,在單片機應用的少)等。我也曾經向單片機(我剛開始用的是STC89C58,后來開始用STC12C5A60S2,不過這也是今年才開始用)上去移植這些現成的方案,但移植并不順利。最后我打算不再用任何現有方案,自己研究自己寫。

    于是我開始動手寫了一個最原始的方案,這個最原始的方案僅僅可以實現讀取根目錄下的某個文件,還非常不成熟,同時我在網上發了一篇文章《FAT32文件系統的存儲機制及其在單片機上的實現》(感興趣的話可以在網上找一下,不過這篇文章里講的非常膚淺)。我將這個文件系統方案的雛形用于MP3播放實驗,實現了讀SD卡MP3文件播放的功能。與此同時,我錄制了《51單片機實現FAT32文件系統》視頻教程(長達500分鐘),希望通過通俗全面的講解,讓廣大電子愛好者對文件系統有一個初頻的了解(不過,現在回想起來,錄制視頻教程的時候對文件系統的研究仍然還不算深刻)。因為我發現很多人雖然每天在用電腦,每天在聽MP3,每天在看電子書,但從不知道有文件系統這種東西存在,從來不納悶存在扇區中的數據在我們面前怎么就成為了一個個的文件。

    我的SD卡MP3的基本功能雖然實現了,但我又在想:“難道國內就不能有一款開源的,好用的FAT32文件系統的方案嗎?”。我在前期研究的基礎上,又開始進行更深入的研究。也許你可以在1個月內,甚至1個星期,把文件系統的相關技術手冊通讀N遍,也可能在理論上搞得很明白(當然需要較高的悟性),但這離最終的實現還相差甚遠,或者說只是剛剛起步。一些國外的研究文件系統的組織都是很多人一起傾注很大精力在作的,像EFSL(比利時的開源項目)、FATFS(上面已經提到,它是從大量的wince源代碼中剝離出的fat文件系統源代碼,微軟的代碼)等。它們會給我們使用,但不會講給我們他們是怎么實現的,更重要的一點是,它們一般用于AVR、ARM等芯片上,如果想要在51單片機上使用,不能說不能用,但因為硬件資源有限,所以用起來會有麻煩。所以,我才打算在RAM僅有1K字節的STC國產51單片機上真正作一套功能完備,方便移植的,性能較高,完全從0原創的文件系統方案。

    應用說這項工作工作量很大,主要是我不想僅僅去實現基本的功能,還希望能有功能上的創新。要實現的基本功能有:1、文件系統初始化 2、打開文件 3、讀取數據 4、文件重命名 5、復制文件 6、創建文件 7、添加數據 8、創建目錄 9、關閉文件  10、獲取剩余容量 11、獲取總容量  獨特具有的功能:我稱之為“多設備”(所謂的多設備功能,就是可以在運行的過程中動態的切換存儲設備的驅動,說明了就是文件系統可以穿梭于多種存儲設備之間,你會問這有什么用?我要說,這里所實現的每一項功能都有非常實際的應用,多設備最典型的應用就是可以在多種設備間進行文件的拷貝,如將SD卡上的某一文件拷貝到CF卡、U盤或是另一張SD卡上)

    最大的工作量并不在于寫代碼,而在于測試代碼和改代碼。就像讀數據的功能,讀從文件里讀1000個字節,沒有問題,讀10000字節呢?仍然不會出錯嗎?又如打開文件這一功能,如果目錄里有5個文件,要打開其中某個文件沒有問題,那能保證目錄里有10000個文件的時候,打開這個文件仍然沒有問題嗎?能打開根目錄下的文件沒有問題,打開\A\B\C\D\E\F\G\H\IJ\K\K\K\K\L\A.TXT這樣的深層目錄下的文件,也會沒問題嗎?寫入文件數據時,寫入1個字節沒問題,寫入10K的數據也照樣沒有問題嗎?............像這種類似的情況有很多。憑我一個人的力量是不夠的,我找了很多網友,給他用我的代碼,并將問題反饋給我,我再加以修改。還有一個很重要的途徑是通過一些公司實際的工程項目,因為他們會有專門測試的環境,比如頻繁讀數據、長時間的運行等等。很多問題會在此期間暴露出來。在修改代碼的過程中,時常還會發現一些以前沒有看到的FAT32更深層的東西。到現在為止,我的文件系統方案已經較為完備,在穩定性與正確性上得到了一定的保障。

    要著重說明的是所實現的一切功能,僅僅用了大約900字節的RAM,其中包括512字節的扇區數據緩沖。

    到后期,我的文件系統開始在網上開源,為了讓大家能記住它,我給它起名為znFAT(意為振南的FAT32文件系統方案)。僅僅有znFAT代碼是遠遠不夠的,大家感興趣還是使用znFAT來作的一些實驗,比如讀SD卡上的TXT文本文件,作電子書;讀SD卡上的MP3文件作播放器;讀SD卡上的BMP文件,作數碼相框;在SD卡與CF卡之間進行文件的互拷;甚至我自己用51的串口作了一個Shell命令接口,來通超級終端敲入命令來實現相應的文件操作(這就是我在網上起名為“仿DOS”的實驗)。令我欣慰的是,現在已經有人開始在用znFAT來作一些實驗了,說明znFAT真正被人們用起來了。雖然還沒有像FATFS等方案那樣流行,但它仍然是完全MIC(Made In China)的。

    代碼公布出來,并不意味著代碼就很成熟,反而會暴露出一些問題。其實最典型的一個問題就是:我提供的znFAT的代碼是基于51單片機的KEIL工程,但很多網友并不用51,而用像AVR、STM32、DSP、NIOSII等等。反應一些功能異常。這是對可移植性的很大考驗,可移植性要求在不同的硬件條件下,在代碼修改量不大的情況下,可以在其上運行,并且功能良好。所以我中途又搞了一陣子STM32(它是一種ARM7核的MCU),最終發現是不同CPU的差異而造成的,說得更具體一些是因為不同CPU的大小端問題。最終成功移植到STM32上,并將代碼在網上公布出來。與此同時,一個網友用LM的控制器也跑通了znFAT,并應用于項目,運行良好。

    znFAT從開始作,到現在已有1年多,這期間研究不斷深化,現在的znFAT與當初的雛形已有極大的發展。原來的視頻教程與文檔資料現在已經覺得比較膚淺,所以在打算錄制新的視頻教程,以求更多的人知道文件系統,知道它的重要。我要說,存儲設備的扇區讀寫好實現,而建立在扇區讀寫基礎上的文件系統的實現,才是思想真正的升華,對研發能力最大的考驗。

    為了更廣泛的普及文件系統的相關知識,也為了滿足很多對文件系統的需求和好奇(您難道沒有發現國內,乃至國外,還沒有一本專門講在嵌入式中構建和使用文件系統的書嗎?),在努力撰寫《振南的znFAT--單片機上的FAT32文件系統》一書。不地寫書過程漫長而辛苦,努力早日出來。

   振南贈語

振嚇四方博為旨,

南極北斗自來朝。

電摯山河獨標新,

子聚吾來弄天狼。

原點出發終有始,

創業何達必親為。

無盡峰端難攀登,

限在你我掌當中。

提問者:36切53 地點:- 瀏覽次數:4245 提問時間:10-22 16:55
我有更好的答案
提 交
18條回答
chunlan83768 08-04 18:37 回答數: 被采納數:
呵呵,我用在MP3播放的文件系統參考了很多沁恒公司的思想,只需512字節的扇區數據緩沖區,我覺得51單片機最好用FAT16文件系統,FAT32用在8位的51上面,速度慢.只需低速讀寫的應用另當別論.
陜西友航電子科技有限公司 07-28 13:01 回答數:0 被采納數:0
znFAT的應用絕不僅限于51
blueshine 08-03 07:31 回答數: 被采納數:
很多系統的核心是文件系統,文件系統作好,很多東西就可以作了
60user159 07-26 22:00 回答數:1 被采納數:0
您好,振南先生,我現在在DSP2812上使用您的znFAT文件系統,效果很好,可是有一個問題,我不能像操作Word一樣隨意的修改或刪除文件中的一部分,我現在是做數據采集,和存儲,每次存儲2048字節數據,當達到一定容量后再自動刪除文件頭部分的2048字節,可是2048字節小于一個簇4096字節,為了減少運行時間,我就直接修改的FAT文件表,讓首簇變為原來首簇的下一個簇,相當于進行了刪簇操作來減少4096字節,可是這樣不是長久的解決辦法啊,我能不能刪除隨意大小隨意位置的數據吶?
recoltd 08-02 01:17 回答數:0 被采納數:0
謝謝對znFAT的支持
你的意思是把文件數據整體向前移動2048字節嗎?
據我所知現有的所有文件系統方案都不能完成這一功能
如果你刪除了文件某個位置的數據,那個位置就會出現空余,要把后面的數據向前移動,這是比較費時間的。
你所用的方法也比較好,只是你多刪了2048字節
你可以用Disk Ginius這個軟件把你的SD卡格式化為簇大小為2048,這樣你用你的這種方法就可以實現了

你修改了FAT以后,有幾點要注意
1、要把原來的首簇設置為0x0000,即空簇
2、在文件的文件項中首簇更新為當前的首簇
3、更改文件項中的文件大小
4、更改FSINFO中的空閑簇數
5、更改FSINFO中的空簇參考值
糊涂忠1 08-04 03:09 回答數: 被采納數:
你好,謝謝振南先生的回答,您的意思是我無法像Word一樣操作,那Word里的文件操作,比如說刪除一段后點關閉保存時怎樣的操作吶?是吧文件內容完全讀進內存,修改完后然后再完全重新寫進去嗎?相當于向文件添加全部數據,文件其實偏移量為0?是嗎
zhan81411 07-26 22:03 回答數:0 被采納數:0
有時我還想隨意刪除文件頭部的任意長度的數據,您看有沒有好的方法啊,其實我現在是每采集8192點數據進行存儲,每個點數是16位整形,這樣8192點共占16384字節,就是4個簇的空間,在文件長度達到85M時自動刪除文件頭部的4個簇。這種方法我也實現了,現在是要在這8192點數據前加上時間信息,也就是說每一次存儲的數據正好比16384多一點,我想到文件達到85M是自動刪減這堆比16384多點的數據,讓每一次能在文件的開頭處看到時間信息,這樣能實現嗎
60user20 08-01 17:41 回答數:0 被采納數:0
在嵌入式中的文件操作,是不可能像在PC上那樣的,你如果要在文件頭上添加數據,就會造成后面數據大批的后移,效率極低。
你所說的WORD中,確實是在RAM中進行操作,最后再存入文件的,znFAT可以讓你自由向文件追加數據,可以定位到文件的某個位置,直接去修改數據,但你想實現在文件任意位置添加數據,就比較難,而且效率也很低。你可以預先把你要添加的數據預先留出來,以后可以到文件這個位置來改。
hzp_bbs1 08-05 00:14 回答數: 被采納數:
還有,不要叫我振南先生,我本身現在還是學生,叫我振南就好,或者叫ZN
凈小空空 07-29 10:12 回答數:0 被采納數:0
你好,振南,聽了你的解說,我清楚了,昨天仔細看了一下你說的這五點,前三項我是做了的,就是第四、五項,我沒有找見關于FSINFO的相關代碼,還不會做
1、要把原來的首簇設置為0x0000,即空簇
2、在文件的文件項中首簇更新為當前的首簇
3、更改文件項中的文件大小
4、更改FSINFO中的空閑簇數
5、更改FSINFO中的空簇參考值
這是我的程序,按找刪除文件的函數改寫的,沒有涉及到FSINFO啊?
void DeletData(struct FileInfoStruct *pfi)
{long Cluster1,Cluster2,Cluster3,Cluster_New_Start;
struct direntry *prec;
FAT32_ReadSector(pfi->Rec_Sec,FAT32_Buffer);//獲取頭四個簇,然后將其清空
prec=(struct direntry *)(FAT32_Buffer+pfi->nRec);
Cluster1=FAT32_GetNextCluster(pfi->FileStartCluster);
Cluster2=FAT32_GetNextCluster(Cluster1);
Cluster3=FAT32_GetNextCluster(Cluster2);
Cluster_New_Start=FAT32_GetNextCluster(Cluster3);//找尋到新的首簇 Cluster_New_Start
FAT32_Modify_FAT(pfi->FileStartCluster,0x00000000);
FAT32_Modify_FAT(Cluster1,0x00000000);
FAT32_Modify_FAT(Cluster2,0x00000000);
FAT32_Modify_FAT(Cluster3,0x00000000);

pfi->FileStartCluster=Cluster_New_Start; //更改文件首簇到Cluster_New_Start
pfi->FileSize=pfi->FileCurOffset-16384;//更改改文件大小
pfi->FileCurSector=SOC(pfi->FileCurCluster);
pfi->FileCurOffset=pfi->FileCurOffset-16384;
FAT32_ReadSector(pfi->Rec_Sec,FAT32_Buffer);//修改FAT表首簇號
(prec->deHighClust)[0]=(Cluster_New_Start&0x00ff0000)>>16;
(prec->deHighClust)[1]=(Cluster_New_Start&0xff000000)>>24;
(prec->deLowCluster)[0]=(Cluster_New_Start&0x000000ff);
(prec->deLowCluster)[1]=(Cluster_New_Start&0x0000ff00)>>8;
? ?FAT32_WriteSector(pfi->Rec_Sec,FAT32_Buffer);

??FAT32_ReadSector(pfi->Rec_Sec,FAT32_Buffer);//修改文件大小
??(((struct direntry *)(FAT32_Buffer+pfi->nRec))->deFileSize)[0]=((pfi->FileCurOffset)&0x000000ff);
??(((struct direntry *)(FAT32_Buffer+pfi->nRec))->deFileSize)[1]=((pfi->FileCurOffset)&0x0000ff00)>>8;
??(((struct direntry *)(FAT32_Buffer+pfi->nRec))->deFileSize)[2]=((pfi->FileCurOffset)&0x00ff0000)>>16;
??(((struct direntry *)(FAT32_Buffer+pfi->nRec))->deFileSize)[3]=((pfi->FileCurOffset)&0xff000000)>>24;
??FAT32_WriteSector(pfi->Rec_Sec,FAT32_Buffer);
}
riverdj 07-28 15:52 回答數: 被采納數:
FAT32與FAT16不同點之一就是FAT32有FSINFO,其中就可以直接讀出來磁盤剩余容量和下一個可以用的空閑簇,當然FSINFO也需要程序來進行維護。

也許你有這種經歷,使用CH375配套的沁恒文件系統庫時,在獲取U盤的剩余容量時,FAT32可以馬上得到結果,而FAT16就要等一段時間才能得到結果。就是因為FAT16沒有FSINFO,所以程序要由FAT表來統計容量,這時間就長了。

FSINFO是我研發文件系統后期才發現的一個區域。它的位置在DBR的后一個扇區
gwerwfe 08-01 22:50 回答數:0 被采納數:0
呵呵,等你的書出了在看看先,??我看過你那個文件系統,? ?一團亂碼,? ?或許是我功力不夠吧,
朱振振振 08-01 10:50 回答數:0 被采納數:0
由于文件系統本身的復雜性,如果沒有基礎,看起來確實就是一團亂碼
正是由于文件系統代碼有些龐雜,所以才有了出書的念頭,讓帶讀者一起來剖析
我盡力讓代碼條理清晰一些,方便大家的學習和使用
謝謝
qwer38 07-26 10:08 回答數: 被采納數:
標記一下有時間好好研究一下
limisy 07-31 01:27 回答數: 被采納數:
如果要做商業應用,可能更多人會選擇大公司開發的,比如ZLG,MICROCHIP,這是我了解到的。
wmc55555 07-28 12:11 回答數: 被采納數:
如果你不打算把這個FAT做到中國知名以及于知名度匹配的完善,以便有更多的人能用于商業應用,把這個時間抽出來做其它,你可以得到更全面的提高。
技術員都有玩技術的傾向,但是做產品開發,卻最怕技術員玩技術。而技術員如果太喜歡玩技術,而不是更多考慮產品和自己的發展,也是不大好。不過趁著還是學生,多玩一下技術是好的,畢業了,就沒那么多時間了。加油。
ywujwerwx 07-27 04:17 回答數:0 被采納數:0
znFAT剛開始源于興趣,已經作了1年多,中間經歷無數次測試,包括多次在工程上的應用。也暴露出無數的問題,都在發現后得到我改進和修復。從而保證其正確性與穩定性。
znFAT的研發初衷在于解決實際的問題,滿足實現的需求。是希望它能被更多人知道,更多人用起來,我把代碼全部開源的原因也就在于此。
不光用起來,還讓有興趣的人可以有機會來研究學習。這就是要出教程與書的原因了。

學生確實是喜歡玩技術,把技術當成是玩具來找樂趣。本身我現在是研三的學生,現在的時間確實不多了。
盡力把自己研究的東西作到完善。
當然希望有更多的人來用我的znFAT,來感覺它到底怎么樣。
在EDNCHINA那邊有小組我已經發了10個應用實例,大家可以過去看看。
http://group.znmcu.cn/
loujie39 07-29 21:07 回答數: 被采納數:
FATFS ZLGFS UCFS固然好,但它不會配上教程,配上書,告訴你它是怎么實現的,內部技術有哪些,細節是怎樣的,如果要自己寫文件系統方案,應該怎么作。這是我研究文件系統的初衷。
撰寫答案
提 交
相關技術交流
單片機軟硬件復位的條件都有啥
電動機的單片機控制
mos管驅動感性負載的問題
有用過BTS6143D高邊驅動開關作為感性負載的驅動的嗎
求助 關于單片機與485總線 命令幀的發送和響應幀的接收
相關單片機
具有音調控制的單片機立體聲前置放大器
用于單片機與電子裝置中的開關電源
單片機軟硬件復位的條件都有啥
電動機的單片機控制
帶二線串行接口智能溫度傳感器TCN75與89C51單片機的接口電路圖
排列5预测最准专家 小罐茶专卖店赚钱吗 15选5 男人多运动 赚钱更多 雷速体育比分直 批发吉他赚钱吗 邢台麻将作弊器免费版 竞彩比分直播500即时比分 一品大宰相怎么快速赚钱 浙江快乐12 小区里炸油条赚钱吗 即时赔率亚洲赔率澳门赔率 如意娱乐群 怎么挂wow赚钱吗 四川快乐12 厦门开超市赚钱吗 开鱼具店赚钱吗哪里进货