AnsweredAssumed Answered

fclose on SDCard filesystemhandle hangs

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

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