This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/CC2642R: FATfs: f_write behavior on a perpetually opened file and current consumption

Part Number: CC2642R
Other Parts Discussed in Thread: CC2640

Tool/software: TI-RTOS

Hello,

I am currently having some issues with the FATFS API on the CC26X2R1 (SDK 2.30.0.34). My program spends most of it’s time collecting data in low-power mode using SCS code and wakes up periodically to empty buffer and write the data to a microSD card.

For previous versions of this code that I ran on both the CC2640 and the CC2640R2, the code would open a file (and keep it open while doing periodic f_sync's), start the SCS task, then do f_writes to the microSD card, with only the writing process repeating upon every wake up of the device. For these devices I was able to achieves a current draw of around 3mA.

For my current build on the CC26X2R1, the process/code is the same, but I am unable to leave the file open without getting errors or empty files. The workaround I found for this issue was to do an f_open of the file, f_write the data, and then f_close, with this entire process repeating every time the device is woken up from the SCS task. This would be fine if it weren’t for the fact that the open and closing process takes an extremely long time and results in the device consuming an astounding 17-19 mA of current during operation. In order to isolate the portion of the code responsible for the high current, I ended up putting an infinite while loop around the f_open->f_write->f_close sequence and current remained constant at around 21 mA. I also verified that the idle current from the microSD card is not the culprit. My device needs to be able to run for seven days and with it's current power consumption its only making it one day.

What can I do to solve this problem?

Thanks

  • Hi Stephen,

    I will consult the subject matter expert and get back to you.

    How are your measuring the average current consumption of your system?

    BR,
    Seong
  • Hey Seong,

    Thanks for the response.  I am using a Fluke 87 with 100ms averaging.

    Here is a picture of the setup on one of the boards running a simple blinking led program:

  • Hey Seong,

    I decided to try the 2.40 SDK to see if it would fix the issue but it unfortunately did not (still get FR errors).

    After that I tried the 3.10 SDK which also does not work (FR is okay but the file it writes to comes out empty with an impossibly large size for the amount of run-time).

    Also here is the portion of the code where the write fails (2.4 SDK) or creates an huge empty file (3.10 SDK):

    void inline write_blockdata_to_sd(uint32_t *blockdata, size_t blocksize, uint32_t timestamp){
    
         timestamp_start = (Clock_getTicks() * Clock_tickPeriod);
      
         fr = f_write(&src, &timestamp, 1 * sizeof(uint32_t), &bytesWritten);
         System_printf("fr after f_write timestamp %d\n", fr); System_flush();
         
         fr += f_write(&src, blockdata, blocksize * sizeof(uint32_t), &bytesWritten);
         
         System_printf("fr after f_write  %d\n", fr); System_flush();
         if(timeToSync)
             {
                fr += f_sync(&src);
                timeToSync = false;
             }
         if(fr){
             //This means we got an error result back from the fsync, or any of the rest of them, for that matter
             RYBfxn(Blue);
             System_printf("THERE WAS AN ERROR HERE\n"); System_flush();
             f_close(&src);
             sd_cleanup();
             CPUdelay(8000 * (1000));
             PIN_setOutputValue(SDCardPinHandle2, SDCARD_VCC, 0);
             SysCtrlSystemReset();
         }
         timestamp_end = (Clock_getTicks() * Clock_tickPeriod);
         timestamp_end = timestamp_end - timestamp_start;
         return;
    }

  • Hi,
    See if this example helps. This is for MSP432 but the procedure of using should be the same for Agama.

    dev.ti.com/.../
  • Hi F,

    (responding on behalf of Stephen Poanessa)

    Thank you for the example. I'm not sure how it applies.  Let me restate the problem.

    With the CC2640, we ported a FATFS.  Pseudo code for system operation is:

    • Initialize (including f_open)
    • Start SCS task to collect data from peripherals
    • While (1)
      • SCS reads data from peripherals and buffers in sensor controller memory
      • As the SCS buffer fills, move data to a 2nd buffer using M3 memory
      • Every 900 ms, write the data from the M3 buffer to the SD card (f_write)

    With the CC2642, we are trying to use the now-included TI FATFS.

    For SDK 2.30 and 2.40, using the same code as above, we receive FR errors (meaning the f_write operation failed).

    For SDK 3.10, there are no FR error, but the files consists of nothing but white space.

    A power-hungry work-around that provides the correct data to the SD card is this:  

    • Initialize 
    • Start SCS task to collect data from peripherals
    • While (1)
      • SCS reads data from peripherals and buffers in sensor controller memory
      • As the SCS buffer fills, move data to a 2nd buffer using M3 memory
      • Every 900 ms,
        • f_open
        • write the data from the M3 buffer to the SD card (f_write)
        • f_close

    Because there is a system call for f_open and f_close every 900 ms, the system power consumption increases from 1 mA (avg) to 20 mA (avg).

    We need to understand how to use the TI FATFS without need to close and open the file between each buffer and I don't see anything in the example that would affect this. 

    Is there something in the example that must be in place to allow multiple f_writes without need to f_close / f_open between each write operation?

    Thanks,

    Steve

  • Hi Steve and Stephen,

    I tested this myself using the following example:

    int32_t fatfs_getFatTime(void) {
        // Dummy
    }
    
    /*
     *  ======== mainThread ========
     *  Task to perform a raw write and read from the SD card.
     *  Note: Running this application will cause any filesystem on the
     *      SD card to become corrupted!
     */
    
    FATFS fs[2];         /* Work area (filesystem object) for logical drives */
    FIL fsrc, fdst;      /* File objects */
    BYTE buffer[4096];   /* File copy buffer */
    FRESULT fr;          /* FatFs function common result code */
    UINT br, bw;         /* File read/write count */
    BYTE workarea[4096];    /* Work area */
    
    void *mainThread(void *arg0)
    {
        Display_init();
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            /* Failed to open display driver */
            while (1);
        }
    
        Display_printf(display, 0, 0, "Starting the FATFS example\n");
    
        SDFatFS_Handle handle;
        SDFatFS_init();
    
        handle = SDFatFS_open(0, 0);
        if (handle == NULL) {
            //Error opening SDFatFS driver
            while (1);
        }
        
        /* Open source file, handle errors */
        fr = f_open(&fsrc, "myfile", FA_OPEN_EXISTING | FA_WRITE);
        switch (fr)
        {
        case FR_NO_FILESYSTEM:
            fr = f_mkfs("", FM_ANY, 0, workarea, sizeof(workarea));
            if (fr) while(1);
            fr = f_open(&fsrc, "myfile", FA_CREATE_NEW | FA_WRITE);
            break;
        case FR_NO_FILE:
            fr = f_open(&fsrc, "myfile", FA_CREATE_NEW | FA_WRITE);
        default:
            while(1);
        }
    
        if (fr) while(1);
    
        /* Write to file, sync, sleep, read, print, repeat ... */
        uint8_t counter = 0;
        char buffer [100];
        int cx;
        for (;;) {
    
            /* Write count as string to file ... */
            cx = snprintf (buffer, 100, "Count is: %d \r\n", counter);
            fr = f_write(&fsrc, buffer, cx, &bw);
            if (fr)
                break;
    
            /* Try to sync */
            fr = f_sync(&fsrc);
            if (fr)
                break;
    
            /* Sleep for 1 sec */
            sleep(1);
    
            counter++;
    
            /* Stop after 100 entries */
            if (counter > 100) {
                break;
            }
        }
    
        /* Close open files */
        f_close(&fsrc);
    
        while(1);
    
        return (NULL);
    }
    
    

    Running this, I do not see any issues writing to the open file while performing syncs. I use the 3.10 SDK and the third_part fatfs library from the SDK. 

  • Hey M-W,

    Sorry for the late response, I was pretty sick over the past two weeks and have not been in the office.

    Thank you for taking the time to put this great little program together. We compared your example to our code and found that the trick to avoiding the f_open and f_close was changing FIL* src to FIL src. By fixing this issue we were able to determine that it was not just the f_open/close operations that caused the high current consumption. We are now digging into the next layer of debugging to determine its source.

    Once again thank you for your time and assistance!

    - Stephen Poanessa