N9H26 SD卡的FATFS移植使用V1.2

FATFS文件系统移植记录(N9H26)

准备工作

移植记录

1.首先添加源码到工程中

添加完如下图:
在这里插入图片描述

2.修改diskio.c文件

2.1 添加SD卷标
#define SD_CARD (0) // SD卡,卷标为0

uint32_t sectorNum; // 用于记录sd卡sector数量
2.2 修改函数disk_initialize
  • 单分区可以在init里面初始化sd卡
DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
	uint8_t res=0;	    
	switch(pdrv)
	{
		case SD_CARD:		//SD卡
            
            sicIoctl(SIC_SET_CLOCK, sysGetPLLOutputHz(eSYS_UPLL, sysGetExternalClock())/1000, 0, 0);    // clock from PLL
            sicOpen();
            sectorNum = sicSdOpen0();
            sysprintf("Detect SD card on SD port 0 with %d sectors.\n", sectorNum);
        
  			break;
		default:
			res=1; 
	}		 
	if(res)return  STA_NOINIT;
	else return 0; //初始化成功 
} 
  • 多分区需要把初始化放到其他位置,比如挂载之前,避免多次进行初始化
 //--- Initial system clock for SD
    sicIoctl(SIC_SET_CLOCK, sysGetPLLOutputHz(eSYS_UPLL, sysGetExternalClock())/1000, 0, 0);    // clock from PLL
    //--- Enable AHB clock for SIC/SD/NAND, interrupt ISR, DMA, and FMI engineer
    sicOpen();
	sectorNum = sicSdOpen0();
    sysprintf("Detect SD card on SD port 0 with %d sectors.\n", sectorNum);

  	res = f_mount(&fs[0],"0: ",1); 					//挂载SD卡 
2.3 修改函数disk_read
DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address in LBA */
	UINT count		/* Number of sectors to read */
)
{
	u8 res=0; 
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误	
	switch(pdrv)
	{
		case SD_CARD://SD卡
			res=sicSdRead0(sector,count,(INT32)buff);	 
			while(res)//读出错
			{
				sysprintf("\nread erro\n");
				res=sicSdRead0(sector,count,(INT32)buff);	
			}
			break;
		default:
			res=1; 
	}
    if(res==0x00)return RES_OK;	 
    else return RES_ERROR;	   
}
2.4 修改函数disk_write
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address in LBA */
	UINT count			/* Number of sectors to write */
)
{
	u8 res=0;  
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误		 	 
	switch(pdrv)
	{
		case SD_CARD://SD卡
			res=sicSdWrite0(sector,count,(INT32)buff);
			while(res)//写出错
			{
				res=sicSdWrite0(sector,count,(INT32)buff);
			}
			break;
		default:
			res=1; 
	}
    if(res == 0x00)return RES_OK;	 
    else return RES_ERROR;	
} 
2.5 修改函数disk_ioctl
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
DRESULT res;						  			     
	if(pdrv==SD_CARD)//SD卡
	{
	    switch(cmd)
	    {
		    case CTRL_SYNC:
				res = RES_OK; 
		        break;	 
		    case GET_SECTOR_SIZE:
				*(DWORD*)buff = 512; 
		        res = RES_OK;
		        break;	 
		    case GET_BLOCK_SIZE:
		        res = RES_OK;
		        break;	 
		    case GET_SECTOR_COUNT:
		        *(DWORD*)buff = sectorNum;
		        res = RES_OK;
		        break;
		    default:
		        res = RES_PARERR;
		        break;
	    }
	}else res=RES_ERROR;//其他的不支持
    return res;
} 

3. 进行单分区操作

3.1 测试
(1) 挂载分区
	res = f_mount(&fs[0],"0: ",1); 					//挂载SD卡 
	sysprintf("SD 1 mount = %d\r\n",res);
    if(res == FR_NO_FILESYSTEM) {
        res = f_mkfs("0:", 0, 0); 
        res = f_mount(&fs[0],"0: ",1); 					//挂载SD卡 
        sysprintf("SD 1 mount = %d\r\n",res);
    }
(2)读写测试
	FIL fp;
	int res;
	
	res = f_open(&fp,"0:text.txt",FA_CREATE_ALWAYS | FA_READ | FA_WRITE);
	sysprintf("open status : %d\r\n",res);
	f_write(&fp,"hello1",sizeof("hello1"),&bw);
	f_close(&fp);

4.进行多分区操作

4.1 开启多分区支持
(1)修改ffconf.h
#define _VOLUMES	2	//支持2个磁盘
...
#define	_MULTI_PARTITION	1
(2) 添加分区信息(在自己的.c里)
PARTITION VolToPart[_VOLUMES] = {
    {0, 1},     /* "0:" ==> 1st partition on physical drive 0 */
    {0, 2},     /* "1:" ==> 2nd partition on physical drive 0 */
};
(3) 这里使用fatfs自带的分区函数
  • 分区成功后,不再调用以下函数
  • 还可以再电脑上使用软件工具进行分区,这里就没有尝试了。想通过软件进行分区的,可以看附录的引用内容。
	uint8_t work[512];
    DWORD plist[]={80,20,0,0}; // 80% 20%
    sysprintf("fdisk run \r\n");
    res = f_fdisk(0,plist,work);
    sysprintf("fdisk status : %d \r\n", res);
4.2 多分区测试
(1) 挂载分区
	FATFS fs[2];
	int res = 0;
	
	res = f_mount(&fs[0],"0: ",1); 					//挂载SD卡 
	sysprintf("SD 1 mount = %d\r\n",res);
    if(res == FR_NO_FILESYSTEM) {
        res = f_mkfs("0:", 0, 0);
        res = f_mount(&fs[0],"0: ",1); 					//挂载SD卡 
        sysprintf("SD 1 mount = %d\r\n",res);
    }
   	
    res = f_mount(&fs[1],"1:",1); 					//挂载SD卡 
	sysprintf("SD 2 mount = %d\r\n",res);
    if(res == FR_NO_FILESYSTEM) {
        res = f_mkfs("1:", 0, 0);
        res = f_mount(&fs[1],"1:",1); 					//挂载SD卡 
        sysprintf("SD 2 mount = %d\r\n",res);
    }
(2)读写测试
	FIL fp;
	int res;
	
	res = f_open(&fp,"0:text.txt",FA_CREATE_ALWAYS | FA_READ | FA_WRITE);
	sysprintf("open status : %d\r\n",res);
	f_write(&fp,"hello1",sizeof("hello1"),&bw);
	f_close(&fp);
     
    res = f_open(&fp,"1:text.txt",FA_CREATE_ALWAYS | FA_READ | FA_WRITE);
	sysprintf("open status : %d\r\n",res);
	f_write(&fp,"hello2",sizeof("hello2"),&bw);
    f_close(&fp);

5.其他情况记录

  • 当需要开启CACHE_WRITE_BACK时,需要对读写接口进行调整
DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address in LBA */
	UINT count		/* Number of sectors to read */
)
{
	u8 res=0; 
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误	
	switch(pdrv)
	{
		case SD_CARD://SD卡
			sysFlushCache(I_D_CACHE);
			res=sicSdRead0(sector,count,(INT32)buff);	 
			while(res)//读出错
			{
				sysFlushCache(I_D_CACHE);
				sysprintf("\nread erro\n");
				res=sicSdRead0(sector,count,(INT32)buff);	
			}
			break;
		default:
			res=1; 
	}
    if(res==0x00)return RES_OK;	 
    else return RES_ERROR;	   
}

DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address in LBA */
	UINT count			/* Number of sectors to write */
)
{
	u8 res=0;  
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误		 	 
	switch(pdrv)
	{
		case SD_CARD://SD卡
			sysFlushCache(I_D_CACHE);
			res=sicSdWrite0(sector,count,(INT32)buff);
			while(res)//写出错
			{
				sysFlushCache(I_D_CACHE);
				res=sicSdWrite0(sector,count,(INT32)buff);
			}
			break;
		default:
			res=1; 
	}
    if(res == 0x00)return RES_OK;	 
    else return RES_ERROR;	
} 

问题记录

1.SD卡读写失败

  • 重新使用一次SIC例程后解决,没有找到具体问题。

附录

参考博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值