PhatIO Uses File System To Control External Hardware

[Andrew Smallbone] wrote in with a link to his latest open source project. This is phatIO, a USB I/O device that uses a mass storage file system for control. The idea is that any operating system can manipulate files on a USB storage device. This enumerates as mass storage, and any alterations you make to its file system will result in pin manipulation on the I/O header.

We’ve long been Linux advocates and enjoy the fact that everything on a *nix system is a file. This simply extends the idea across multiple platforms. [Andrew’s] guide for the hardware gives an overview of how the system is structured. The top ‘io’ directory contains sub-directories called mode, pins, status, and a few others. Inside the directories are files for each pin. Writing to these files has much the same effect as writing to a data direction register, port register, or reading a pin register on a microcontroller.

The board is not yet in production and the github link to his hardware files gives us a 404 error. But there is code available for several software demos. After the break we’ve included video of the phatIO driving a Larson scanner.

27 thoughts on “PhatIO Uses File System To Control External Hardware

    1. Yes but if you mount the media using the “sync” option you get synchronous writing. It’s not safe on flash disks since it forces a higher number of writes, but in this case it’s ok. In software you can use the fsync() call after any write to get immediate data flush on disk (this device).
      Not sure about Windows, but certainly there’s a way to accomplish the same thing there too.

      1. The device identifies itself as a removable media to ‘encourage’ synchronous write. There is still a filesystem buffer/delay – you wouldn’t want to try to toggle a pin thousands (or even hundreds) of times a second. There’s built in functionality for PWM, TWI, SPI etc so you can configure a simple ‘device driver’ for a file that does the ‘high bandwidth’ stuff. There’s an example in the ideas section that shows how to hide an Adafruit TWI 7 segment display behind a device file – write “0123” to the file and phatIO will convert the ASCII text and do the TWI communication to get the numbers on the display.

    1. Getting I/O lines on systems where they are not provided. Of course this is pointless if you already have a USB/serial port since it’s easy to program any USB/serial equipped PIC or other microcontroller to act as a slave and control its ports, but if all you have on your board is a slot for external flash memory then it could have its use.

  1. Lots, lots and lots of advantages. Not to sound positive, but what would be the disadvantage of this, LOL? I could plug this right into the usb port (or a powered connected hub) on my Raspberry Pi and instantly have analog and pwm. No mucking about with I2C or any of the Pi’s GPIO stuff. And not to mention that the very very same brain-dead perl code java or other code that only does file i/o can read and write digital, analog, and pwm, on practically any platform, linux, mac windows whatever.

  2. This would be great if timing isn’t an issue. If you were just toggling bits to turn a light on, or reading a switch, especially if it debounces in hardware, then this would be great. But it wouldn’t run a midi port after the lags you would get first from going through the file system layer, and then the usb layer.

  3. This is beautiful. Sure you can say it’s inefficient, but hey. Sometimes it’s way more important to just have physical I/O than anything else. One could totally use this to get around various app platform’s unwillingness to allow programs access to physical hardware, but still allow filesystem access.

  4. @Jimmy the very same [somewhat lack of] timing issues already exist in linux and probably windows and many other platforms that aren’t considered a “realtime os” — there’s lots of discussion of that in the RPi vs Arduino type discussions.

    As Mike said in the post, “everything on *nix is a file” and so any timing issues that exist in any usb device are either a) irrelevant or b) accounted for. Even a webcam under linux is a “file” that’s accessed under /dev/usb or some path in the filesystem. What would be more realtime than a live camera?

    Now granted there will be latencies introduced at every layer, but a designer has to know about these and deal with them anyway. Actually I’m not sure what sort of a delay, can’t be much at all, is present with a usb filesystem that doesn’t involve either mechanical read/write hardware or the read speed limitations of flash memory. Once the AVR chip processes the USB signals its response would be limited only by its code efficiency and clock speed, maybe the sampling rate in the case of analog input, but even that’s moot if it’s running the samples in the background between file read requests from the host.

  5. At first glance, this seems slick, but the more I have thought about it, the more difficulty one will have with the implementation. Not all OSes are going to have easily and reliably controlled fs cache settings. What happens when someone deletes one or more of these special files? renames one, or more, or renames a directory? creates a file? I am sure it will reset if you unplug and plug it back in, but what happens until you do? Do you error out to prevent such things from happening? Will that cause other problems?

    I am really curious if there is actual mass storage that is being read and written to by the host system as well as whatever is embedded on this board, or if that storage area is entirely virtual and handled by parsing the intent out of the reads and writes that the host system is attempting to do. Looks like I have some reading to do.

    1. maybe not allow the os to delete the file, giving it an ioerror instead? or if implementing a filesystem with better rights management and having the special files without delete access?

  6. The O in I/O sounds great, despite many possible problems with the OS delaying writes, but what of when you want to read IN data as infrequently as once a minute. Any reasonably optimizing OS will assume it’s the only one modifying the filesystem, and so -unless it handled a write operation- the data will be the same as last time. How does that work?

  7. im suprised that most of the windows users here
    have never ventured into the regular windows control panel !!!

    there is a setting called “write cache for this drive”
    turn it on or off and reboot :)

    (well in windows 3, 95, 98, ME, 2000, XP)
    i have absoloutely no idea if vista, 7, or 8 have this setting

    the only gripe with windows i have here is;
    you have to reboot for it to take effect.

    assuming you SUCESSFULLY rebooted,
    then whatever you set writecache to on that drive,
    it will remain next time you plug it in

    PS: i highly doubt it includes flash as MSC.
    why? you only need about 50 or 100 *_BYTES_*
    it does not need to store anything when unplugged,
    thats what the USB and _real_ HDD are for

    PPS: the delete command? im sure the device does not HAVE a delete command, so windows would just error or maybe device says “readonlyfile” After that im sure user would unplug, then re-plug and never make that mistake again.

  8. I looked into this option several years ago. I could not find any way inside Windows to guarantee a sync, short of writing my own Windows device driver (which defeats the purpose of using a usb mass storage device). For one way communications with no time guarantee, it does work, (i.e. Windows will eventually write whatever file you wrote/modified to the device), but, if you are trying to read dynamic data from the device, it will not work simply because after you’ve read the file once, Windows will just return the cached file (yes, I tested this). The only work around would be to create a new file each time, at which point the whole thing got too messy.

    I hope someone can figure out a better way, as it would be really nice to build usb systems this way.

    1. If you call the Windows API CreateFile function (which also opens existing files) with the FILE_FLAG_NO_BUFFERING flag, disk caching for both read and write are supposed to be completely bypassed. Note that for any file opened with this flag, you’re “limited” to reading/writing whole sectors. All transfers must be sector-aligned, and must be a multiple of one or more complete sectors in length.

      I say “limited” because I’m fairly sure that communications between *any* OS (not just Windows) and a USB mass storage device always occurs in whole sectors anyway. Even if you just want to write a single byte, the entire sector must always first be read, then modified and rewritten; either explicitly by you in this case, or perhaps behind the scenes in some other OS. Quite inefficient from a bus utilization standpoint, as if the caching issues weren’t enough.

  9. Conceptually this is at least 15 year old approach, which I totally admire and have been using for 10 years. Not the USB implementation but the 1 Wire Dallas bus where all devices on the bus show up as files within a user space file system. How simple and genius to bypass all the OS crap and present physical devices as files. I would have loved to see the IO board on an Ethernet network instead of USB but I’m sure that’s coming soon.

    For those interested in network-attached sensors showing up on the file system here is what I have been running for at least 10 years and still waiting to find a defect or crapout:

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

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