M-Stack open source USB stack for PIC microcontrollers


Here is an open source USB stack for PIC microcontrollers and DSPs. It features a dual LGPL and Apache licenses making it suitable for commercial open source projects. So far it only supports the HID device class.

A USB device stack is the software necessary to drive the USB device peripheral hardware on a microcontroller (MCU) or other device. Typically, USB peripheral hardware only supports the transaction level and below of the USB protocol. Enumeration and transfers are left to the firmware or software to implement. The Microchip PIC line of microcontrollers work exactly this way.

Join the Conversation


    1. I expect “easily” is meant only in the sense that the stack is well-designed for modular additions. Otherwise I agree more with what you said at the bottom of the main page:

      “USB is hard. There’s no getting around it. There’s a good chance if you’re reading this that USB is not the main focus of your project. USB is a means to an end, and your specialization is likely more related to the end than to the means.”

      So with that in mind, do you plan to release support for CDC and storage classes, which along with HID would cover most use cases for the average person?

      1. What I meant about “easily” was that it’s easy for a user of the library to make devices which are of no device class (ie: device classes of bDeviceClass = 0xff: Vendor Defined; see the USB specification). I did not mean, that it’s easy to implement device classes yourself.

        Also, what you said is true, the stack is well designed for modular addition of device classes. That means it’s doable and clean; it doesn’t doesn’t mean it’s easy.

        When you say CDC, HID, and MSC cover most use cases for the average person, I’d agree that in terms of actual units manufactured, that may be true, as most actual USB devices in existance are probably thumbdrives, keyboards, and mice. However, classless devices, combined with custom applications using libusb and winusb on the host side, are the right way to solve most of the problems that most engineers are facing. Most of the engineering work seems to be done making devices which are custom, and I’d say most of the device _types_ created are custom devices for custom applications. Many of these devices won’t see more than 100 units manufactured, but it’s at device type nonetheless. Custom devices shouldn’t be trying to shoehorn data though some device class which isn’t appropriate, which is what I see many, many people do with HID and CDC regularly.

        It’s surprised me quite a bit the questions I’ve gotten about CDC. It seems that _everyone_ wants it and I can’t figure out why. On Windows, if you make a CDC device, you force each _user_ to have to figure out and deal with which virtual COM port number to configure your host-side application for. Users touching the Device Manager in Windows sounds like a support nightmare to me, especially when so many projects would be better served by making devices which can use libusb and winusb, binding a driver automatically on windows 7+ (maybe Vista too) though the WinUSB descriptor, and having direct access to the device on all flavors of Linux/BSD/Mac (through libusb). PC-side applications can just open those devices directly by VID/PID without any user configuration. That’s the whole _point_ of USB.

        I think the reason we see so much CDC is that many hardware people (which many times become firmware people) are weak on PC-side software development and like to stick with what they know (the serial port). Of course not _all_ firmware engineers are like that, but I’ve met a lot who are exacly that way, and had this conversation before.

        Using CDC/ACM for something other than a serial port (or something that’s a lot like a serial port), is most of the time the wrong way to solve the problem. If your device is custom, don’t use a device class. Make a Vendor Defined device; make some endpoints; and send/receive data on them with libusb and/or winusb. That’s the _right_ way. It’s also the _easiest_ way.

        My unit_test example program shows an example of how to do this.

        That said, CDC is the next thing on my list. Mass Storage may be after that, but maybe EEM first. There is value in having a CDC class, even if people are mostly going to use it “wrong” :)

        A quick word about HID…. Until a year or so ago, winusb devices required an INF file to be created and then _installed_ by the user, which was really annoying (especially since Microsoft wants you to have it signed to avoid annoying popups for the user). They since introduced the WinUSB descriptor on Windows 8, and have now pushed it back into 7, which avoids the need for an INF file. For XP, and for WIn7 boxes without service packs and not connected to Windows update, HID remains a good method for getting data to and from a USB device without having to make a USB driver. (In my opinion! others disagree :) )

        Thanks for your comments :)

  1. To me HID, then MSC, then Custom device class and then CDC is important in that order.
    And CDC is much less important to me than MSC.

  2. CDC is much less important to me than HID, MSC and Custom.
    You can do everything with those three and what you can do with CDC you can do with Custom.
    If Custom is implemented and not CDC, you can work around that.
    Because of that, to me at least, it seems it’s better to first have custom and then work on CDC.

Leave a comment

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.