1. 程式人生 > >轉一篇比較詳細介紹FatFs檔案系統移植的文章

轉一篇比較詳細介紹FatFs檔案系統移植的文章

摘自:http://blog.163.com/[email protected]/blog/static/3278568820090710053782/

補充一點,FatFs的作者寫了兩個,一個是正宗的FatFs,比較適合大的RAM的裝置,另一個是FatFs/Tiny,比較適合小RAM的系統,比如微控制器,FatFs/Tiny佔用較小的RAM,代價是更慢的讀寫速度和更少的API函式。不過兩個都支援FAT12,FAT16,FAT32檔案系統。

下載下來的FatFs的FatFs有兩個資料夾,一個是 doc ,FatFs的說明,包括特性,系統函式,以及可能的一些問題,另一個就是原始碼資料夾src了,總共8個檔案,diskio.c和diskio.h是硬體層,ff.c和ff.h是FatFs的檔案系統層和檔案系統的API層,integer.h是檔案系統所用到的資料型別的定義,tff.c和tff.h是Tiny的檔案系統層和檔案系統的API層,還有一個00readme.txt簡要的介紹了FatFSHE FatFs/Tiny,包括他們所支援的API,怎麼配置等等。

移植的問題,第一個是資料型別,在integer.h裡面去定義好資料的型別。第二個,就是配置,開啟ff.h(我用的FatFs,不是Tiny),_MCU_ENDIAN,選擇你的CPU是大端儲存(big endding)還是小端儲存(little endding),一般的都用的小端儲存,1是小端,2是大端。這個相當重要,一會兒還要談到這裡。其他的,按照自己的需要來配置了,說明文件夠清楚了,我就不多說啥了。

第三件事情,就是寫底層的驅動函式,包括:

disk_initialize- Initialize disk drive

disk_status- Get disk status

disk_read- Read sector(s)

disk_write- Write sector(s)

disk_ioctl- Control device dependent features

get_fattime- Get current time

所有的函式都牽涉到了選擇第幾個磁碟的問題,如果僅僅用一個,可以不必理會這個drv 引數。

disk_initialize,如果不需要的話,直接返回0就行

disk_status,這個嘛,先不管了,直接返回0就OK

disk_read- Read sector(s)

disk_write- Write sector(s)

讀寫扇區,注意引數哦!

disk_ioctl需要回應CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZE 三個命令,正確返回0即

RES_OK,不正確返回RES_ERROR。

所有的命令都從 ctrl 裡面去讀,返回值僅僅返回這次操作是否有效,而需要傳遞回去的資料在buff

裡面,以下是我的:

CTRL_SYNC命令,直接返回0;

GET_SECTOR_COUNT,得到所有可用的扇區數目(邏輯定址即LBA定址方式)

GET_BLOCK_SIZE,得到每個扇區有多少個位元組,比如 *((DWORD*)buff) = 512;

其他的命令,返回RES_PARERR

disk_ioctl這個函式僅僅在格式化的時候被使用,在除錯讀寫的時候,這個函式直接讓他返回0就OK 了。

get_fattime- 得到系統的時間,格式請見文件。不用的話,返回0就行。

這樣移植了,也基本上就成功了,但是在我的板子上面死活不行,每次一執行到幾個巨集定義比如

LD_WORD(ptr)(WORD)(*(WORD*)(BYTE*)(ptr)) 就產生資料終止異常( DATAABORT exception),但是網上的一個兄弟的(ouravr上的一個兄弟,用的SD卡,IAR編譯器,平臺是STM32,已經成功了,還公佈了原始碼的,這裡沒有問題啊),沒問題。分析下這個幾個巨集的意思:

LD_WORD(ptr)(WORD)(*(WORD*)(BYTE*)(ptr)) 是在little endding裡面定義的

LD_WORD(ptr),LD就是load,WORD在integer.h裡面定義的是16位的無符號數,那這個需要完成的就是載入一個16位的數,或者說是2個位元組,後面的 ptr是引數。(WORD)(*(WORD*)(BYTE*)(ptr)),先將這個ptr轉換成一個指向BYTE型別資料的指標(BYTE *),在將這個指標轉換成一個指向16位無符號數的指標(WORD *),然後用一個 ” * “將這個資料取出來,轉換成一個無符號的16位資料,這個僅僅從C語言的角度來看,實際上呢,這個完成的就是從ptr指標指向的位置,取出2個位元組,作為一個16位的無符號數取出,而這2個位元組是little endding,即小端模式,低位元組是低8位,高位元組是高8位。

既然是這樣的,測試了下,定義了一個BYTE buf[512],定義一個WORD型別 zz,用一個指標pt,讓pt指向

buf[0],呼叫LD_WORD(ptr),zz=LD_WORD(pt);沒問題,將pt指向buf[1],呵呵,問題馬上出來了,資料終止異常,然後測試了指標指向 buf[3],buf[5]等等奇數個,都是這樣的問題,我就鬱悶了啊,,編譯器的問題!!!!不過還好,找到問題了,就可以解決問題了,在 ff.h裡面的巨集定義裡面把這即個東東給註釋掉,然後在ff.c裡面把這幾個巨集定義寫成函式,這裡貼一個出來:

WORDLD_WORD(void *pt)

{

BYTE*PT = (BYTE*)pt; //定義一個指標,將當前的指標指向的地址的值賦給PT

return(WORD)(PT[0]+PT[1]*256); //計算這個16位數,(低8位在前面,高8位在後面),並來個強制型別轉

//換,並返回

}

需要注意的是,LD_WORD返回的就必須是WORD。這樣做了,編譯器大部分的也可以編譯通過,但是ADS就是通不過,有3個地方,

finfo->fsize= LD_DWORD(&dir[DIR_FileSize]); /* Size */

finfo->fdate= LD_WORD(&dir[DIR_WrtDate]); /* Date */

finfo->ftime= LD_WORD(&dir[DIR_WrtTime]); /* Time */

其中,dir的是這樣定義的:const BYTE *dir,編譯器報錯是型別不匹配,因此,這裡的幾個LD_WORD和LD_DWORD重寫,定義成一致的型別即可:

WORDLD_WORD_1(const BYTE *pt)

{

BYTE*PT = (BYTE*)pt;

return(WORD)(PT[0]+PT[1]*256);

}

DWORDLD_DWORD_1(const BYTE *pt)

{

BYTE*PT = (BYTE*)pt;

return((DWORD)PT[0]+(DWORD)(PT[1]*256)+(DWORD)(PT[2]*65536)+(DWORD)(PT[3]*16777216));

}

而後面改成:

finfo->fsize= LD_DWORD_1(&dir[DIR_FileSize]); /* Size */

finfo->fdate= LD_WORD_1(&dir[DIR_WrtDate]); /* Date */

finfo->ftime= LD_WORD_1(&dir[DIR_WrtTime]); /* Time */

編譯,一路OK,然後寫一個檔案,哇,哈哈哈哈!!!!終於出來了!!!!寫檔案沒問題,讀也沒問題!@~~~~~測試了常用的函式,都沒有問題,包括格式化(f_mkfs,前提是你的disk_ioctl 沒問題),測試

了下速度,讀12.5M的MP3,大約3秒,寫這個12.5M的MP3大約6.5秒,勉強達到要求,再優化下驅動那邊就可以更快了!~~~~~~~

發個FatFs的官方網址 http://elm-chan.org/fsw/ff/00index_e.html

總結這次移植,差點失敗就在於編譯器的指標的轉換問題,寫出來,希望兄弟姐妹們在移植的時候不會遇到這種問題。


相關推薦

比較詳細介紹FatFs檔案系統移植文章 FatFs檔案系統移植

  因為需要,又不想自己寫,所以就移植了一個檔案系統。     說下我的硬體和開發工具:接成 TRUE IDE 模式下的CF卡(也就是相當於一塊硬碟了),三星S3C2440的ARM9,開發工具是很老很老的D版的ADS1.2。    

比較詳細介紹FatFs檔案系統移植文章

摘自:http://blog.163.com/[email protected]/blog/static/3278568820090710053782/ 補充一點,FatFs的作者寫了兩個,一個是正宗的FatFs,比較適合大的RAM的裝置,另一個是FatFs/

關於SVM比較介紹的博文

    動筆寫這個支援向量機(support vector machine)是費了不少勁和困難的,原因很簡單,一者這個東西本身就並不好懂,要深入學習和研究下去需花費不少時間和精力,二者這個東西也不好講清楚,儘管網上已經有朋友寫得不錯了(見文末參考連結),但在描述數

STM32的FATFS檔案系統移植筆記(

一、序言     經常在網上、群裡看到很多人問關於STM32的FATFS檔案系統移植的問題,剛好自己最近也在除錯這個程式,為了讓大家少走彎路,我把我的除錯過程和方法也貢獻給大家。 二、FATFS簡介     FatFs Module是一種完全免費開源的FAT檔案系統模組,專門為小型的嵌入式系統而設計。

FATFS檔案系統移植

先說下我做的專案實現功能吧!語音播放器,類似一個小MP3那種,只是儲存用的SD卡、TF卡。檔案系統採用了開源的FATFS. FATFS模組的層次結構圖 1、底層介面,包括儲存媒介讀/寫介面(disk I/O)和供給檔案建立修改時間的實時時鐘,需要我們根據平臺和儲存介質編寫移植程式碼

fatfs檔案系統移植 讀寫時莫名出現FR_DISK_ERR問題

在移植fatfs檔案系統後,可以讀寫檔案系統,但是在讀寫過程中一直出現FR_DISK_ERR錯誤,以為是底層函式編寫有問題,一直無法解決問題,後經過多方查閱資料,懷疑是SDIO訪問時鐘頻率過高導致,將SDIO時鐘頻率調低

STM32的FATFS檔案系統移植筆記

一、序言     經常在網上、群裡看到很多人問關於STM32的FATFS檔案系統移植的問題,剛好自己最近也在除錯這個程式,為了讓大家少走彎路,我把我的除錯過程和方法也貢獻給大家。 二、FATFS簡介     FatFs Module是一種完全免費開源的FAT檔案系統模組,專

LPC1768 SPI模式下SD卡FatFs檔案系統移植

最近在LPC1768 SPI模式下移植SD卡FatFs(版本R0.09a)檔案系統成功,總結一下移植過程。 一、      底層驅動 使用的SSP0的SPI模式驅動,SSP時鐘開始使用的25M。SD卡驅動測試完成,可讀寫擦除測試沒有問題之後開始檔案系統移植。 要用到的底層驅

Petit FatFs檔案系統移植至STC89C52RC

MCU:STC89C51RC 最高主頻:80M Flash:4K SRAM:512B EEPROM:4K 系統:Petit FatFs 整合開發環境:keil 4 今天將Petit FatFs成功掛載到STC89C52RC晶片上進行執行,實話說這樣做的意義並不

ElasticSearch原始碼解析():介紹中文分詞的文章

轉自:http://www.cnblogs.com/flish/archive/2011/08/08/2131031.html  基於CRF(Conditional Random Field)分詞演算法 論文連結:http://nlp.stanford.edu/pubs/

FatFS檔案系統介紹及使用例程

FatFS檔案系統包含了檔案 ff.h         :檔案系統實現標頭檔案,定義有檔案系統所需的資料結構 diskio.h  :底層驅動標頭檔案,就一些狀態巨集的定義和底層驅動函式的申明 integer.h:僅實現資料型別重定義,增加系統的可移植性 ffcon

MYSQL文章《數據庫表設計,沒有最好只有最適合》

其他 eqv 新的 fmt 記錄 ces 末尾 base64 過程 http://mp.weixin.qq.com/s/a8klpzM5iam0_JYSw7-U4g 我們在設計數據庫的時候,是否會突破常規,找到最適合自己需求的設計方案,下面來舉個例子: 常用的鄰接表設計

()linux目錄結構詳細介紹

中產 沒有 默認 耗時 共享 而是 控制臺 toc inf linux目錄結構詳細介紹 原文:http://blog.51cto.com/yangrong/1288072 目錄 1、樹狀目錄結構圖 2、/目錄 3、/etc/目錄 4、/usr/目錄 5、/var/目錄 6、

大數據筆記(三十)——SparkStreaming詳細介紹

rgs 啟動 gui sele big 虛擬 ring foreach 單詞 Spark Streaming: Spark用於處理流式數據的模塊,類似Storm 核心:DStream(離散流),就是一個RDD=================================

開啟運維之路之第 3 ——目錄作用介紹檔案搜尋、其它命令、解壓縮包、使用者管理

1、目錄作用介紹 我們先切換到系統根目錄 / 看看根目錄下有哪些目錄 [[email protected] ~]# cd / [[email protected] /]# ls 說明: 根目錄下的bin和sbin,usr目錄下的bin和sbin,這四

QT中PRO檔案寫法的詳細介紹 Pro檔案變數詳細說明

學習Qt時,發現有些知識看了不經常用就忘了,以下是書本上寫的一些關於qmake的相關知識,自己看後,打算把一些經常用到的記下來,整理整理。   Qt程式一般使用Qt提供的qmake工具來編譯。 qmake工具可以使用與平臺無關的.pro檔案生成與平臺相關的makefile。該工具包含了呼叫Qt

關於如何在Unity裡使用Protobuf

https://www.cnblogs.com/designyourdream/p/4268092.html 原帖地址: http://purdyjotut.blogspot.com/2013/10/using-protobuf-in-unity3d.html 先轉過來,等時間合適了,再

Spring整合Struts2框架的第一種方式(Action由Struts2框架來創建)。在我的上博文中介紹的通過web工廠的方式獲取servcie的方法因為太麻煩,所以開發的時候不會使用。

rac println 需要 如果 value const tps http 建立 1. spring整合struts的基本操作見我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10140588.html,這裏面將spring與st

有關Java的記憶體洩露的文章(受益哦)

引言      Java的一個重要優點就是通過垃圾收集器GC (Garbage Collection)自動管理記憶體的回收,程式設計師不需要通過呼叫函式來釋放記憶體。因此,很多程式設計師認為Java 不存在記憶體洩漏問題,或者認為即使有記憶體洩漏也不是程式的責任,而是GC 或JVM的問題。其實,這種想法是

【睿遠諮詢】聽說你是小白?這裡有Salesforce入門介紹,請查收!

  聽說有家叫Salesforce的CRM公司很厲害 你肯定聽說過不少國內CRM企業信誓旦旦地想做中國的Salesforce。作為CRM領域的標杆,Salesforce在國際市場上到底有多厲害?看看權威雜誌的這些資料你就明白了。   Salesfo