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.

TIRTOS USBMSCHFatFs, when is it safe to power down USBI am using

I am using USBMSCHFatFs on my TMS4C129ENCPDT processor and the USB reading is writing correctly to the USB memory stick.

TIRTOS_TIVAC version is 2_14_04_31

I currently have a couple of long Task_sleeps after I close the file (2000ms) and after I unmount the USBfs (500ms) before I power down the USB.  I have done this as I cannot see any function that tells me when the USB has finished writing back to its flash and it is safe to power down the USB drive.  I may have missed something and would appreciate if anyone can point me in the correct direction as to how I can determine when it is safe for me to power down the USB.

We are using the USB as an exporting tool on battery backed device and don't want to have the USB operating for any longer than required so we don't waste battery life.

  • Hi Barry,

    The FatFs APIs are blocking, so there should be no case where execution returns without the function having completed (like f_close).

    Additionally, theUSBMSCHFatFs driver automatically mounts the driver in the USBMSCHFatFs_open() function & un-mounts it in the USBMSCHFatFs_close(). As mentioned above, these APIs are also blocking until completion, so once you call USBMSCHFatFs_close() the USB is in a safe state.

    Regards,
    -- Emmanuel
  • It would seem this doesn't necessarily mean the USB drive is finished with its own internal write.

    When I turned the USB power of after doing f_close() and USBMSCHFatFs_close() the file existed but it had no contents (Just a small file with 157 characters in it).

    However when I sleep after the f_close() and the USBMSCHFatFs_close() the file exists and has the data correctly written to it.

    My code is just a simple test FatFS app and simply

    Powers up USB

    Waits for USB connect

    Creates the file if it doesn't exist, displays contents if it does

    Writes the contents to the file

    Read the contents and displays them

    Closes the file

    Closes the USB FatFS.

    Powers down the USB

    If I don't wait before turning off the power the file contents cannot be guaranteed, despite being able to read back as part of the test.

    The test code itself is:

    //
    //	Test function for USB FATFS
    //
    void	USBFatFSTest(void)
    {
      USBMSCHFatFs_Handle usbmschfatfsHandle;
      USBMSCHFatFs_Params usbmschfatfsParams;
      FRESULT fresult;
      UInt bytesRead = 0;
      UInt bytesWritten = 0;
      FIL src;
    
      // Mount and register the USB Drive
      USBMSCHFatFs_Params_init(&usbmschfatfsParams);
      usbmschfatfsParams.serviceTaskStackPtr = usbServiceTaskStack;
      usbmschfatfsParams.serviceTaskStackSize = sizeof(usbServiceTaskStack);
      usbmschfatfsHandle = USBMSCHFatFs_open(Board_USBMSCHFatFs0,
                                             USB_DRIVE_NUM,
                                            &usbmschfatfsParams);
      if (usbmschfatfsHandle == NULL)
      {
         System_printf("Error starting the USB Drive\n");
         System_flush();
         return;
      }
      else
      {
        System_printf("Drive %u is mounted\n", USB_DRIVE_NUM);
        System_flush();
      }
    
      // Power on the USB
      GPIO_write(Board_USB_EN, Board_LED_ON);
    
      // Need to block until a USB Drive has been enumerated
      if (!USBMSCHFatFs_waitForConnect(usbmschfatfsHandle, 10000))
      {
          System_printf("No USB drive present, exiting...\n");
          System_flush();
    			USBMSCHFatFs_close(usbmschfatfsHandle);
    		  // Power OFF the USB
    		  GPIO_write(Board_USB_EN, Board_LED_OFF);
    			return;
      }
    
      System_printf("USB drive connected\n");
      System_flush();
    
      fresult = f_open(&src, USBinputfile, FA_WRITE|FA_READ);
    	if (fresult != FR_OK)
    	{
    
    			if (fresult == FR_NO_FILESYSTEM)
    			{
    					System_printf("No file system\n");
    					System_flush();
    					USBMSCHFatFs_close(usbmschfatfsHandle);
    				  // Power OFF the USB
    				  GPIO_write(Board_USB_EN, Board_LED_OFF);
    					return;
    			}
    			System_printf("Creating a new file \"%s\"...\n", USBinputfile);
    			System_flush();
    
    			// Create file for both reading and writing
    			fresult = f_open(&src, USBinputfile, FA_CREATE_NEW|FA_READ|FA_WRITE);
    			if (fresult != FR_OK)
    			{
    				System_printf("Error: \"%s\" could not be created\n",	USBinputfile);
    				System_flush();
    				USBMSCHFatFs_close(usbmschfatfsHandle);
    			  // Power OFF the USB
    			  GPIO_write(Board_USB_EN, Board_LED_OFF);
    				return;
    			}
    	}
    
    	fresult = f_read(&src, readarray, f_size(&src), &bytesRead);
    	System_printf("Read %d\n", bytesRead);
    	System_flush();
    
    	// Reset the internal file pointer
    	f_lseek(&src, 0);
    	f_write(&src, textarray1, strlen(textarray1), &bytesWritten);
    	System_printf("Writing %d bytes to file \"%s\"...\n", bytesWritten, USBinputfile);
    	System_flush();
    
    	System_printf("Reading from file \"%s\"...\n", USBinputfile);
    	System_flush();
    
    	memset(readarray,  0, sizeof(readarray));
    	// Reset the internal file pointer
    	f_lseek(&src, 0);
    
    	//  Read from source file
    	fresult = f_read(&src, readarray, f_size(&src), &bytesRead);
    
    	// Write what we read
    	System_printf("Read %d\n%s", bytesRead, readarray);
    	System_flush();
    	// Close the file
    	f_close(&src);
    
    	Task_sleep(2000);
    
    	// Stopping the USB Drive
      USBMSCHFatFs_close(usbmschfatfsHandle);
      System_printf("Drive %u unmounted\n", USB_DRIVE_NUM);
    	System_flush();
    
    	Task_sleep(500);
    
    	// Power OFF the USB
      GPIO_write(Board_USB_EN, Board_LED_OFF);
    }
    

  • Just investigating further in the code of TiRTOS 2_14_04_31

    SD card driver for disk IO control  DRESULT SDSPITiva_diskIOctrl(BYTE drv, BYTE ctrl, void *buf) does:

            case CTRL_SYNC:
                /* Make sure that data has been written */
                if (wait_ready(hwAttrs) == 0xFF) {
                    Log_print1(Diags_USER2,
                               "SDSPI:(%p) disk IO control: control sync: ready",
                               hwAttrs->baseAddr);
                    res = RES_OK;
                }
                else {
                    Log_print1(Diags_USER2,
                               "SDSPI:(%p) disk IO control: control sync: not ready",
                               hwAttrs->baseAddr);
                    res = RES_NOTRDY;
                }
                break;
    

    where as the usb driver DRESULT USBMSCHFatFsTiva_diskIOctl(BYTE drv, BYTE ctrl, void *buf) simply does

            case CTRL_SYNC:
                Log_print0(Diags_USER1, "USBMSCHFatFs: disk IO control: OK");
                return (RES_OK);
    

    So it appears that the USB driver doesn't actually check if the flash is ready, it just assumes it is.

    This is also the case in TIRTOS 2_16_00_08