將FATFS移植STM32RBT6遇到的掛載不成功和返回值問(wèn)題(2)
移植前做了大量準備,在網(wǎng)上尤其是原子論壇翻看各種其他人移植的心得,去fatfs的官方網(wǎng)站下載0.10版本的程序,看各種相關(guān)的移植心得,文檔版本眾多,眼花繚亂,花了點(diǎn)時(shí)間看了看一些函數??吹貌畈欢嗔?,就直接把0.10的版本考到自己的工程目錄下開(kāi)始make,經(jīng)過(guò)大量的翻閱和實(shí)踐,要動(dòng)的地方只有diskio.c和ffconfig.h,第一個(gè)需要把底層驅動(dòng)函數sd_inti();添加進(jìn)去。sd卡的讀單塊和讀多塊,寫(xiě)單塊寫(xiě)多塊填進(jìn)去,ffconfig.h里邊需要改幾個(gè)宏定義的值參照別人的例程就可以實(shí)現很簡(jiǎn)單。
DSTATUS disk_initialize (
BYTE drv/* Physical drive nmuber (0..) */
)
{
u8 state;
state=SD_Init();
if(!state){
return STA_NODISK;
}
return 0;
}
/*-----------------------------------------------------------------------*/
/* Return Disk Status */
DSTATUS disk_status (
BYTE drv/* Physical drive nmuber (0..) */
)
{return 0;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
DRESULT disk_read (
BYTE drv,/* Physical drive nmuber (0..) */
BYTE *buff,/* Data buffer to store read data */
DWORD sector,/* Sector address (LBA) */
BYTE count/* Number of sectors to read (1..255) */
)
{
u8 res=0;
if(count==1) //1個(gè)sector的讀操作
{
res = SD_ReadSingleBlock(sector, buff);
//res= SD_ReadDisk(buff,sector,count);
}
else //多個(gè)sector的讀操作
{
res = SD_ReadMultiBlock(sector, buff, count);
}
//處理返回值,將SPI_SD_driver.c的返回值轉成ff.c的返回值
if(res == 0x00)
{
return RES_OK;
}
else
{
return RES_ERROR;
}
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
#if _READONLY == 0
DRESULT disk_write (
BYTE drv,/* Physical drive nmuber (0..) */
const BYTE *buff,/* Data to be written */
DWORD sector,/* Sector address (LBA) */
BYTE count/* Number of sectors to write (1..255) */
)
{
u8 res;
// 讀寫(xiě)操作
if(count == 1)
{
res = SD_WriteSingleBlock(sector, buff);;
}
else
{
res = SD_WriteMultiBlock(sector, buff, count);
}
// 返回值轉換
if(res == 0)
{
return RES_OK;
}
else
{
return RES_ERROR;
}
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
DRESULT disk_ioctl (
BYTE drv,/* Physical drive nmuber (0..) */
BYTE ctrl,/* Control code */
void *buff/* Buffer to send/receive control data */
)
{
DRESULT res;
if (drv)
{
return RES_PARERR; //僅支持單磁盤(pán)操作,否則返回參數錯誤
}
//FATFS目前版本僅需處理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三個(gè)命令
switch(ctrl)
{
case CTRL_SYNC:
res=RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = 512;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = SD_GetCapacity();
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
return res;
}
以上代碼是參照網(wǎng)友的,當然原子的也沒(méi)有問(wèn)題。只要底層沒(méi)有問(wèn)題基本上,應用層就不會(huì )有問(wèn)題。如何判別底層函數呢?在不加fatfs前跟蹤調試一下看是否初始化能成功和其他的寄存器值是否能讀成功。
在sd卡底層沒(méi)有問(wèn)題的情況下再做應用層函數的編寫(xiě)。
我在移植時(shí)沒(méi)有使用內存管理機制,所以卡了好幾天,一直以為是底層問(wèn)題,可是讀sd卡絕對沒(méi)有問(wèn)題,還能播放MP3呢。找不到問(wèn)題所在頭就大,后來(lái)在論壇上留言終于網(wǎng)友點(diǎn)醒了我,原來(lái)在定義FATFS *FS;是需要分配內存的,據說(shuō)空間分配有兩種方式一個(gè)是數組,另一個(gè)是定義指針,定義指針時(shí)要使用malloc分配內存還要free釋放內存,而我定義了fatfs結構的指針沒(méi)有分配內存,造成返回值FR_NO_FILESYSTEM,/* (13) There is no valid FAT volume */,后來(lái)我改成fatfs fs;還有一個(gè)問(wèn)題sd卡的掛載驅動(dòng)號是1 ,我寫(xiě)0res= f_mount(&fs,(TCHAR*)0,1); /* Mount a logical drive */;的時(shí)候老返回FR_INVALID_DRIVE,/* (11) The logical drive number is invalid */掛載失敗。如果你也遇到這個(gè)問(wèn)題建議改成res= f_mount(&fs,(TCHAR*)1,1);這種形式就行了,但是打開(kāi)文件和讀文件內容時(shí)還要這么寫(xiě)
res=exf_getfree("0:",&nCapacity,&free);//得到SD卡的總容量和剩余容量
res=f_open(&file, "0:/test.txt", FA_OPEN_EXISTING|FA_READ);
res=f_read (
&file, /* Pointer to the file object */
buffer,/* Pointer to data buffer */
512,/* Number of bytes to read */
&br/* Pointer to number of bytes read */
) ;
好了,廢話(huà)不多說(shuō),把main函數應用層代碼粘貼出來(lái)
FATFS fs;FIL file; //文件1
FIL ftemp; //文件2.
UINT br,bw;//讀寫(xiě)變量
FILINFO fileinfo;//文件信息
DIR dir;
FILINFO fileInfo;
UINT br,bw;
評論