版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
《操作系統(tǒng)課程設計》報告《操作系統(tǒng)課程設計》報告專業(yè)班級:計科1106班姓名:李育洪、胡壯劉春林、鄧程峰指導老師:李璽設計時間:2014年6月目錄概論·······································3設計的基本概念和原理·······················4總體設計···································6詳細設計···································8系統(tǒng)的測試和運行···························18系統(tǒng)的使用說明·····························20課程設計總結(jié)·······························21參考資料···································22
概論課程設計的內(nèi)容本次課程設計我們是四個人的小組,我們選擇的是第三個題目,題目的描述如下:在uC/OS操作系統(tǒng)中增加一個簡單的文件系統(tǒng),要求如下:熟悉并分析uc/os操作系統(tǒng)設計并實現(xiàn)一個簡單的文件系統(tǒng)可以是存放在內(nèi)存的虛擬文件系統(tǒng),也可以是存放在磁盤的實際文件系統(tǒng)編寫測試代碼,測試對文件的相關(guān)操作:建立,讀寫等課程設計的目的操作系統(tǒng)課程主要講述的內(nèi)容是多道操作系統(tǒng)的原理與技術(shù),與其它計算機原理、編譯原理、匯編語言、計算機網(wǎng)絡、程序設計等專業(yè)課程關(guān)系十分密切。本課程設計的目的綜合應用學生所學知識,建立系統(tǒng)和完整的計算機系統(tǒng)概念,理解和鞏固操作系統(tǒng)基本理論、原理和方法,掌握操作系統(tǒng)開發(fā)的基本技能。要解決的主要問題通過對題目的分析,以及對相關(guān)資料的查閱,我們決定為μC/OS-II寫一個FAT32文件系統(tǒng)。那么,我們要解決的主要問題就有:掌握μC/OS-II的基本原理,并能在μC/OS-II上用C語言進行程序設計;μC/OS-II開發(fā)環(huán)境的建立。由于我們沒有嵌入式的硬件設備,所以在PC上進行開發(fā)。于是就需要把μC/OS-II一直到windows下,用VC++作為開發(fā)環(huán)境;了解FAT32文件系統(tǒng)的底層細節(jié)。必須要有FAT32這種文件系統(tǒng)的詳細說明。手動實現(xiàn)FAT32文件系統(tǒng)。測試。必須保證文件系統(tǒng)能在μC/OS-II下運行。設計的基本概念和原理2.1μC/OS-II簡介μC/OS-II由Micrium公司提供,是一個可移植、可固化的、可裁剪的、占先式多任務實時內(nèi)核,它適用于多種微處理器,微控制器和數(shù)字處理芯片(已經(jīng)移植到超過100種以上的微處理器應用中)。同時,該系統(tǒng)源代碼開放、整潔、一致,注釋詳盡,適合系統(tǒng)開發(fā)。μC/OS-II已經(jīng)通過聯(lián)邦航空局(FAA)商用航行器認證,符合航空無線電技術(shù)委員會(RTCA)DO-178B標準。μC/OS-II可以大致分成核心、任務處理、時間處理、任務同步與通信,CPU的移植等5個部分。核心部分是操作系統(tǒng)的處理核心,包括操作系統(tǒng)初始化、操作系統(tǒng)運行、中斷進出的前導、時鐘節(jié)拍、任務調(diào)度、事件處理等多部分。能夠維持系統(tǒng)基本工作的部分都在這里。任務處理部分任務處理部分中的內(nèi)容都是與任務的操作密切相關(guān)的。包括任務的建立、刪除、掛起、恢復等等。因為μC/OS-II是以任務為基本單位調(diào)度的,所以這部分內(nèi)容也相當重要。時鐘部分μC/OS-II中的最小時鐘單位是timetick(時鐘節(jié)拍)。任務延時等操作是在這里完成的。任務同步和通信部分為事件處理部分,包括信號量、郵箱、郵箱隊列、事件標志等部分;主要用于任務間的互相聯(lián)系和對臨界資源的訪問。與CPU的接口部分是指μC/OS-II針對所使用的CPU的移植部分。由于μC/OS-II是一個通用性的操作系統(tǒng),所以對于關(guān)鍵問題上的實現(xiàn),還是需要根據(jù)具體CPU的具體內(nèi)容和要求作相應的移植。這部分內(nèi)容由于牽涉到SP等系統(tǒng)指針,所以通常用匯編語言編寫。主要包括中斷級任務切換的底層實現(xiàn)、任務級任務切換的底層實現(xiàn)、時鐘節(jié)拍的產(chǎn)生和處理、中斷的相關(guān)處理部分等內(nèi)容。2.2μC/OS-II在VC++下的移植為了開發(fā)環(huán)境的方便,需要將μC/OS-II移植到VC++上。移植主要有三步,下面作簡要說明。詳細的方法可以參考《嵌入式實時操作系統(tǒng)μC/OS原理與實踐》一書。VC下時鐘的獲得可以使用采用軟件定時器來模擬時鐘中斷。這里我們采用的是timeSetEvent()函數(shù)。這個函數(shù)很簡單,不需要消息循環(huán),定時精度為ms級,主要應用在多媒體定時方面,能夠在非常精確的時間間隔內(nèi)完成一個事件、函數(shù)或過程的調(diào)用??梢酝ㄟ^調(diào)用timeSetEvent()函數(shù),將需要周期性執(zhí)行的任務定義在LpTimeProc回調(diào)函數(shù)中,從而完成所需處理的事件。調(diào)用這個函數(shù)后會增加一個線程,時間一到則在這個線程中調(diào)用回調(diào)函數(shù),對于主線程來說,非常類似外部中斷調(diào)用,我們需要的正是這樣的效果。模擬時鐘中斷的產(chǎn)生中斷指的是中止當前的事務,處理別的更要緊的事情。我們通過軟件定時器來模擬產(chǎn)生uC/OS-II的時鐘中斷,但timeSetEvent()函數(shù)調(diào)用定時回調(diào)函數(shù)是和主線程同時被windows操作系統(tǒng)調(diào)度的,并沒有起到中斷的作用。所以在調(diào)用定時回調(diào)函數(shù)的時候必須停止主線程的運行,退出回調(diào)函數(shù)則恢復主線程的運行,自然這些事情可以都放在定時回調(diào)函數(shù),也就是uC/OS-II的時鐘中斷處理函數(shù)中完成。Windows下要掛起一個線程的運行,首先要得到這個線程的句柄,然后調(diào)用SuspendThread(hangdler)和ResumeThread(handler)就可以掛起和繼續(xù)執(zhí)行線程。任務切換任務切換,其實做的是任務的上下文切換,在其他CPU上非常容易分辨出任務的上下文,一般就是CPU上的相應寄存器,那么在VC下呢?從簡單考慮,我們選擇了不帶浮點運算的上下文環(huán)境,因此任務的上下文和uC/OS-II在80x86上移植的上下文很相近,不同點只是段寄存器不用保存,因為在VC下任務其實只是在同一個線程中切換,而且在保護模式下段寄存器的概念已變,其值在同一個線程中是不會變的。2.3FAT32文件系統(tǒng)格式FAT32是Windows系統(tǒng)硬盤分區(qū)格式的一種。這種格式采用32位的文件分配表,使其對磁盤的管理能力大大增強,突破了FAT16對每一個分區(qū)的容量只有2GB的限制。由于現(xiàn)在的硬盤生產(chǎn)成本下降,其容量越來越大,運用FAT32的分區(qū)格式后,我們可以將一個大硬盤定義成一個分區(qū)而不必分為幾個分區(qū)使用,大大方便了對磁盤的管理。目前已被性能更優(yōu)異的NTFS分區(qū)格式所取代。一個FAT文件系統(tǒng)包括四個不同的部分:保留扇區(qū)、FAT區(qū)域、根目錄區(qū)域、數(shù)據(jù)區(qū)域。對于FAT32的具體說明可以參考微軟官網(wǎng)上關(guān)于FAT32的白皮書,網(wǎng)址:HYPERLINK。總體設計嵌入式文件系統(tǒng)由于功能和作用與普通桌面操作系統(tǒng)的文件系統(tǒng)不同,導致了二者在體系結(jié)構(gòu)上具有很大的差異性。在普通桌面操作系統(tǒng)中,文件系統(tǒng)不僅要管理文件,提供文件系統(tǒng)調(diào)用API,還要管理各種設備,支持對設備和文件操作的一致性(即要像操作文件一樣來操作各種I/O設備)。在嵌入式文件系統(tǒng)中,這種規(guī)則發(fā)生了很大的變化。在某些情況下,嵌入式系統(tǒng)可以針對特殊的目的來進行定制,特別是隨著ASOS(為應用定制的嵌入式操作系統(tǒng))的發(fā)展,對嵌入式操作系統(tǒng)的系統(tǒng)功能規(guī)整性、可伸縮性及其靈活性提出了更高的要求。基于以上的考慮,我們采用了下圖所示的嵌入式文件系統(tǒng)體系結(jié)構(gòu),該結(jié)構(gòu)定義的文件系統(tǒng)從上到下有三個層次:第一層為API層、第二層為中間轉(zhuǎn)換層、下層為介質(zhì)驅(qū)動層。第一層:API層。API層是文件系統(tǒng)和用戶應用程序之間的接口,它有一個標準C函數(shù)庫,其中包含有諸如打開文件(f_open)、寫文件(f_write)等函數(shù)。本層的功能是將用戶調(diào)用傳送給中間轉(zhuǎn)換層。這是整個系統(tǒng)設計的核心,也是嵌入式文件系統(tǒng)中用戶唯一可見的部分。第二層:中間轉(zhuǎn)換層。中間轉(zhuǎn)換層要為文件系統(tǒng)的實現(xiàn)提供與硬件無關(guān)的統(tǒng)一接口,是文件系統(tǒng)結(jié)構(gòu)規(guī)整性的基礎。中間轉(zhuǎn)換層包含有文件系統(tǒng)子層及邏輯塊子層,其中文件系統(tǒng)子層將文件操作解釋到邏輯塊子層,然后文件系統(tǒng)調(diào)用邏輯塊子層并根據(jù)不同的設備定義出相應的設備驅(qū)動程序;邏輯塊子層主要是同步對設備驅(qū)動程序的訪問,向上提供友好界面。第三層:介質(zhì)驅(qū)動層。介質(zhì)驅(qū)動層是訪問硬件的最低端的程序,該程序的結(jié)構(gòu)要能夠便于實現(xiàn)對硬件的訪問。本層的功能主要是完成對介質(zhì)的訪問。本層的重要任務就是提供統(tǒng)一的設備驅(qū)動程序接口。根據(jù)文件系統(tǒng)的層次結(jié)構(gòu),可以將該文件系統(tǒng)分成三大功能塊:API接口模塊、中間轉(zhuǎn)換模塊、設備驅(qū)動模塊。其中API接口模塊主要完成文件的基本操作,包含有文件的生成、刪除、打開、關(guān)閉、文件讀、文件寫等。中間轉(zhuǎn)換模塊主要完成對存取權(quán)限的檢查、介質(zhì)的選擇、邏輯到物理的轉(zhuǎn)換。設備驅(qū)動模塊完成存儲介質(zhì)的驅(qū)動程序,包含有一個驅(qū)動程序函數(shù)表和介質(zhì)讀、介質(zhì)寫、檢查狀態(tài)、執(zhí)行特定命令等驅(qū)動程序。詳細設計總體設計完成之后,就可以幾種精力進行詳細設計。根據(jù)總體設計劃分的模塊,一個模塊一個模塊進行詳細設計。4.1文件系統(tǒng)對外提供的主要接口1、FRESULTf_open(FIL*,constchar*,BYTE);函數(shù)功能:打開或者創(chuàng)建一個文件2、FRESULTf_read(FIL*,BYTE*,WORD,WORD*);函數(shù)功能:讀一個文件3、FRESULTf_close(FIL*);函數(shù)功能:關(guān)閉一個文件4、FRESULTf_opendir(DIR*,constchar*);函數(shù)功能:讀一個目錄中的目錄項5、FRESULTf_readdir(DIR*,FILINFO*);函數(shù)功能:讀取目錄的內(nèi)容6、FRESULTf_stat(constchar*,FILINFO*);函數(shù)功能:獲取文件的狀態(tài)7、FRESULTf_mountdrv();函數(shù)功能:初始化文件系統(tǒng)8、FRESULTf_write(FIL*,constBYTE*,WORD,WORD*);函數(shù)功能:寫文件9、FRESULTf_sync(FIL*);函數(shù)功能:同步文件緩沖區(qū)的內(nèi)容到磁盤中10、FRESULTf_delete(constchar*);函數(shù)功能:刪除一個文件或者目錄11、FRESULTf_mkdir(constchar*);函數(shù)功能:創(chuàng)建一個目錄這就是文件系統(tǒng)提供的全部功能,靈活地運用上述函數(shù),就可以編寫出復雜的應用程序。4.2文件系統(tǒng)的主要數(shù)據(jù)結(jié)構(gòu)1)UCFS結(jié)構(gòu)體/*文件系統(tǒng)結(jié)構(gòu)體,保存文件系統(tǒng)的有關(guān)信息*/typedefstruct{BYTEfs_type;//文件系統(tǒng)類型BYTEfiles;//當前已打開的文件的數(shù)目BYTEsects_clust;//每個簇的扇區(qū)數(shù)BYTEn_fats;//FAT表的數(shù)目WORDn_rootdir;//根目錄數(shù)(在FAT32中為0)BYTEwinflag;//標記文件是否被改動過,為1時要回寫B(tài)YTEpad1;//站位,字節(jié)對齊DWORDsects_fat;//每個FAT表所占的扇區(qū)數(shù)DWORDmax_clust;//總的簇數(shù)DWORDfatbase;//FAT區(qū)的起始扇區(qū)DWORDdirbase;//根目錄區(qū)的起始扇區(qū)DWORDdatabase;//數(shù)據(jù)區(qū)的起始扇區(qū)DWORDwinsect;//當前緩沖區(qū)中存儲的扇區(qū)號BYTEwin[512];//單個扇區(qū)緩存}UCFS;UCFS結(jié)構(gòu)體記錄了文件系統(tǒng)的所有信息,有了這個結(jié)構(gòu)體,就可以方便地訪問文件系統(tǒng)的每一部分。2)DIR結(jié)構(gòu)體//目錄結(jié)構(gòu)體,表示一個目錄typedefstruct{DWORDsclust;//起始簇DWORDclust;//當前簇DWORDsect;//當前扇區(qū)WORDindex;//當前索引}DIR;作為目錄項的指針,既可以用于記錄一個特定文件在目錄中的位置,又可以用于記錄在目錄中當前目錄項指針的位置(類似于文件指針)。FIL結(jié)構(gòu)體//文件結(jié)構(gòu)體,表示一個文件typedefstruct{DWORDfptr;//文件讀寫指針DWORDfsize;//文件大小DWORDorg_clust;//文件起始簇DWORDcurr_clust;//當前簇(fsize=0時為0)DWORDcurr_sect;//當前扇區(qū)DWORDdir_sect;//此文件的目錄項所在的扇區(qū)BYTE*dir_ptr;//指向文件目錄項的指針BYTE*buffer;//文件讀寫緩沖區(qū)BYTEflag;//文件狀態(tài)標識BYTEsect_clust;//當前簇中剩余的扇區(qū)數(shù)}FIL;記錄普通文件(不是目錄文件)的詳細信息,比如文件對應的目錄項位置,文件起始簇號,文件指針,文件大小等。FILINFO結(jié)構(gòu)體//文件信息的結(jié)構(gòu)體,也可以表示目錄,用fattrib區(qū)分typedefstruct_FILINFO{DWORDfsize;//文件大小WORDfdate;//文件修改日期WORDftime;//文件修改時間BYTEfattrib;//文件屬性charfname[13];//文件名(8.3格式)}FILINFO;win[512]數(shù)組位于FATFS結(jié)構(gòu)體中,作為目錄項或者FAT分配表的讀寫緩沖區(qū)。它不是某一個文件專有的緩沖區(qū),而是整個文件系統(tǒng)的公共讀寫緩沖區(qū)。buffer指針buffer是一個指向512字節(jié)緩沖區(qū)的指針,位于FIL結(jié)構(gòu)體中,也就相當于是FIL中有一個512字節(jié)緩沖區(qū)的成員。此512字節(jié)的緩沖區(qū),是一個文件的專有緩沖區(qū)。用于當文件的讀寫沒有按照512字節(jié)對齊的時候,作為磁盤與用戶讀寫緩沖區(qū)之間的臨時緩沖區(qū)。4.3各個函數(shù)的詳細實現(xiàn)1)move_window函數(shù)原型:BOOLmove_window(DWORDsector)函數(shù)功能:win[]操作函數(shù)(DBR、FAT表、目錄項)<1>讀取新的扇區(qū)內(nèi)容到臨時緩沖區(qū)win[]<2>同步win[]中的內(nèi)容到磁盤注意:<1>如果讀取新的扇區(qū)號就是現(xiàn)在存儲在win[]中的扇區(qū)號,就什么也不操作<2>如果不同,則根據(jù)情況同步win[]到磁盤中,并且將新扇區(qū)中的內(nèi)容讀取到win[]中<3>如果sector為0,則函數(shù)功能變?yōu)橥絯in[]到磁盤中,不會讀取0扇區(qū)的內(nèi)容到win[]輸入?yún)?shù):sector要讀取扇區(qū)的扇區(qū)號與其他函數(shù)的關(guān)系:此函數(shù)被下列函數(shù)直接或間接調(diào)用第一類:操作FAT表① get_cluster② put_cluster③ remove_chain④ create_chain第二類:操作MBR、DBR⑤ check_fs第三類:操作目錄項所在扇區(qū)(目錄的數(shù)據(jù)空間)⑥ trace_path程序的實現(xiàn)方法:首先判斷要讀取的扇區(qū)號是否與當前緩存在win[]中的扇區(qū)號一致。倘若一致,則無需執(zhí)行任何操作。倘若不一致,再判斷緩存在win[]中的內(nèi)容是否被修改過,如果修改過,就需要更新到磁盤,最后還要把新扇區(qū)中的內(nèi)容加載到win[]中。當傳入?yún)?shù)0時,0與當前緩存在win[]的扇區(qū)號肯定不一樣,所以一定會同步win[]內(nèi)容到磁盤中。2)f_mountdrv函數(shù)原型:FRESULTf_mountdrv()函數(shù)功能:初始化磁盤;初始化UcFs對象,記錄物理磁盤的相關(guān)參數(shù)。函數(shù)實現(xiàn)方法:首先調(diào)用磁盤初始化函數(shù),對磁盤進行初始化。然后讀取物理磁盤0號扇區(qū)的內(nèi)容,判斷是否是DBR扇區(qū)。如果不是DBR扇區(qū),那么肯定就是MBR扇區(qū),再從MBR扇區(qū)中獲取DBR扇區(qū)的地址,將DBR扇區(qū)的內(nèi)容調(diào)取到win[]中。接下來從win[]中,填充UCFS類型的系統(tǒng)對象,這樣物理磁盤和文件系統(tǒng)的參數(shù)就被保存到了這個對象中。以后,程序就可以從全局變量--UcFs類型的變量,訪問文件系統(tǒng)的每一個區(qū)域。3)f_open函數(shù)原型:FRESULTf_open(FIL*fp,constchar*path,BYTEmode)函數(shù)功能:以指定的方式打開或者新建一個文件。如果打開或者創(chuàng)建成功,會填充fp指向的文件信息變量(包含文件的目錄項確切位置和文件的信息)。函數(shù)參數(shù):fp 指向文件信息變量的指針path 指向文件的路徑mode 打開方式輸出參數(shù):FR_OK打開或者創(chuàng)建成功其他值打開或者創(chuàng)建失敗函數(shù)實現(xiàn)方法:以只讀的方式打開一個已經(jīng)存在的文件首先調(diào)用函數(shù)trace_path搜索文件系統(tǒng)中是否存在目標文件,如果不存在就返回失??;如果存在就返回文件的目錄項位置(dirscan、dir),并且將目錄項所在扇區(qū)的內(nèi)容加載到win[]中。接下來就是從win[]中,將文件目錄項的參數(shù)稍作轉(zhuǎn)化后傳入FIL類型的變量中。到此,一個文件就算完整的打開了。注意打開文件并不是打開文件的內(nèi)容,而是文件的目錄項,知道了文件的目錄項就知道了如何去查看文件的內(nèi)容。以后,通過FIL類型的變量就可以操作對應的文件。② 新建一個文件首先調(diào)用函數(shù)trace_path搜索文件系統(tǒng)中是否存在目標文件,因為是新建文件肯定不存在。那么不存在的文件就返回新建文件當前文件夾的目錄指針位置(dirscan、dir)--第一個空目錄項所在位置,并且將當前目錄指針所在扇區(qū)的內(nèi)容加載到win[]中。首先給新建文件在當前文件夾中預定一個目錄項位置,然后填入新建文件的目錄項初始值(文件名、擴展名、屬性、創(chuàng)建時間、更新時間)到win[]中。注意這里并不會將新建文件目錄項所在扇區(qū)同步到磁盤中,只有當調(diào)用f_sync函數(shù)時才會將文件的目錄項所在扇區(qū)同步到磁盤。創(chuàng)建一個新文件,只會在其上一層目錄中添加對應的目錄項并初始化,并不會給文件分配數(shù)據(jù)空間,當然文件的大小肯定是0。③ 重建一個文件首先調(diào)用函數(shù)trace_path搜索文件系統(tǒng)中是否存在目標文件,因為是重建文件肯定存在。那么就返回文件的目錄項位置(dirscan、dir),并且將目錄項所在扇區(qū)的內(nèi)容加載到win[]中。重建首先將文件的簇鏈刪除,然后設置文件起始位置和文件大小為空,還需要初始化文件的屬性、創(chuàng)建時間和修改時間。這里的修改都只是在win[]中進行的,并沒有同步到磁盤。只有當調(diào)用f_sync函數(shù)時才會將文件的目錄項所在扇區(qū)同步到磁盤。重建文件更改了原來文件在目錄中的目錄項信息,重建文件并沒有分配簇,也就是沒有分配數(shù)據(jù)空間。4)f_read函數(shù)原型:FRESULTf_read(FIL*fp,BYTE*buff,WORDbtr,WORD*br)函數(shù)功能:文件讀操作輸入?yún)?shù):fp 文件信息指針buff指向用戶緩沖區(qū)btr 準備讀取的字節(jié)數(shù)br 指向?qū)嶋H讀取字節(jié)數(shù)的變量輸出參數(shù):FRESULT成功與否備注:函數(shù)在讀取文件內(nèi)容后,還會移動文件指針到下一此讀寫操作的起點。函數(shù)的實現(xiàn)方法:讀文件的情況有些復雜,不同的情況有不同的處理方法。開始讀的時候,文件指針并沒有位于扇區(qū)邊界上(512字節(jié)對齊),讀取的跨度為3個簇。首先讀沒有對齊扇區(qū)的剩余內(nèi)容,其實這個內(nèi)容在以前的函數(shù)(以前的函數(shù)移動了文件指針)已經(jīng)將這個扇區(qū)的內(nèi)容加載到了buffer中。所以,直接從緩沖區(qū)buffer中讀取此扇區(qū)文件指針以后的剩余內(nèi)容到用戶緩沖區(qū)。接下來,讀取第一個簇的剩余一個扇區(qū)的內(nèi)容到用戶緩沖區(qū)。通過get_cluster函數(shù)從FAT表中,獲取第二個簇鏈的位置。然后一次性的將一個簇鏈的所有扇區(qū)內(nèi)容讀取到用戶緩沖區(qū)中。再通過get_cluster函數(shù)從FAT表中,獲取第三個簇鏈的位置。然后將第三個簇鏈的第一個扇區(qū)內(nèi)容讀取到用戶緩沖區(qū)中。最后,將最后所需要讀取剩余內(nèi)容所在的扇區(qū)(剩余部分不夠一個扇區(qū))讀取到buffer中,然后再從buffer中讀取所需要的剩余內(nèi)容到用戶緩沖區(qū)中。到這里為止,整個讀取操作已經(jīng)完成。由于buffer中還有一部分內(nèi)容沒讀,假設繼續(xù)調(diào)用函數(shù)f_read函數(shù)讀取數(shù)據(jù),那么肯定先從這個buffer緩沖區(qū)中將文件指針以后的扇區(qū)剩余內(nèi)容讀取到用戶緩沖區(qū)。5)f_write函數(shù)原型:FRESULTf_write(FIL*fp,constBYTE*buff,WORDbtw,WORD*bw)函數(shù)功能:文件寫操作,只對文件的數(shù)據(jù)區(qū)進行寫入,并沒有更新對應的目錄項。輸入?yún)?shù):fp文件信息指針 buff指向讀取的用戶緩沖區(qū) btw準備寫入的字節(jié)數(shù) bw返回實際寫入的字節(jié)數(shù)輸出參數(shù):FRESULT成功與否備注:函數(shù)在寫完文件內(nèi)容后,還會移動文件指針到下一此讀寫操作的起點。函數(shù)的實現(xiàn)方法:寫文件的情況與讀取文件內(nèi)容類似。開始寫的時候,文件指針并沒有位于扇區(qū)邊界上(512字節(jié)對齊),寫入數(shù)據(jù)的跨度為3個簇。首先寫入沒有對齊扇區(qū)的剩余內(nèi)容,其實這個內(nèi)容在以前的函數(shù)(以前的函數(shù)移動了文件指針)已經(jīng)將這個扇區(qū)的內(nèi)容加載到了buffer中。所以,將用戶緩沖區(qū)中對應的內(nèi)容寫入到buffer中(從文件指針開始到buffer結(jié)束的這部分空間)。然后再將buffer中的內(nèi)容寫入到磁盤對應的扇區(qū)。接下來,將用戶緩沖區(qū)寫入到第一個簇的剩余一個扇區(qū)中。通過creat_chain函數(shù)從FAT表中,獲取第二個簇鏈的位置(如果是文件有剩余簇鏈則使用文件的剩余簇鏈,如果已經(jīng)用完則重新從FAT表中搜索一個空的簇鏈連接到此文件中,也就是更改了文件的大?。?。然后一次性的將用戶緩沖區(qū)寫入到第二個簇鏈的所有扇區(qū)中。再通過get_cluster函數(shù)從FAT表中,獲取第三個簇鏈的位置。然后將用戶緩沖區(qū)寫入到第三個簇鏈的第一個扇區(qū)中。最后,將最后所需要寫入剩余內(nèi)容所在的扇區(qū)(剩余部分不夠一個扇區(qū))讀取到buffer中,然后再將用戶緩沖區(qū)中剩余內(nèi)容寫入到buffer中。到這里為止,整個讀取操作已經(jīng)完成。注意這里并沒有將buffer的內(nèi)容寫入到磁盤中。當調(diào)用f_sync函數(shù)的時候才會將buffer的內(nèi)容同步到磁盤。在函數(shù)返回之前,還需要判斷文件大小是否更改了,如果大小更改了則要更新文件的大小,并將FA__WRITTEN記錄到文件的flag中。這樣做的目的是為了當執(zhí)行f_sync時,可以根據(jù)FA__WRITTEN判斷出文件修改過,從而更新文件的目錄項。6)f_sync函數(shù)原型:FRESULTf_sync(FIL*fp)函數(shù)功能:在關(guān)閉文件之前,同步文件緩沖區(qū)中的內(nèi)容到磁盤,同步文件目錄項信息到磁盤。輸入?yún)?shù):fp文件信息指針輸出參數(shù):FRESULT成功與否函數(shù)實現(xiàn)方法:判斷文件是否修改過,如果修改過再判斷文件buffer緩沖區(qū)是否修改過,如果修改過則同步到磁盤中文件對應的數(shù)據(jù)空間中。如果文件修改過,還要更新文件的目錄項,這時的修改也是在win[]中的。最后通過調(diào)用move_window(0),將文件目錄項信息同步到磁盤中。7)f_opendir函數(shù)原型:FRESULTf_opendir(DIR*scan,constchar*path)函數(shù)功能:打開一個目錄輸入?yún)?shù):scan指向返回找到的目錄項結(jié)構(gòu)體 path指向路徑輸出參數(shù):FRESULT成功與否函數(shù)的實現(xiàn)方法:首先調(diào)用函數(shù)trace_path搜索文件系統(tǒng)中是否存在所要打開的目錄,如果不存在就返回失?。蝗绻嬖诰头祷啬夸泴夸涰椀奈恢茫╠irscan、dir),并且將目錄對應目錄項所在扇區(qū)的內(nèi)容加載到win[]中。接下來判斷找到的是不是一個目錄。如果就是一個目錄的話,就從win[]中將目錄對應目錄項的參數(shù)稍作轉(zhuǎn)化后傳入DIR類型的變量中。到此,一個目錄就算完整的打開了。注意打開目錄并不是打開目錄的內(nèi)容,而是目錄對應的目錄項,知道了目錄對應的目錄項就知道了如何去查看目錄的內(nèi)容。以后,通過DIR類型的變量就可以操作對應的目錄。8)f_mkdir函數(shù)原型:FRESULTf_mkdir(constchar*path)函數(shù)功能:創(chuàng)建一個目錄新建一個目錄,它雖然是一個空目錄(有效存儲內(nèi)容為0),但是系統(tǒng)已經(jīng)為它分配了一個簇的數(shù)據(jù)空間,用于保存它的目錄項。這是與新建一個普通文件區(qū)別很大的地方。另外,新建一個目錄時,對新建目錄在上一層目錄的目錄項以及新建目錄中的目錄項的初始化,全部都在win[]中進行操作。輸入?yún)?shù):path指向路徑的指針輸出參數(shù):FRESULT成功與否函數(shù)的實現(xiàn)方法:首先調(diào)用函數(shù)trace_path搜索文件系統(tǒng)中是否存在目標目錄,因為是新建目錄肯定不存在。那么不存在目錄時就返回新建目錄所在當前文件夾的目錄指針(dirscan、dir)--第一個空目錄項位置,并且將當前目錄指針所在扇區(qū)的內(nèi)容加載到win[]中。接下來給新建目錄在當前文件夾中預定一個目錄項位置。然后調(diào)用creat_chain函數(shù)在FAT表中為新建目錄找到一個可用的數(shù)據(jù)簇,再調(diào)用move_window(0)同步FAT表到磁盤中。為新建目錄的數(shù)據(jù)簇初始化,并且初始化第一個目錄項。最后,填入新建目錄的目錄項初始值(目錄名、屬性、創(chuàng)建時間、數(shù)據(jù)簇起始位置)到win[]中。然后同步到磁盤中,完成整個新建目錄的工作。9)f_delete函數(shù)原型:FRESULTf_delete(constchar*path)函數(shù)功能:刪除一個文件或者目錄1、刪除目錄或者文件的簇鏈(回收數(shù)據(jù)空間)。2、文件或者目錄的目錄項被設置成為刪除(0xE5),注意目錄項并沒有回收,只是標記為刪除。輸入?yún)?shù):path指向路徑的指針輸出參數(shù):FRESULT成功與否函數(shù)的實現(xiàn)方法:首先調(diào)用函數(shù)trace_path搜索文件系統(tǒng)中是否存在所要刪除的目錄或者文件,如果不存在就返回失?。蝗绻嬖诰头祷貙夸涰椀奈恢茫╠irscan、dir),并且將對應目錄項所在扇區(qū)的內(nèi)容加載到win[]中。判斷要刪除的是不是目錄,如果是目錄還要判斷是不是非空目錄,如果是非空目錄則不允許刪除。如果是空目錄,那么就可以刪除。刪除文件或者目錄時,首先刪除簇鏈(數(shù)據(jù)空間),然后修改目錄項為刪除狀態(tài)(0xE5),最后同步目錄項所在扇區(qū)win[]緩沖區(qū)到磁盤中,完成刪除。10)f_readdir函數(shù)原型:FRESULTf_readdir(DIR*scan,FILINFO*finfo)函數(shù)功能:從當前目錄項指針處讀取一個目錄項,并且移動目錄指針到下一個索引輸入?yún)?shù):scan要讀取的目錄 finfo目錄的信息,finfo->fname[0]=0,這是一個空目錄項finfo->fname[0]=others,這是一個非空目錄項。輸出參數(shù):FRESULT成功與否函數(shù)的實現(xiàn)方法:首先將目錄指針當前所在物理扇區(qū)讀取到win[]中,然后調(diào)用get_函數(shù)從當前目錄指針處讀取當前目錄項并處理后存入finfo中。最后,還要移動目錄項指針到下一個索引位置。11)f_close函數(shù)原型:FRESULTf_close(FIL*fp)函數(shù)功能:關(guān)閉文件函數(shù)參數(shù):fp指向文件的指針函數(shù)返回值:FRESULT操作是否成功函數(shù)的實現(xiàn)方法:首先調(diào)用f_sync(),如果成功,則把UcFs->files減一。系統(tǒng)的測試和運行文件系統(tǒng)主要是對外提供接口,因此需要編寫驅(qū)動程序開測試文件函數(shù)是否正常工作。5.1測試程序的編寫測試程序必須運行在μC/OS-II上,因為我們是為μC/OS-II編寫的文件系統(tǒng)。而且測試程序必須覆蓋所有的公共接口。下面是測試程序的主要代碼:voidtest_fs(void*p_arg){charcmd[256];charparam[20];char*p;CMDTYPEtype;for(;;){printf("ucosii/fs>");fgets(cmd,255,stdin);//刪除行尾的換行符p=strrchr(cmd,'\n');if(p!=NULL)*p='\0';rm_blank(cmd);if(*cmd=='\0'){puts("");continue;}type=parse(cmd,param);switch(type){caseREAD:read_test(param);puts("");break;caseWRITE:write_test(param);puts("");break;caseLS:ls_test(param);puts("");break;caseRM:rm_test(param);puts("");break;caseNEWFILE:new(param);puts("");
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 20521.4-2025半導體器件第14-4部分:半導體傳感器半導體加速度計
- 養(yǎng)老院入住老人財務收支審計制度
- 企業(yè)內(nèi)部培訓與外部合作制度
- 公共交通線路規(guī)劃管理制度
- 2026年金融從業(yè)資格模擬測試題庫
- 2026年財務成本控制與管理試題集
- 2026年營養(yǎng)師職業(yè)技能等級認定筆試題集
- 2026年教育心理學應用教師考核試題及答案
- 2026年攝影培訓協(xié)議(人像風光·實操版)
- 2026年冷鏈運輸協(xié)議(醫(yī)藥·GSP合規(guī)版)
- DB21-T 4279-2025 黑果腺肋花楸農(nóng)業(yè)氣象服務技術(shù)規(guī)程
- 2026廣東廣州市海珠區(qū)住房和建設局招聘雇員7人考試參考試題及答案解析
- 2026新疆伊犁州新源縣總工會面向社會招聘工會社會工作者3人考試備考題庫及答案解析
- 廣東省汕頭市2025-2026學年高三上學期期末語文試題(含答案)(含解析)
- 110接處警課件培訓
- DB15∕T 385-2025 行業(yè)用水定額
- 火箭軍教學課件
- 新媒體運營專員筆試考試題集含答案
- 護理不良事件之血標本采集錯誤分析與防控
- 心臟電生理檢查操作標準流程
- 盾構(gòu)構(gòu)造與操作維護課件 2 盾構(gòu)構(gòu)造與操作維護課件-盾構(gòu)刀盤刀具及回轉(zhuǎn)中心
評論
0/150
提交評論