This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

creating a new file after calling fsfat_example()

I am trying to create a datalogger onto a uSD card with a fat file system. I have been able to run the fatfs example which creates a file on the uSD card, NORDIC.TXT. The file has some test text inside. 

My question, if the fatfs_example(), initializes the system and presumably does uninitialize it then why does the my application hang when trying to write a second file onto the uSD card? It does not return from the function afilewrite(); I have seen error codes equivalent to 12 and have followed this to work area not established or does not exist.

I have taken out the static variables pertaining to the files and the disk and made then global in order to reuse what is working in the fatfs_example. Attached is the file that has been created in order to write the initial NORDIC.TXT and the attempt at the subsequent files. 

Also, I am interested in some documentation on utilizing the app_sdcard.c?

#include "fat_memory.h"

FIL file;
uint32_t bytes_written;
FRESULT ff_result;

/**
 * @brief Function for demonstrating FAFTS usage.
 */
void fatfs_example(char * cfilename)
{
    static FATFS fs;
    static DIR dir;
    static FILINFO fno;
    
    DSTATUS disk_state = STA_NOINIT;

    // Initialize FATFS disk I/O interface by providing the block device.
    static diskio_blkdev_t drives[] =
    {
            DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev), NULL)
    };

    diskio_blockdev_register(drives, ARRAY_SIZE(drives));

    NRF_LOG_INFO("Initializing disk 0 (SDC)...");
    for (uint32_t retries = 3; retries && disk_state; --retries)
    {
        disk_state = disk_initialize(0);
    }
    if (disk_state)
    {
        NRF_LOG_INFO("Disk initialization failed.");
        SEGGER_RTT_printf(0, "Disk intialization failed.\n");
        return;
    }

    uint32_t blocks_per_mb = (1024uL * 1024uL) / m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_size;
    uint32_t capacity = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count / blocks_per_mb;
    NRF_LOG_INFO("Capacity: %d MB", capacity);
    SEGGER_RTT_printf(0, "Capacity: %d MB.\n",capacity);
    NRF_LOG_INFO("Mounting volume...");
    ff_result = f_mount(&fs, "", 1);
    if (ff_result)
    {
        NRF_LOG_INFO("Mount failed.");
        return;
    }

    NRF_LOG_INFO("\r\n Listing directory: /");
    ff_result = f_opendir(&dir, "/");
    if (ff_result)
    {
        NRF_LOG_INFO("Directory listing failed!");
        return;
    }

    do
    {
        ff_result = f_readdir(&dir, &fno);
        if (ff_result != FR_OK)
        {
            NRF_LOG_INFO("Directory read failed.");
            return;
        }

        if (fno.fname[0])
        {
            if (fno.fattrib & AM_DIR)
            {
                NRF_LOG_RAW_INFO("   <DIR>   %s",(uint32_t)fno.fname);
            }
            else
            {
                NRF_LOG_RAW_INFO("%9lu  %s", fno.fsize, (uint32_t)fno.fname);
            }
        }
    }
    while (fno.fname[0]);
    NRF_LOG_RAW_INFO("");

    NRF_LOG_INFO("Writing to file %s", cfilename);
    ff_result = f_open(&file, cfilename, FA_READ | FA_WRITE | FA_OPEN_APPEND);
    if (ff_result != FR_OK)
    {
        NRF_LOG_INFO("Unable to open or create file: %s", cfilename);
        return;
    }

    ff_result = f_write(&file, TEST_STRING, sizeof(TEST_STRING) - 1, (UINT *) &bytes_written);
    if (ff_result != FR_OK)
    {
        NRF_LOG_INFO("Write failed\r\n.");
    }
    else
    {
        NRF_LOG_INFO("%d bytes written.", bytes_written);
    }

    (void) f_close(&file);
    return;
}


void afilewrite(char * afilename,uint16_t * filebuf)
{
    ff_result = f_open(&file, afilename, FA_OPEN_APPEND | FA_WRITE);
    if (ff_result != FR_OK)
    {
        SEGGER_RTT_printf(0, "unable to create file: %s %x\n",afilename,ff_result);
        return;
    }

    ff_result = f_write(&file, filebuf, sizeof(filebuf) - 1, (UINT *) &bytes_written);
    
    if (ff_result != FR_OK)
    {
        NRF_LOG_INFO("Write failed\r\n.");
        SEGGER_RTT_printf(0,"Write failed\r\n.");
    }
    else
    {
        NRF_LOG_INFO("%d bytes written.", bytes_written);
        SEGGER_RTT_printf(0,"%d bytes written.", bytes_written);
    }

    (void) f_close(&file);
    return;
}
 

  • It sounds like you are using different instances of &fs., or that fs is not volatile. 

    I don't know where you declare fs, but I see that the example does it in the function fatfs_example().

    Try to declare it as a volatile near the top of your main:

    static volatile FATFS fs;

    The same with your other fatfs variables: dir, fno and file.

    If they are not volatile, they may still think that they use the same instance, but optimization may optimize out the check of the fs. It will think that since the button handler has not updated the fatfs variable, it must be the same as when initialized, and hence not mounted.

Related