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)
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’:
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:
Note that you need to increase the number of volumes to match the number of drives:
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:
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:
Then simply select your existing memory or drive component:
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 🙂
If someone don’t understand ‘lazy’, lazy == practical
LikeLike
Pingback: Darth Vader Santa Claus Sumo Bot | MCU on Eclipse
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.
LikeLike
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?
LikeLike
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
LikeLike
thanks :-).
Yes, that way you can work with multiple devices. If using threads/tasks, make sure you turn on _FS_REENTRANT.
LikeLike