您的位置:首页 > 其它

evm6678l 上跑fatfs的实现过程

2016-09-13 13:56 423 查看
刚到一家公司上班,让我在dsp上实现fatfs文件系统,虽然我不推荐使用这个文件系统因为它没有坏块管理功能,没办法就当练手吧,经过了一周左右对开发板的熟悉,现在终于移植成功了,在这其中使用到了官方给的驱动程序。

要使用fatfs,只需要完成diskio.c下面对应的函数的移植,下面来看看我在c6678的移植的实现。

板子上的nandflash 是一个64m的falsh,读取速度很慢,只有2m左右,也是醉了。

该nandflash的块大小为16kb,页大小为512byte,这里我们把也作为fatfs的块,一块512byte,

吧nandflash的块作为fatfs的族进行格式化。

下面看看移植代码,

/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2013 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control module to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "nand_util.h"
#include "diskio.h" /* FatFs lower layer API */

#include "fatfs_util.h"
/* Definitions of physical drive number for each media */
#define NANDFLASH 0

/*-----------------------------------------------------------------------*/
/* 初始化一个设备 */
/*-----------------------------------------------------------------------*/
PLATFORM_DEVICE_info *p_device=0x00;

DSTATUS disk_initialize(BYTE pdrv /* Physical drive nmuber (0..) */
) {
switch (pdrv) {

case NANDFLASH:
if(p_device!=0x00){return 0;}
//初始化设备
if(nand_init()==1){return 1;}
//打开设备
p_device = platform_device_open(PLATFORM_DEVID_NAND512R3A2D, 0);
if(p_device==0x00){break;}
// nand_erase_all_blks(p_device);
return 0;
}

return 1;
}

/*-----------------------------------------------------------------------*/
/* 获取磁盘的状态 */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status(BYTE pdrv /* Physical drive nmuber (0..) */
) {
DSTATUS stat = 0;

switch (pdrv) {
case NANDFLASH:

return stat;
}
return STA_NOINIT;
}

/*-----------------------------------------------------------------------*/
/* 读多个块 */
/*-----------------------------------------------------------------------*/

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) */
) {
u32 i=0;
u32 offset;
u32 nBlock=0;
u32 nPage=0;
u32 badFlag=0;
u8 readBuffer[2*1024];
switch (pdrv) {
case NANDFLASH:
//写数据前需要对块进行擦除
//所以必须先将块内的数据读出来,在写入
for(i=0;i<count;i++){
//把块偏移转化为偏移量
nand_fatfsbl_to_nandbl(sector+i,&nBlock,&nPage);
do{
if(platform_blocknpage_to_offset(
p_device->handle,
&offset,
nBlock,
nPage)!=Platform_EOK){
return RES_ERROR;
}
//检查是不是坏块
if(checkBadBlockMark(p_device,nBlock)!=0){
badFlag=1;
//坏块
nBlock++;
}else{badFlag=0;};
}while(badFlag);

//读取数据
if(platform_device_read(
p_device->handle,
offset,
(uint8_t*)readBuffer,
PAGE_SIZE)!=Platform_EOK){
return RES_ERROR;
}
for(i=0;i<PAGE_SIZE;i++){
buff[i]=readBuffer[i];
}
}
return RES_OK;
}
return RES_PARERR;
}

/*-----------------------------------------------------------------------*/
/* 写多个块 */
/*-----------------------------------------------------------------------*/

#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) */
) {
u32 i=0;
u32 j=0;
u32 offset;
u32 nBlock=0;
u32 nPage=0;
u32 badFlag=0;
switch (pdrv) {
case NANDFLASH:
for(i=0;i<count;i++){
//读取的块的大小
u8 block[BLOCK_SIZE]={0};
//把块偏移转化为偏移量
nand_fatfsbl_to_nandbl(sector+i,&nBlock,&nPage);
do{
if(platform_blocknpage_to_offset(
p_device->handle,
&offset,
nBlock,
nPage)!=Platform_EOK){
return RES_ERROR;
}
//检查是不是坏块
if(checkBadBlockMark(p_device,nBlock)!=0){
badFlag=1;
//坏块
nBlock++;
}else{badFlag=0;};
}while(badFlag);

if(platform_device_read(
p_device->handle,
//一次读一页
nBlock,
//读32次
(uint8_t*)(block),
//一次读的大小为512Byte
BLOCK_SIZE) != Platform_EOK){
//return RES_ERROR;
}
//读取这一块的数据
// for(j=0;j<BLOCK_IN_PAGE_NUM;j++){
// //读失败说明是坏页
// if(platform_device_read(
// p_device->handle,
// //一次读一页
// nBlock*BLOCK_SIZE + j*PAGE_SIZE,
// //读32次
// (uint8_t*)(block+ j*PAGE_SIZE),
// //一次读的大小为512Byte
// PAGE_SIZE) != Platform_EOK){
// //return RES_ERROR;
// }
// }
//写入数据
for(i=0;i<PAGE_SIZE;i++){
block[nPage*PAGE_SIZE+i]=buff[i];
}
if(Platform_EOK!=platform_device_erase_block(
p_device->handle,
nBlock)){
return RES_ERROR;
}
if(Platform_EOK!=platform_device_write(
p_device->handle,
nBlock*BLOCK_SIZE,
block,
BLOCK_SIZE)){
return RES_ERROR;
}
}
return RES_OK;
}
return RES_PARERR;
}
#endif

/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/

#if _USE_IOCTL
DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
) {
// if (pdrv) {
// return RES_PARERR;
// }
// nandWriterInfo.deviceTotalBytes = p_device->block_count * p_device->page_count * p_device->page_size;
// nandWriterInfo.blockSizeBytes = p_device->page_count * p_device->page_size;

switch (pdrv) {
case NANDFLASH:

switch (cmd) {
case CTRL_SYNC:
break;
case GET_BLOCK_SIZE:
*(DWORD*) buff =BLOCK_SIZE;
break;
case GET_SECTOR_COUNT:
*(DWORD*) buff = p_device->block_count*p_device->page_count;
break;
case GET_SECTOR_SIZE:
*(WORD*) buff = PAGE_SIZE;
break;
default:
return RES_PARERR;
}
return RES_OK;
}
return RES_PARERR;
}
#endif


这是diskio.c的移植代码,完成这个,移植基本就完成了。

下面来看看测试代码:

#include <stdio.h>
#include "ff.h"
#include "fatfs_util.h"
FIL fp;
FATFS fs;
FATFS *pfs;
void init_fatfs(void){
f_mount(&fs,"0",0);
//f_mkfs("0",0,0);
}

void test_fatfs(void){
u8 rData[512]={0};
u32 nWrite;
u8 flag=0;
FRESULT res;
DWORD clust;
pfs=&fs;
f_getfree("/", &clust, &pfs);
if(f_mkdir ("zz")==FR_OK){
printf("dir create ok!..");
}
flag=f_open (&fp,"1.txt", FA_READ|FA_WRITE);
if( flag==FR_
4000
OK){
printf("file create ok!..");
}
flag=f_write (
&fp, /* [IN] Pointer to the file object structure */
"hello_world..", /* [IN] Pointer to the data to be written */
13, /* [IN] Number of bytes to write */
&nWrite /* [OUT] Pointer to the variable to return number of bytes written */
);
if( flag==FR_OK){
printf("write create ok!..");
}
flag=f_close(&fp);
flag=f_open (&fp,"1.txt", FA_READ|FA_WRITE);
flag=f_read (
&fp, /* [IN] File object */
rData, /* [OUT] Buffer to store read data */
13, /* [IN] Number of bytes to read */
&nWrite /* [OUT] Number of bytes read */
);
if(flag==FR_OK){
printf("read create ok!..");
}
f_close(&fp);

}

测试,向文件内写入hello word 字符,关闭文件后,能够正常读取到hell word字符.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息