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;
}
 

  • So, I can get a second, third, and ... if the call to afilewrite is not within an event handler. So, the call to afilewrite has been located within the main loop and a flag is set within the event handler to make a write once back in the main loop.

  • Hello,

    You say that afilewrite() returns 12. I see that your function afilewrite() doesn't return anything, so I assume that it is one of the function calls inside this function that returns 12. Which of the function calls inside afilewrite() returns 12?

    Best regards,

    Edvin

  • I see. Where do you call afilewrite() from? and with what arguments? Have you mounted the volume first?

    Can you try to call f_readdir() first (like in the fatfs example)? Also, can you try to add FA_READ to your f_open() input parameters? E.g. ff_result = f_open(... , FA_OPEN_APPEND | FA_WRITE);

    If that doesn't work, what does f_mount(&fs, "", 1); return if you try to add it before f_open() and f_readdir()?

    BR,

    Edvin

  • I was trying to call the afilewrite from the button interrupt handler but with no success. I now set a flag in the button_handler and call afilewrite from the main.c loop. The parameters I call afilewrite with are two buffers a filename and a buffer containing the data. But this is only after I have called the fatfs example, which has called f_mount(&fs,"",1), so I assume the disk is mounted until unmounted which I do not see has ever been called.

    I am now writing to the open file consistently with 20 bytes as I have set a flag inside the button handler and call the afilewrite with the two buffers for file name and data. I have also hard coded the number of bytes to write as opposed to getting the number of bytes from the call to sizeof(buffer), with 20.

    I am still unsure as to why I can not call afilewrite from within the button interrupt handler? 

Related