cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to make USBX and FileX working on same sd-card

Led
Senior

Current working device
For a client we developed a device using stm32F469 that writes sensor data to an sd-card periodically. Later the data are read out from sd-card by connecting it via USB to a computer, using USBD_MSC_CLASS. The system uses FreeRTOS, FatFS, ST USB driver. This works well (using blocking write and read commands to SDIO). The two paths to access the sd-card (from the MCU software using FatFS and the access from Windows using USB driver from ST) is separated by the MCU software, using init and de-init functions of the modules.

 

New approach

Now I wanted to transfer it to Azure RTOS using ThreadX, FileX, UsbX. The access to SDIO shall be done with DMA (fx_stm32_sd_write_blocks() calls BSP_SD_WriteBlocks_DMA()). The interrupt callbacks from SDIO (transfer completed) are rerouted with callback functions, depending on who (FileX or UsbX) accesses the sd-card.

 

However this does not work with the following issues:

  • UsbX and FileX worke fine when I disable all FileX write-to-file (fx_file_write()) commands.
  • Enable the FileX write-to-file (fx_file_write()) fails with SDIO driver timeout: SDIO_FLAG_CTIMEOUT in SDMMC_GetCmdResp1().
  • A first workaround is to use blocking SDIO function calls for FileX (fx_stm32_sd_write_blocks() calls BSP_SD_WriteBlocks()), and adding a timeout after the NOTIFY macro in fx_stm32_sd_driver.c sd_write_data():
  sd_write_data(..){
    [..]
    status = fx_stm32_sd_write_blocks(FX_STM32_SD_INSTANCE, (UINT *)media_ptr->fx_media_driver_buffer, (UINT)start_sector, num_sectors);
    if (status == error){..}
    FX_STM32_SD_WRITE_CPLT_NOTIFY();  /* --> This calls tx_semaphore_put(&transfer_semaphore); */
    tx_thread_sleep(10);              /* --> delay added as workaround  */
    [..]
  }
  fx_stm32_sd_write_blocks(..){
    [..]
    if (BSP_SD_WriteBlocks((uint32_t *)buffer, start_block, total_blocks, 2000) != MSD_OK)  {    ret = 1;  }
    FX_SD_WriteCpltCallback(); /* --> this function is (should be) called by ISR when using DMA. 
                                      It executes: tx_semaphore_put(&transfer_semaphore);
    return ret;
  }
  • This workaround solves the write issue of FileX. However, when connecting to USB afterwards, the drive appears in Windows Explorer, but Windows is unable to read it.
  • Plugging the sd-card with a card reader to Windows directly, the filesystem needs to be fixed, and then the files are available including the written data, which could be written thanks to the above described workaround.

==> So looks like having issues with synchronization and threads...

 

Questions that possibly help:

  • UsbX itself creates 2 threads inside the third party code. FileX not. Do I need to create threads for FileX
  • Before accessing the sd-card with FileX in the MCU software, HAL_PCD_Stop() is called to stop UsbX access. This is maybe not enough to kill UsbX access to sd-card. (Unfortunately ST does not implement de-init functions, so it is not really clear what functions must be called...)
  • I thought about using Mutex instead of de-init of the USB module. I did not do so yet because UsbX does the access to sd-card directly. No simple interface is provided by the ST driver as for example done in FatFS.

Thanks for any support!

5 REPLIES 5
Saket_Om
ST Employee

Hello @Led,

Could you please share your project files so we can analyze and assist you more effectively?

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

Unfortunately it is a client project and I cant share it. What I can provide is parts of the code, without the sensitive parts. Still I dont want to publish it. I'll send you a post with the access data.

Led
Senior

Unfortunately I still waste a huge amount of time to find a fix.

Let me ask a simplified question:
What are reasons for SDIO_FLAG_CTIMEOUT in SDMMC_GetCmdResp1?

Especially with the focus using SDIO with DMA, FileX and USBX together.
As my implementation sometimes (seldom) works, I assume synchronization and priority issues.

Hello @Led 

The flag SDIO_FLAG_CTIMEOUT is set when a command response is not received within the expected time frame.

The Command TimeOut period has a fixed value of 64 SDIO_CK clock periods. Please refer to the reference manual for more details.

Saket_Om_0-1732611601508.png

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

Hi @Saket_Om 
Thanks for your reply. The questions remains what are the reasons for it?

With debugger I see
- In SDMMC_CmdReadSingleBlock() a command is sent to SDIO
- Then SDMMC_GetCmdResp1() is blocking-waiting for an answer.
Why should the answer not come? Knowing that writing via USB works, but writing via FileX does mostly not work.