I am trying to use Elm-chan's FatFS code (Link); eventually it will be ported to a microcontroller for use writing and reading files to an SD card, but for now I am working on understanding how to port it, so I am building it on a host PC and trying to use a static or dynamic RAM buffer for the filesystem. I have it building and I can make calls to it, but whenever I try to mount the filesystem, I get error 13: FR_NO_FILESYSTEM.
Here's my implementation of the diskio functions, and the main.c I am using to test FatFS. When I build and run main, f_mount() always returns 13. I am not sure what I am doing wrong. I know that with a formatted SD card I won't need f_mkfs(), but I'd still like to understand how to use it.
Is it possible to use a RAM buffer for the FatFS volume/filesystem, and if so, what am I doing incorrectly?
Differences in my ffconf.h from default:
#define FF_USE_MKFS 1
#define FF_CODE_PAGE 437
Also in my implementation, FF_MIN_SS = FF_MAX_SS = 512
.
diskio.c:
#include <stdint.h>
#include <stdio.h>
#include "diskio.h"
#include "ff.h"
static DSTATUS gStatus = STA_NOINIT;
static BYTE *disk = NULL;
#define NUM_SECTORS 128
DSTATUS disk_initialize(
BYTE pdrv
)
{
if (pdrv == 0)
{
if (disk == NULL)
{
disk = malloc(FF_MIN_SS * NUM_SECTORS);
if (disk != NULL)
{
// for RAM buffer, no additional setup needed, so clear NOINIT bit.
gStatus &= ~STA_NOINIT;
// set malloc'd buffer to zeros
memset(disk, 0, FF_MIN_SS * NUM_SECTORS);
}
else
{
gStatus = STA_NOINIT;
}
}
}
return gStatus;
}
DSTATUS disk_status(
BYTE drv
)
{
return gStatus;
}
DRESULT disk_read(
BYTE pdrv,
BYTE *buff,
LBA_t sector,
UINT count
)
{
DRESULT res = RES_OK;
if (pdrv == 0 && sector <= NUM_SECTORS)
{
memcpy(buff, disk + (sector * FF_MIN_SS), count * FF_MIN_SS);
}
else
{
res = RES_PARERR;
}
return res;
}
DRESULT disk_write(
BYTE pdrv,
const BYTE *buff,
LBA_t sector,
UINT count
)
{
DRESULT res = RES_OK;
if (pdrv == 0 && sector <= NUM_SECTORS)
{
memcpy(disk + (sector * FF_MIN_SS), buff, count * FF_MIN_SS);
}
else
{
res = RES_PARERR;
}
return res;
}
DRESULT disk_ioctl (
BYTE pdrv, /* [IN] Drive number */
BYTE cmd, /* [IN] Control command code */
void* buff /* [I/O] Parameter and data buffer */
)
{
DRESULT res = RES_OK;
if (pdrv != 0)
{
res = RES_PARERR;
}
else
{
switch(cmd)
{
case GET_SECTOR_COUNT:
*(DWORD *)buff = NUM_SECTORS;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(DWORD *)buff = 128;
res = RES_OK;
break;
case CTRL_SYNC:
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}
return res;
}
DWORD get_fattime(
void
)
{
// 0 will make the file timestamp invalid, but I don't need an accurate timestamp.
return 0;
}
main.c
#include <stdio.h>
#include "ff.h"
int main(void)
{
FATFS fs;
FRESULT fres;
FIL file;
char *writeBuf = "Hello, World!";
unsigned int bytesWritten;
BYTE work[FF_MIN_SS];
MKFS_PARM parm;
parm.fmt = FM_FAT | FM_SFD;
fres = f_mkfs("", &parm, work, sizeof(work));
if (fres != FR_OK)
{
printf("f_mkfs() failed: %d\r\n", fres);
return -1;
}
fres = f_mount(&fs, "", 1);
if (fres != FR_OK)
{
printf("f_mount() failed: %d\r\n", fres);
return -1;
}
fres = f_open(&file, "test.txt", FA_CREATE_NEW | FA_WRITE);
if (fres != FR_OK)
{
printf("f_open() failed: %d\r\n", fres);
return -1;
}
return 0;
}
Output: f_mount() failed: 13
Expected: file gets written to RAM buffer