FATFS文件系统移植记录(N9H26)
准备工作
- FATfs文件系统下载
- N9H26官方demo
- 测试使用SIC例程
- 移植时fatfs版本为:R0.12
移植记录
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例程后解决,没有找到具体问题。