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.

Saving SD Card file immediately upon Power Failure

MCU: TM4C1294NCPDT

TI-RTOS: v2.01.00.03

CCS: v6.0.1.0040

-

Hi,

    I have an SD card connected to the MCU & the driver I am using is SDSPI. The file read/write operations I am performing are using TI-RTOS file access function (fwrite) & not elm-chan's file access functions. I have noticed that, if a file is open (in write mode) & data is being written to it (say once every second), the data written to the file after the file was opened is lost if power is withdrawn from the board.

    My application requires that whenever there will be a power removal from the system, the file should be immediately saved & all written data retained (I have a power retain window of some 100 mSec or 150 mSec). On my system hardware, the NMI pin is hardwired to the power fail detection circuitry. Whenever, there is a power fail detected, the NMI pin of the MCU is pulled high & NMI interrupt gets triggered (NMI function may have 100 mSec of time to do its work).

     I initially decided to keep the file handle in a global variable & whenever the NMI is triggered due to power failure, I will call fclose(file_handle) [from the NMI function]. But I wonder, what will happen if fwrite is called from a Task & while fwrite is NOT yet complete (not returned / function still running) & the fclose is triggered from the NMI function?

    Can anybody suggest some good way of implementing what I am trying to implement? Or some better way than what I am planning to incorporate?

-

Thanks

-

Regards

Soumayjit

  • Soumayjit,

    this can be a real tricky business. The FatFs module included with the TI-RTOS kernel uses semaphores for reentrancy protection, which means that you can't make FatFs calls from within a Hwi, Swi, or even the NMI for that matter. On another note, with the NMI, you can't call SYS/BIOS APIs either because BIOS it can't guarantee reentrancy with an interrupt that it can't disable.

    With FatFs, here is an app note that suggests how to minimize critical sections. Perhaps you need some sort of monitor task that periodically saves small chunks of data.

  • Hi Tom,

       Thanks for your opinion.

    PART 1:

       I would like to ask, what if I disable NMI inside the NMIsr function (my NMI service function) by re-configuring the NMI pin as a normal GPIO & then try to return from the NMI & take a quick action. Or is it that, NMI can never return even if I set the NMI pin as a GPIO (may be bcoz some NMI INTERRUPT Flag will be set which can not be cleared)?

       Also, what if I don't use NMI feature at all & keep the NMI pin as a GPIO right from the beginning of code execution. In this case, I am planning to read the status of the GPIO pin (power fail detection pin) just before initiating a file write. If a power fail detection is asserted, then I will call fclose() instead of calling fwrite() & I will wait in an infinite loop. At the same time, from some other Task (high priority task) I will execute the following code.

    while(1)
    {
        Task_sleep(50); // 50 mSec
        if(power_fail_detect() == true && flag_file_write_in_progress == false)
        {
          if(global_file_handle != NULL)
          {
            fclose(global_file_handle);
          }
          while(1);
        }
    }

       The variable, flag_file_write_in_progress will be set just before calling fwrite() & will be cleared after fwrite() returns.

    Whatever works out, I'll try these options & post here the results.

    PART 2:

       The link you provided, shows a function named f_sync(). Now, f_sync() function is part of elm-chan FatFs library, whereas I am using TI-RTOS FatFs library. My question is whether I can call both types of functions in the same Task? Somewhere (most probably in the TI-RTOS FatFs documentation/user guide) I found it is mentioned that mixing TI-RTOS FatFs & elm-chan FatFs may result into unpredictable behaviour of the FatFs & hence, its NOT recommended.

       Can I use f_sync() in my codes?

    PART 3:

       Even if, I use elm-chan's FatFs function f_sync() & due to some power failure I am unable to call fclose() function, will the data still be written successfully to the file?

    Thanks for your replies

    Regards

    Soumyajit

  • Soumyajit,

    Soumyajit Das said:
     I would like to ask, what if I disable NMI inside the NMIsr function (my NMI service function) by re-configuring the NMI pin as a normal GPIO & then try to return from the NMI & take a quick action. Or is it that, NMI can never return even if I set the NMI pin as a GPIO (may be bcoz some NMI INTERRUPT Flag will be set which can not be cleared)?

    Within the context of the non-maskable (in the NMI interrupt) or a zero-latency interrupt, you cannot make any SYS/BIOS calls. Reconfiguring while the NMI to a GPIO wouldn't work. Is there a problem to keep the pin a GPIO interrupt that just posts a Semaphore?

    Soumyajit Das said:

    PART 2:

       The link you provided, shows a function named f_sync(). Now, f_sync() function is part of elm-chan FatFs library, whereas I am using TI-RTOS FatFs library. My question is whether I can call both types of functions in the same Task? Somewhere (most probably in the TI-RTOS FatFs documentation/user guide) I found it is mentioned that mixing TI-RTOS FatFs & elm-chan FatFs may result into unpredictable behaviour of the FatFs & hence, its NOT recommended.

       Can I use f_sync() in my codes?

    Use FatFs APIs OR C I/O APIs. Using the C I/O APIs, you need to call fclose() to sync your changes. An fclose call also implies you need to call fopen again if you want to append to the file. The C I/O has no knowledge that the FatFs module buffers data so there really isn't any C I/O call that can be made to invoke a f_sync.

    Perhaps, you can rebuild the FatFs module with the options listed by the FatFs page so that it does not buffer its data within the FILE object (see _FS_TINY option) and instead you can use the C I/O buffering options shown in the CCS documentation, but both of these are options that haven't tested as part of the TI-RTOS product release.

    Soumyajit Das said:

       Even if, I use elm-chan's FatFs function f_sync() & due to some power failure I am unable to call fclose() function, will the data still be written successfully to the file?

    Thanks for your replies

    http://elm-chan.org/fsw/ff/en/sync.html

  • Hi Tom,
    Thanks for all your help. I have implemented the idea using a normal GPIO. A dedicated task is running once every 10 milli seconds which is checking the GPIO status continuously. If a POWER FAIL situation is detected by the logic level of the said GPIO, certain Semaphores are posted along with raising the priorities of those tasks where the corresponding Semaphore_pend() functions reside.
    -
    After implementing this, I find that the moment POWER FAIL is detected (with a maximum latency of 10 milli sec), the Tasks whose priorities are raised, gets unblocked & runs successfully to achieve the desired results. Both my SD card data as well as on-board serial FLASH are now protected from sudden power outage(s). I only made sure that the MCU & SD Card are powered at least 400 milli seconds after the POWER FAIL detection occurs.
    -
    Thanks
    -
    Regards
    Soumyajit