AnsweredAssumed Answered

fclose on SDCard filesystemhandle hangs

Question asked by Tobias Bystricky on Dec 3, 2013
Latest reply on Jan 13, 2014 by T J

Hello,

if we are using the sdcard we are facing the following problem.

We are mounting the SDCard:

void SDCard::mount()
{
    static const char szOpenMode[4] = "rw";
    
    if ( (NULL != filesystem_handle) ) { return; }


    _mqx_int error_code = MFS_NO_ERROR;
    
  if (NULL == com_handle)
  {
  _mqx_uint un32Param = SPI_FLAG_FULL_DUPLEX;

  /* Open low level communication device */
  com_handle = _io_fopen(com_name, (const char *)un32Param);

  /* Install SD card device */
  if ( MQX_OK != _io_sdcard_install((char *)str(ms_szName), (SDCARD_INIT_STRUCT *)&_bsp_sdcard0_init, com_handle))
  {
  _io_puts("\n");
  _io_puts(com_name);
  _io_puts(" unable to install device.");
  }
  }

  if (NULL == sdcard_handle)
    {
  /* Open the device which MFS will be installed on */
  sdcard_handle = _io_fopen(str(ms_szName), szOpenMode);
  if (NULL == sdcard_handle) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" unable to open device.");

  return;
  }

#if 1
  Tun32int un32Param = 0;
  if (IO_OK != _io_ioctl(sdcard_handle, IO_IOCTL_SET_FLAGS, (pointer)&un32Param))
  {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error setting flags ");


  return;
  }
#endif

    }


  /* Install partition manager over SD card driver */
  error_code = _io_part_mgr_install(sdcard_handle, partman_name, 0);
  if (IO_DEVICE_EXISTS == error_code)
  {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" partition manager already installed ");
  }
  else if (MFS_NO_ERROR != error_code) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error installing partition manager: ");
  _io_puts(MFS_Error_text((uint_32) error_code));
  _io_puts(" unable to open device.");


  return;
  }

  _time_delay (20);


#if 0
  if ( !isAvailable() )
  {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" no card inserted ");

  turnOff();
  return;
  }
#endif


#if 0
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" installing MFS over SD card driver...");
#endif

  /* Install MFS over SD card driver */
  error_code = _io_mfs_install(sdcard_handle, filesystem_name, (_file_size) 0);
  switch (error_code)
  {
  case MFS_NO_ERROR:
  break;
  case IO_DEVICE_EXISTS:
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" MFS already installed ");
  break;
  default:
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error initializing MFS: ");
  _io_printf("(%04x) ", error_code);
  _io_puts(MFS_Error_text((uint_32) error_code));

  return;
  }

  /* Open file system */
  filesystem_handle = _io_fopen(filesystem_name, (char)0);
  if (NULL == filesystem_handle)
  {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error opening filesystem: NULL pointer returned. ");


  return;
  }
  error_code = _io_ferror(filesystem_handle);
  if (MFS_NO_ERROR != error_code) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error opening filesystem: ");
  _io_printf("(%04x) ", error_code);
  _io_puts(MFS_Error_text((uint_32) error_code));


#if SDCARD_AUTO_FORMAT
  if (error_code == MFS_NOT_A_DOS_DISK) {
  error_code = _io_ioctl(filesystem_handle, IO_IOCTL_DEFAULT_FORMAT, NULL);
  }

  if (MFS_NO_ERROR != error_code)
  {
#endif


  return;
#if SDCARD_AUTO_FORMAT
  }
#endif
  }


  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" mounted to ");
  _io_puts(filesystem_name);
}


void SDCard::unmount() {
  Tun32int error_code;


  /* Close the filesystem */
  if ((NULL != filesystem_handle)
  && (MQX_OK != _io_fclose(filesystem_handle))) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error closing filesystem.");
  }
  filesystem_handle = NULL;


  /* Uninstall MFS  */
  error_code = _io_mfs_uninstall(filesystem_name);
  if ( (IO_DEVICE_DOES_NOT_EXIST != error_code) && (error_code != MFS_NO_ERROR) ) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error uninstalling filesystem ");
  _io_printf("(%04x)", error_code);
  }


  /* Uninstall partition manager  */
  error_code = _io_part_mgr_uninstall(partman_name);
  if ( (IO_DEVICE_DOES_NOT_EXIST != error_code) && (error_code != MFS_NO_ERROR) ) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error uninstalling partition manager ");
  _io_printf("(%04x)", error_code);
  }


  /* Close the SD card device */
  if ((NULL != sdcard_handle)
  && (MQX_OK != _io_fclose(sdcard_handle))) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" unable to close SD card device.");
  }
  sdcard_handle = NULL;


#if SDCARD_DEEP_CLEAN
  if (MQX_OK != _io_dev_uninstall((char *)str(ms_szName))) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" unable uninstall device.");
  }

  /* Close the ESDHC device */
  if ((NULL != com_handle) && (MQX_OK != _io_fclose(com_handle))) {
  _io_puts("\n");
  _io_puts(com_name);
  _io_puts(" unable to close ESDHC device.");
  }
  com_handle = NULL;
#endif


  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" unmounted.");
}

 

After the mounting the access to the sdcard works well.

Then we do the unmount.

void SDCard::unmount() {
  Tun32int error_code;


  /* Close the filesystem */
  if ((NULL != filesystem_handle)
  && (MQX_OK != _io_fclose(filesystem_handle))) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error closing filesystem.");
  }
  filesystem_handle = NULL;


  /* Uninstall MFS  */
  error_code = _io_mfs_uninstall(filesystem_name);
  if ( (IO_DEVICE_DOES_NOT_EXIST != error_code) && (error_code != MFS_NO_ERROR) ) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error uninstalling filesystem ");
  _io_printf("(%04x)", error_code);
  }


  /* Uninstall partition manager  */
  error_code = _io_part_mgr_uninstall(partman_name);
  if ( (IO_DEVICE_DOES_NOT_EXIST != error_code) && (error_code != MFS_NO_ERROR) ) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" error uninstalling partition manager ");
  _io_printf("(%04x)", error_code);
  }


  /* Close the SD card device */
  if ((NULL != sdcard_handle)
  && (MQX_OK != _io_fclose(sdcard_handle))) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" unable to close SD card device.");
  }
  sdcard_handle = NULL;


#if SDCARD_DEEP_CLEAN
  if (MQX_OK != _io_dev_uninstall((char *)str(ms_szName))) {
  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" unable uninstall device.");
  }

  /* Close the ESDHC device */
  if ((NULL != com_handle) && (MQX_OK != _io_fclose(com_handle))) {
  _io_puts("\n");
  _io_puts(com_name);
  _io_puts(" unable to close ESDHC device.");
  }
  com_handle = NULL;
#endif


  _io_puts("\n");
  _io_puts(str(ms_szName));
  _io_puts(" unmounted.");
}

This works also well.

But after repeating the progress three time the unmount hangs in the fclose of the SDCard.

We take a deeper look inside and found out that it hangs in a sem_destroy.

Could it be a problem if different tasks mount / umount the SDCard?

Can someone help?

Thanks and regards,

 

Tobias

Outcomes