USB Mass Storage Device

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
Post Reply
User avatar
Badger
Posts: 346
Joined: Mon Apr 18, 2011 6:07 pm

USB Mass Storage Device

Post by Badger »

I've finally managed to cobble together a working mass storage driver

It mostly seems to work:

Image

Transfers are slowww over FS usb interface.. but that's all I have to test with at the moment :D

Improvements, suggestions, bug fixes etc are welcome. Code available at the github link above
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: USB Mass Storage Device

Post by mobyfab »

This is awesome, nice work!

Now you have to test it with the USB HS ;)
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB Mass Storage Device

Post by Giovanni »

Good work, how much slow? is it able to saturate the FS USB?

Giovanni
User avatar
Badger
Posts: 346
Joined: Mon Apr 18, 2011 6:07 pm

Re: USB Mass Storage Device

Post by Badger »

Looks like it runs at about 100KB/s... (that is writing to the disk via the file system, I couldn't get dd straight to the disk to work on my macbook)

So probably something isn't quite optimised right! I'll try benchmarking the R/W performance of the microSD card over SPI within chibios first to see what the max that can manage is.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB Mass Storage Device

Post by Giovanni »

I think it could be improved by implementing an asynchronous prefetch mechanism and a cache.

Giovanni
User avatar
Badger
Posts: 346
Joined: Mon Apr 18, 2011 6:07 pm

Re: USB Mass Storage Device

Post by Badger »

That sounds like a good suggestion.

The driver could do with a mechanism for making sure that the usb transaction doesn't complete before the thread goes to sleep, so that it will always get woken. I suppose the usb callback should set a variable somewhere to indicate that an even has occurred, which is checked before going to sleep.
User avatar
Badger
Posts: 346
Joined: Mon Apr 18, 2011 6:07 pm

Re: USB Mass Storage Device

Post by Badger »

I did a test, the fastest I can read from my microSD over SPI3 (so not the fastest SPI) is about 360KB/s. I'll try pre-fetching the data
User avatar
Badger
Posts: 346
Joined: Mon Apr 18, 2011 6:07 pm

Re: USB Mass Storage Device

Post by Badger »

I have mostly implemented the cached read/write, but I'm having problems with waking the thread when a USB read or write callback is called.

My strategy is to use a binary semaphore, initialised as taken. The worker thread issues the USB transfer and the. Calls chBSemWait(). The callback wakes the thread with chBSemSignal. This all works fine until the USB transfer completes before chBSemWait() is called. Am I doing something wrong here? It seems like the bsem should be untaken as the callback signalled it so Id expect chBSemWait() to return immediately but it hangs!

BTW the code with caching and semaphores is not yet published as I am travelling on a train whilst working on this..
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB Mass Storage Device

Post by Giovanni »

Not sure, try posting some code related to the sem.

Giovanni
User avatar
Badger
Posts: 346
Joined: Mon Apr 18, 2011 6:07 pm

Re: USB Mass Storage Device

Post by Badger »

Here's a summary of how I'm using the binary semaphore. Any ideas?

Code: Select all

   /* initialise binary semaphore as taken */
   chBSemInit(&msdp->bsem, TRUE);

...

    usbPrepareReceive(msdp->usbp, USB_MS_DATA_EP,
            (uint8_t *)&msdp->cbw, sizeof(msd_cbw_t));

    chSysLock();
    usbStartReceiveI(msdp->usbp, USB_MS_DATA_EP);
    chSysUnlock();

   /* sleep until it completes */
   chBSemWait(&msdp->bsem);

/* then in the end point callback: */
void msdUsbEvent(USBDriver *usbp, usbep_t ep) {
   (void)usbp;
   (void)ep;

   chBSemSignalI(&((USBMassStorageDriver *)usbp->param)->bsem);
}
Post Reply