64

USB storage devices, such as USB sticks and harddrives, are common to attach external storage to any kind of computer. How can the Raspberry Pi emulate an USB storage? The easiest application was to directly access the SD card via USB, but one could also provide acccess to files via Ethernet. I thought about the following layout for an "USB cloud stick":

Computer <---USB---> |Raspberry Pi| <---Ethernet---> Cloud, NAS etc.

The computer should only see a normal USB stick to read and write files from. The Raspberry Pi would act as programmable bridge that map directory listings and file accesss to request to a cloud storage. You could access cloud storage hosters with any computer (including black box media players) via USB without having to install any additional software on the computer. The Raspberry Pi USB bridge should also be able to encrypt/decrypt files on the fly, so one could store files encrypted in the cloud and access them on any device like a normal USB drive.

Edit: Existing products with similar but limited functionality include Wireless Media Stick and USB-over-Network. Access to files in the cloud may be possible by mounting virtual storage with cloud drive or similar software and encryption with TrueCrypt or EncFS - passwords would be stored on the SD card of Raspberry Pi only but one could access the storage with any computer without having to type in a passphrase on a untrusted machine.

Jakob
  • 2,768
  • 5
  • 23
  • 22

10 Answers10

16

EDIT: This answer only applies to older Raspberry Pi devices. The Raspberry Pi 4 (and the Pi Zero) support USB Gadget Mode which allows what the OP is asking for. The rest of this post only applies to Raspberry Pi 1, 2 and 3 which do not have hardware support for USB Gadget Mode.


The problem is that the Pi's USB connection to the PC doesn't have the data pins connected - only the power pins. So you can't use this to speak USB because it's not wired up.

Your only option with the Pi would be to 'bit bang' USB using the GPIO pins, but this is very slow and potentially unreliable. I suspect you would only really be able to emulate a keyboard or mouse - anything higher bandwidth would probably be too much for the CPU to cope with, given the tight timing requirements of bit banging something like USB.

Another alternative would be to find a device that lets you connect two computers together via USB, to make a kind of network. But then you may as well just use the Ethernet connection...

Malvineous
  • 2,109
  • 15
  • 25
9

Based on a quick perusal of the BCM2835 data sheet (http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf) chapter 15, it looks like USB OTG is supported in HW, so theoretically, it might just be a matter of SW to support the proposed scheme. I'm not a USB protocol expert (or even novice, really), but it would be pretty cool to have this functionality.

Looking at a description of the BeagleBone (http://elinux.org/BeagleBone), it appears to support something similar, although there is specific mention of a connector that supports this mode. It would be unfortunate if the Raspberry Pi is limited due only to connector selection.

Hope this is helpful.

8

This now seems to be possible using a PiZero - see https://web.archive.org/web/20210120154409/http://pi.gbaman.info/?p=699 for more.

aleb
  • 173
  • 5
David Walters
  • 111
  • 1
  • 3
5

Unfortunately though this seems simple, as best as I can tell, it hasn't been done. See this thread and very detailed answer for more details

https://unix.stackexchange.com/questions/2683/serve-files-over-usb

And a Pi specific answer here: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=8&t=4938

wmarbut
  • 1,113
  • 1
  • 9
  • 16
4

If you aren't particularly concerned about performance, you could probably get a USB capable microcontroller with USB mass storage code (you could for example reprogram the STM32F103 debug interface on a $10 STM32F0 discovery eval module), carefully connect that to the pi's serial port as a back end, and run at several hundred kilobaud.

Better performance would likely be had by interfacing to the client PC via ethernet, but that would require a custom driver or different presentation to the host operating system - ie, you'd be a network attached storage device or share server.

Off the shelf file transfer cables were I believe already mentioned, but that would require appropriate software for the client PC and source-level linux driver support for the pi end.

Chris Stratton
  • 993
  • 5
  • 11
4

I found out that Arduino can emulate a USB device, the Arduino Leonardo even out of the box. The LUFA USB stack can be used on Arduino and it implements a USB mass storage device driver (see this tutorial). This setup could be used to map USB to SCSI commands such as understood by the SD card reader. I don't know enough about SCSI but it looks like the SD card on Raspberry Pi and the USB-via-Arduino could be used together on the same bus. Sure this idea is not a full solution...

Jakob
  • 2,768
  • 5
  • 23
  • 22
4

The Pi Zero and Pi Zero W are now available and support the Gadget interface (Kernal.org, linux-sunxi.org) allowing several different profiles, including USB Mass Storage and virtual networking.

The closest solution to the OP's request is to use a networking protocol between the Pi and the host PC, and then some other form of networking protocol from the Pi to the cloud/network provider. The Pi Zero W has builtin Wi-Fi, so could even connect directly to the cloud/network provider. Networking both of those links will be the easiest way to get the job done. There are many networking protocols and cloud providers available.

Trying to use USB Mass Storage would be a bad idea; you would have to write or rewrite a driver-level adaptation between USB Mass Storage and the Pi. You'd either start with MTP, or wind up with something similar. MTP has severe performance issues (Reddit, XDA, HowToGeek, Reddit) so I suggest the networking approach.

There should be lots of programs and projects in that direction. From the Pi's perspective, it's just acting like a fileserver/sync server, so any similar tutorial should get you started. Looking into things like Pi-based Seafile, Syncthing, SugarSync, and OwnCloud servers should get you started.

A few useful guides on the Pi Zero as a USB Gadget:

Jan
  • 13
  • 4
YetAnotherRandomUser
  • 1,120
  • 2
  • 11
  • 34
2

This comes down to how USB works, you see whenever two things are connected with USB there is all ways a USB host and a USB device and never the twain shall switch places. A USB host does all kinds of things that USB devices cannot do mostly to sync up data transfer between all devices connected to the USB bus. Check out the USB wikipedia page for more info.

What you're talking about doing is forcing two USB hosts (the Raspberry Pi and a computer) to communicate which unfortunately is simply not supported by the USB standard. There are some devices which can fake a data transfer between two USB hosts but as Malvineous mentioned you'd be better off using ethernet.

Your question specifically mentions using the Raspberry Pi to emulate USB storage but have you considered setting up the Raspberry Pi as a NAS? Using the Raspberry Pi as a NAS box basically does exactly what you asked for but instead of using USB it would be using your network. Here are great instructions on how to do this if you are interested.

Dan B
  • 2,907
  • 2
  • 21
  • 20
2

I can do it with my old Nokia N900 Phone using the usb gadget driver included with the stock Nokia kernel. The emulated device behaves exactly like a real one, you can even boot a PC from it.

Nyg
  • 21
  • 1
1

The USB standard are host based. That means that one device has to controll all communication with the connected devices. Clients can be a simple device or a hub. The hub is a host proxy for the clients connected to the hub, and communicates with the host (or hub) it's connected to.

As the original design of USB looks, you can't connect two hosts together (your PC and the RPi).

There are extentions though, USB On-The-Go, which allow a USB connection to see if it is connected to a host or a client, and adjust it's role depending on that. To this to work, you have to have support in the hardware. I don't belive the RPi is designed to do that.

For more information, look att http://www.usb.org/home or even http://en.wikipedia.org/wiki/Universal_Serial_Bus

In short, I don't belive that it can be done.

Anders
  • 424
  • 2
  • 6