evm6678l 上跑fatfs的实现过程

刚到一家公司上班,让我在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_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字符.


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值