當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]對(duì)于固態(tài)存儲(chǔ)器,其存儲(chǔ)容量可以很大,往往需要一款文件系統(tǒng)對(duì)存儲(chǔ)器用戶數(shù)據(jù)進(jìn)行組織文件的管理。它對(duì)文件存儲(chǔ)器空間進(jìn)行組織和分配,負(fù)責(zé)文件的存儲(chǔ)并對(duì)存入的文件進(jìn)行保護(hù)和檢索。在嵌入式系統(tǒng)中,往往需要采用wi

對(duì)于固態(tài)存儲(chǔ)器,其存儲(chǔ)容量可以很大,往往需要一款文件系統(tǒng)對(duì)存儲(chǔ)器用戶數(shù)據(jù)進(jìn)行組織文件的管理。它對(duì)文件存儲(chǔ)器空間進(jìn)行組織和分配,負(fù)責(zé)文件的存儲(chǔ)并對(duì)存入的文件進(jìn)行保護(hù)和檢索。在嵌入式系統(tǒng)中,往往需要采用windows兼容的文件系統(tǒng),像相機(jī)的照片、視頻監(jiān)控、語音產(chǎn)品等,很多都需要從windows計(jì)算機(jī)上提取資源或在windows計(jì)算機(jī)上進(jìn)一步處理。Fatfs由于其開源免費(fèi),支持fat32,受到了廣泛的應(yīng)用,筆者此處就s3c2416移植Fatfs,對(duì)sd卡進(jìn)行讀寫訪問作一個(gè)簡(jiǎn)單的介紹。

1. Fatfs概述

Fatfs是由日本工程師ChaN所編寫的fat文件系統(tǒng)模塊,從06年發(fā)布第一個(gè)Fatfs版本開始,作者就從未停止維護(hù)和更新。Fatfs的編寫遵循ANSI C,并且完全與磁盤I/O層分開。它不依賴于硬件架構(gòu),代碼和工作區(qū)占用空間小,使之可以嵌入到各個(gè)低成本的微控制器中,如AVR、8051、PIC、ARM、Z80、68K等。

2. 代碼準(zhǔn)備

Fatfs源碼,請(qǐng)讀者自行從Fatfs官網(wǎng)http://elm-chan.org/fsw/ff/00index_e.html下載最新的源碼。

s3c2416啟動(dòng)代碼工程,啟動(dòng)代碼是s3c2416/50/51這系列arm9芯片在運(yùn)行用戶c代碼main函數(shù)之前必須先運(yùn)行的代碼,啟動(dòng)代碼支持sd、Nand啟動(dòng),為用戶設(shè)置系統(tǒng)時(shí)鐘,初始化內(nèi)存,自動(dòng)識(shí)別啟動(dòng)設(shè)備并搬移代碼到RAM,MMU映射,中斷管理等,用戶只需專注于用c開發(fā)其它功能函數(shù)即可。關(guān)于啟動(dòng)代碼以及啟動(dòng)代碼的實(shí)現(xiàn)過程,筆者前面章節(jié)有非常詳細(xì)的介紹。此處以GCC下移植Fatfs為講解,下載”GCC啟動(dòng)代碼工程應(yīng)用實(shí)例”中的啟動(dòng)代碼源碼即可。如果在MDK下開發(fā),下載”MDK啟動(dòng)代碼工程應(yīng)用實(shí)例”中的啟動(dòng)代碼源碼。

用戶代碼,用c開發(fā)的所有功能代碼,其中,用戶代碼入口為main()函數(shù),在這里需要實(shí)現(xiàn)sd卡驅(qū)動(dòng)模塊等。

3. 工程搭建

在linux操作系統(tǒng)下任一路徑下新建一個(gè)Fatfs_GCC的工程目錄,該目錄下新建Fatfs目錄,下載Fatfs最新源碼并解壓,把src目錄內(nèi)容全部拷貝到Fatfs目錄下。

把啟用代碼目錄start_code拷貝到Fatfs_GCC目錄下,這部分代碼無需任何的修改。并保留其中的Makefile這些文件,按照Makefile的模板添加各個(gè)目錄的Makefile。GCC啟動(dòng)代碼下的工程管理Makefile提取自u(píng)boot,可以方便地增加源代碼以及代碼目錄。

在Fatfs_GCC目錄下新建apps目錄,用來保存應(yīng)用相關(guān)的源碼以及各個(gè)模塊驅(qū)動(dòng)。

4. Fatfs移植

Fatfs模塊完全獨(dú)立于磁盤I/O層,因此底層磁盤I/O訪問并不屬于Fatfs的模塊部分,用戶必須自己實(shí)現(xiàn)這部分用來訪問存儲(chǔ)設(shè)備。通常在diskio.c中實(shí)現(xiàn)這六個(gè)函數(shù)disk_initialize()、disk_status()、disk_read()、disk_wirte()、disk_ioctl()、get_fattime()即可。如果使能了OS相關(guān)的特性,則還需額外實(shí)現(xiàn)進(jìn)程/內(nèi)存函數(shù)。sd卡底層驅(qū)動(dòng)實(shí)現(xiàn)在前面的章節(jié)有詳細(xì)的介紹,此處直接在Fatfs移植接口中調(diào)用sd驅(qū)動(dòng)模塊中的相關(guān)函數(shù)。

4.1. disk_initialize函數(shù)

初始化存儲(chǔ)設(shè)備,若設(shè)備初始化成功,應(yīng)清除STA_NOINIT這個(gè)標(biāo)志返回。若初始化不成功,應(yīng)置位STA_NOINIT標(biāo)志再返回。如果在初始化時(shí),未檢測(cè)到卡,可設(shè)置STA_NODISK標(biāo)志表明無卡,檢測(cè)到寫保護(hù),可設(shè)置STA_PROTECT標(biāo)志表明寫保護(hù)。

static DSTATUS State = STA_NOINIT;

DSTATUS disk_initialize (

BYTE pdrv /* Physical drive nmuber (0..) */

)

{

if (pdrv != 0) {

return STA_NOINIT; // 僅支持driver0

}

if (!Hsmmc_Init()) { // 調(diào)用sd卡初始化

State &= ~STA_NOINIT; // 初始化成功

} else {

State |= STA_NOINIT;

}

return State;

}

4.2. disk_status函數(shù)

獲取設(shè)備的狀態(tài),返回STA_NOINIT、STA_NODISK、STA_PROTECT這三個(gè)標(biāo)志的組合。磁盤設(shè)備的狀態(tài)隨時(shí)都可能發(fā)生變化,例如初始化后的sd卡在某一時(shí)刻被拔出,此時(shí)無卡,F(xiàn)atfs通過disk_status函數(shù)重新獲知STA_NODISK無卡這一標(biāo)志。

DSTATUS disk_status (

BYTE pdrv /* Physical drive nmuber (0..) */

)

{

if (pdrv != 0) {

return STA_NOINIT; // 僅支持driver0

}

return State;

}

4.3. disk_read函數(shù)

讀取扇區(qū),F(xiàn)atfs通過該函數(shù)從磁盤某一扇區(qū)地址開始獲取一塊或多塊扇區(qū)的數(shù)據(jù),F(xiàn)atfs最多支持一次性讀寫128個(gè)扇區(qū)的數(shù)據(jù),通常磁盤都支持多塊讀、多塊寫,并且這樣的讀寫性能遠(yuǎn)遠(yuǎn)好于分單塊的讀寫。

DRESULT disk_read (

BYTE pdrv, /* Physical drive nmuber (0..) */

BYTE *buff, /* Data buffer to store read data */

DWORD sector, /* Sector address (LBA) */

UINT count /* Number of sectors to read (1..128) */

)

{

if (pdrv || !count) {

return RES_PARERR;

}

if (State & STA_NOINIT) {

return RES_NOTRDY;

}

if (!Hsmmc_ReadBlock(buff, sector,count)) {

return RES_OK; // 讀取成功

} else {

return RES_ERROR; // 讀取出錯(cuò)

}

}

4.4. disk_wirte函數(shù)

寫扇區(qū),F(xiàn)atfs通過該函數(shù)從磁盤某一扇區(qū)地址開始寫入一塊或多塊扇區(qū)的數(shù)據(jù)。如果只讀(_FS_READONLY == 1),可以不實(shí)現(xiàn)該函數(shù)。

#if _USE_WRITE

DRESULT disk_write (

BYTE pdrv, /* Physical drive nmuber (0..) */

const BYTE *buff, /* Data to be written */

DWORD sector, /* Sector address (LBA) */

UINT count /* Number of sectors to write (1..128) */

)

{

if (pdrv || !count) {

return RES_PARERR;

}

if (State & STA_NOINIT) {

return RES_NOTRDY;

}

if (State & STA_PROTECT) {

return RES_WRPRT;

}

if (!Hsmmc_WriteBlock((unsignedchar *)buff, sector, count)) {

return RES_OK; // 寫成功

} else {

return RES_ERROR; // 寫錯(cuò)誤

}

}

#endif

4.5. disk_ioctl函數(shù)

控制設(shè)備相關(guān)的功能,F(xiàn)atfs使用5個(gè)設(shè)備獨(dú)立的命令控制/獲取設(shè)備特定的功能。

CTRL_SYNC:寫同步,在關(guān)閉文件等操作時(shí),如果磁盤I/O口層使用了寫緩存,那么通知磁盤I/O口層把寫緩存中的數(shù)據(jù)寫回到磁盤中。對(duì)于沒有寫緩存,即每次disk_write均寫入到磁盤中,無需處理該命令,只需返回RES_OK即可。在可寫時(shí)_FS_READONLY == 0,該命令才會(huì)被使用。

GET_SECTOR_COUNT:獲取磁盤的總扇區(qū)數(shù),在用f_mkfs()格式化文件系統(tǒng),f_fdisk對(duì)磁盤分區(qū)時(shí)均會(huì)使用這個(gè)命令來獲取磁盤的總扇區(qū)數(shù),對(duì)于sd卡,通過CSD獲取卡容量信息。在支持格式化文件系統(tǒng)或多分區(qū)的情況下(_USE_MKFS == 1 或 _MULTI_PARTITION== 1),該命令才會(huì)被使用。

GET_SECTOR_SIZE:獲取磁盤一個(gè)扇區(qū)的字節(jié)數(shù),有效值為512、1024、2048或4096。對(duì)于大部分的系統(tǒng),所有內(nèi)存卡,硬盤,通常返回扇區(qū)大小為512字節(jié),但對(duì)于flash,一頁可能為512字節(jié),也可能為1k字節(jié),2k字節(jié),4k字節(jié),需要根據(jù)具體的flash頁大小進(jìn)行配置。

GET_BLOCK_SIZE:以扇區(qū)為單位獲取擦除塊的大小。在用f_mkfs()格式化文件系統(tǒng)時(shí),用來使數(shù)據(jù)區(qū)對(duì)齊到擦除塊。例如,第一個(gè)擦除塊往往用來保存系統(tǒng)信息等,真正的數(shù)據(jù)在第二個(gè)擦除塊位置開始存放。該命令并不重要,可直接返回1表明1個(gè)扇區(qū)對(duì)齊。此處與原作者移植例程保持一致,對(duì)sd2.0版本卡,返回AU(可分配單元)的大小,sd1.0版本卡,返回擦除塊大小。在_USE_MKFS == 1時(shí),該命令才被使用。

CTRL_ERASE_SECTOR:擦除某一段扇區(qū),對(duì)于flash,都是要先擦除才能正確寫入,對(duì)于nor、nand flash,某一個(gè)文件不再使用時(shí)(例如刪除或被覆蓋),先發(fā)出這個(gè)命令強(qiáng)制設(shè)備擦除這個(gè)文件所在的空間區(qū)域,之后在disk_write無需再對(duì)flash進(jìn)行擦除操作,因?yàn)槊看挝募辉偈褂脮r(shí),都已經(jīng)先擦除了這部分。對(duì)于sd卡等,這個(gè)命令沒有任何用處,因?yàn)閟d卡接收到塊寫命令均是先擦除再寫。如果再開啟這個(gè)命令_USE_ERASE == 1,相當(dāng)重復(fù)擦除。對(duì)于sd卡,建議設(shè)置_USE_ERASE == 0,不使用這個(gè)命令。

#if _USE_IOCTL

DRESULT disk_ioctl (

BYTE pdrv, /* Physical drive nmuber (0..) */

BYTE cmd, /* Control code */

void *buff /* Buffer to send/receive control data */

)

{

unsigned char CSD[16];

unsigned charSdState[64];

unsigned int c_size,c_size_multi, read_bl_len, sector_size, au_size;

DRESULT Result =RES_ERROR;

if (pd

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉