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

How to Write to SD Card at high rate ?

Hi All,

I have just started working on interfacing SD card with nrf52 using SDK 12.0. I have to write to SD card at a rate of 84 packets per second and each packet consists of 20 bytes. I am taking fatfs example in sdk 12.0 as reference.

I am sampling the SAADC at 1 ksps and storing these samples in SD card.Here I amwriting to SD card based on GPIO interrupt For each write operation I am using following steps: 1)open directory 2)open file 3)write bytes to file 4)close the file.

While writing continuously I am facing following issues :

  1. Code gets restarted automatically after writing some kb's into SD card.

  2. I am wring only in one file. Still additional files are generated in SD card.

  3. while writing to file somewhere in the middle I am getting massage as Unable to open or create file: ank.TXT.

I am using 8 GB SD card for this operation. IAR version 7.4 and SDK 12.0. Does any one has any idea why I am getting these issues?

I am attaching my code and some images for the reference. modified1.c image description image description image description

image1: when issue no. 3 occurred image2: when code gets restarted image3: when multiple files gets created in SD card

I have to write to SD card whole data at longer duration without restarting the code.

  • You should check why your code is restarting. Most of the time it is because an error condition was met, see here.

    Maybe you get the Unable to open or create file: ank.TXT because you try to open the file while it is not closed yet.

    Can you try to use f_sync(...) as described here to minimize the critical sections? If you use f_sync(..) you can leave the file open instead of closing it after every write, suitable for datalogging, see here. Then you can close it before you remove the SD card or when the logging is done.

  • Hi Ole ,

    Thanks for the reply. As suggested by you,I have added the f_sync() function after f_open() and f_write() functions.But still Unable to open or create file: ank.TXT error comes some times. Also, the return response of
    f_sync() function is not FR_OK all the time. Following is the small part of modified code:

        void SD_Write()
    {
        static FIL file;
        FRESULT ff_result;
        uint32_t bytes_written;
     
        
        uint8_t d[20] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
        char buffer [100]={0};
        int n,eof=0;
    
        ff_result = f_open(&file, FILE_NAME1, FA_READ | FA_WRITE | FA_OPEN_APPEND);
        if (ff_result != FR_OK)
        {
            printf("Unable to open or create file: " FILE_NAME1 ".\r\n");
            (void) f_close(&file);
            return;
        }
        ff_result = f_sync(&file);
        
        n=sprintf (buffer,"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\r",d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15],d[16],d[17],d[18],d[19]);
    
        ff_result = f_write(&file, buffer, n, (UINT *) &bytes_written);
        if (ff_result != FR_OK)
        {
            printf("Write failed\r\n.");
        }
    
        ff_result = f_sync(&file);
        if (ff_result != FR_OK)
        {
            printf("Synced Failed\r\n");
        }
        
        //Check End of File for closing the file
        eof=f_eof(&file);
        if(eof)
        {
            //do nothing
        }
        else
        {
            printf("eof=%d\r\n",eof);
            (void) f_close(&file);
        }
    }
    
    static void fatfs_example()
    {
        static FATFS fs;
        static DIR dir;
        FRESULT ff_result;
        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));
    
        printf("Initializing disk 0 (SDC)...\r\n");
        for (uint32_t retries = 3; retries && disk_state; --retries)
        {
            disk_state = disk_initialize(0);
        }
        if (disk_state)
        {
            printf("Disk initialization failed.\r\n");
            return;
        }
    
        printf("Mounting volume...\r\n");
        ff_result = f_mount(&fs, "", 1);
        if (ff_result)
        {
            printf("Mount failed.\r\n");
            return;
        }
    
        printf("\r\n Listing directory: /\r\n");
        ff_result = f_opendir(&dir, "/");
        if (ff_result)
        {
            printf("Directory listing failed!\r\n");
            return;
        }
        
         //remove perticular file 
        ff_result = f_unlink ("ANK.TXT");
        if (ff_result != FR_OK)
        {
          printf("NoFile : Write failed\r\n.");
        }
        else
        {
            printf("file removed = ANK.TXT \r\n");
        }
      
        
        return;
    }
    
    int main(void)
    {
        bool     erase_bonds;
        // Initialize.
        gpio_init();
        timers_init();
        uart_init();
        buttons_leds_init(&erase_bonds);
        ble_stack_init();
        peer_manager_init(erase_bonds);
        gap_params_init();
        advertising_init();
        gatt_init();
        services_init();
        sensor_simulator_init();
        conn_params_init();
        saadc_init();
        
        // Start execution.
        application_timers_start();
        advertising_start();
        printf("UART Start...\r\n");
        fatfs_example();
    
        
        // Enter main loop.
        for (;;)
        {
    
            if(SD_flag==true)
            {
                SD_flag = false;
                SD_Write();
            }
    
           power_manage();
        }
    }
    

    In Above code,

    1. SD_flag is set after 12ms when NRF_DRV_SAADC_EVT_DONE in SAADC callback occurs.
    2. I am storing 20 bytes means 80 unsigned characters in file in SD_write function.
    3. The code restarting issue is still there with IAR as my IDE.

    Can you suggest something to deal with this?

    Is it because of high sampling rate of SAADC?

  • Here I observed one more thing. If I set the flag in main function as below:

    if(SD_flag==false) { SD_flag = true; } if(SD_flag==true) { SD_flag = false; SD_Write(); nrf_delay_ms(20); }

    I am able to write large data to SD card with less restarting and that to after storing 300kB in SD card. Why it is happening?

    Is it related to SPI clock frequency? I have kept it as 250 kHz. What should be the SPI0 clock frequency for SD card writing?

  • Any updates Here?

    Can anyone guide me how can I resolve above mentioned issues?

  • Can you print out the return code when you get the "unable to open or create file"? This should give you an indication of what is wrong. Something like this:

    NRF_LOG_INFO("Unable to open or create file: " FILE_NAME ".\r\n");
    NRF_LOG_INFO("Error code: %d\r\n", ff_result);
    

    You can also try to check the return code of the f_close function to check if the file was successfully closed.

Related