Multi-Drive Support with FatFS

I admit: I’m sometimes a lazy person. In my projects, I only needed one ‘disk drive’ with the FatFS Processor Expert component: either a SD card or a USB MSD drive. But a reader of this blog wanted to use FatFS with multiple drives: using it with an SD card and a USB MSD drive. And actually FatFS does support this, I just had no need for it, thus I did not add anything special for it. But that reader let me think that I better add Multi-Drive support. Even if I do not need it now, that could be very handy in the future 🙂

FatFS Drive System (Source http://elm-chan.org/fsw/ff/en/appnote.html)

FatFS Drive System (Source http://elm-chan.org/fsw/ff/en/appnote.html)

Multi-Drive Support with the FatFS Component

The way how Processor Expert components are implemented made it pretty easy to extend the existing FatFS component from using a single drive to a ‘multi-drive component’: Instead linking to a single ‘memory’ or ‘drive’ component, I changed the interface to use a ‘list of drives’:

FatFS with List of drives

FatFS with List of drives

List of Drives

I can now increase or increase that list of drives: the screenshot below shows an SD card and a USB MSD drive in the list:

Increasing the number of drives

Increasing the number of drives

Note that you need to increase the number of volumes to match the number of drives:

Number of Volumes in FatFS

Number of Volumes in FatFS

What might be somewhat confusing is how ‘drive’ and ‘volumes’ are related: by default each drive has a single volume, which means there is a single partition per drive. This is set by the _MULTI_PARTITION setting in FatFS:

Multipartition

Multipartition

As another laziness on my side: I have never used multipartion support with FatFS, as all my drives had only one partition on it. Be free to experiment with that setting yourself ;-).

CDE Implemenation

If you are interested how to implement such a ‘list of components’ (actually it is a ‘list of references to components’) with the Processor Expert CDE (Component development environment), then I invite you to have a look at my implementation on GitHub here.

I can get the number of items in the drives list from the DriveSymbolNumItems symbol and assign it to a local script variable (maxDrive):

%- -------------------------------------------------------------------------------------------
%:maxDrive=%DriveSymbolNumItems
%:maxDrive-=1
/*-----------------------------------------------------------------------*/

I decrease then the value as I want to have it from 0..(n-1). Then I can use that variable to dynamically generate the code with:

DSTATUS disk_initialize (
        uint8_t drv %>40 /* Physical drive number (0..) */
)
{
  switch(drv) {
    %for i from [0..%maxDrive]
    case %i:
      return %@Drive%i@'ModuleName'%.disk_initialize(drv);
    %endfor
    default:
      break;
  } /* switch */
  return RES_PARERR;
}

this then gives for one drive:

DSTATUS disk_initialize (
        uint8_t drv                     /* Physical drive number (0..) */
)
{
  switch(drv) {
    case 0:
      return SD1_disk_initialize(drv);
    default:
      break;
  } /* switch */
  return RES_PARERR;
}

or for two drives:

DSTATUS disk_initialize (
        uint8_t drv                     /* Physical drive number (0..) */
)
{
  switch(drv) {
    case 0:
      return SD1_disk_initialize(drv);
    case 1:
      return FsMSD1_disk_initialize(drv);
    default:
      break;
  } /* switch */
  return RES_PARERR;
}

I think this is very, very cool!

Porting Existing Applications

Unfortunately, the multi-drive support in the component required changing a few interfaces. If you are using the earlier FatFS component in your application and load the new component, you will get an error in your project that the component is not selected:

Component not selected

Component not selected

Then simply select your existing memory or drive component:

Selecting Existing Drive

Selecting Existing Drive

and your are good to go!

Application Code

If having multiple drives and volumes, it means I need to mount each of them with the mount() FatFS call. For this, the ‘vol’ argument is used. If using a one-to-one mapping of volumes and drives, the first volume/drive is 0, the second is 1, and so on:

/*-----------------------------------------------------------------------*/
/* Mount/Unmount a Logical Drive                                         */
/*-----------------------------------------------------------------------*/

FRESULT f_mount (
    uint8_t vol,        /* Logical drive number to be mounted/unmounted */
    FATFS *fs        /* Pointer to new file system object (NULL for unmount)*/
);

From your application, the drive 0 is references as

0:/

And so, drive 1 is:

1:/

So if you are using the Shell of the FatFS component, listing the directory of volume/drive one is:

FAT1 dir 1:/

Summary

I should have done it right from the beginning and added multi-drive support to the FatFS component. But sometimes a good question from a reader makes me think and to make a difference, especially it is not that hard to do. Not that I can do it for every wish or request, but if a lot of people (including my self) can benefit from a change, than it’s the way to go :-).

The updated components are available on GitHub

Happy Multi-Driving 🙂

6 thoughts on “Multi-Drive Support with FatFS

  1. Pingback: Darth Vader Santa Claus Sumo Bot | MCU on Eclipse

  2. Hey this is a great idea. I’m trying it with a K20DX128xxx70 (though moving to a K20DX256xxx70 next hw rev) and running into a problem with SDHC component.
    I brought the FatFsMemSDHC into the project, and it included SDHC1 says: “Target processor does not contain a peripheral of this type” ?
    Any help appreciated?
    I’m expecting to be able to use SPI0 – and SDHC1 seems to suggest I should be able to allocate pins – but it doesn’t know about them. I’m probably missing something basic. Many thanks.

    Like

    • I quickly tried that CPU (created a project for it). And indeed, SDHC is not supported (or not present) on that device. So not sure if this is a problem of the data sheet or of Processor Expert. But you might use SPI instead?

      Like

  3. Hey Erich ,
    Great post very useful.
    Just want to understand does this support multi-device access on all time ( example can I open SD card and USB both and mount both of them and writing file in both simultaneously ?)
    does is directly supported or need to change config ?? apart from initialization mentioned

    Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.