How do I use a RAM buffer for a FATFS filesystem?

134 views Asked by At

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

0

There are 0 answers