Author Topic: Anyone know how to write a basic USB stack?  (Read 11427 times)

0 Members and 1 Guest are viewing this topic.

Online NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: Anyone know how to write a basic USB stack?
« Reply #50 on: October 20, 2017, 07:20:31 pm »
I get the same error with your descriptors. Maybe Linux need some other method to feed the report descriptor?

It is all standard on all platform. HID descriptor is passed two ways - in between interface descriptors and EP descriptors within device descriptor and also in response to a separate request. Report descriptor is passed in response to a special  request. Read the specs if in doubt.

You have the source code of your lib and the Linux source code. Have you looked at these? Is Linux requesting something your lib doesn't give? Very easy to figure out what's going on if you just look. No reason to guess.
 

Offline technixTopic starter

  • Super Contributor
  • ***
  • Posts: 3507
  • Country: cn
  • From Shanghai With Love
    • My Untitled Blog
Re: Anyone know how to write a basic USB stack?
« Reply #51 on: October 20, 2017, 07:59:37 pm »
I get the same error with your descriptors. Maybe Linux need some other method to feed the report descriptor?

It is all standard on all platform. HID descriptor is passed two ways - in between interface descriptors and EP descriptors within device descriptor and also in response to a separate request. Report descriptor is passed in response to a special  request. Read the specs if in doubt.

You have the source code of your lib and the Linux source code. Have you looked at these? Is Linux requesting something your lib doesn't give? Very easy to figure out what's going on if you just look. No reason to guess.
I am also poking at it on Windows (Thanks god there is VMware and the super versatile and tolerating USB stack of macOS) and it seem to me that the USB stack is not handling reenumeration properly. Is there any pointer on what is happening when a USB device is being reenumerated?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Anyone know how to write a basic USB stack?
« Reply #52 on: October 20, 2017, 08:04:56 pm »
Your USB device seems to be enumerating correctly  according to the Linux output. HID part is having problems.

There is no fixed enumeration process, host will request descriptors in any order it feels like (starting with device descriptor). Just log all requests and see if you handle all of them.

Specifically HID descriptor is requested with a Get Descriptor command as a standard interface descriptor. And your stack should send the response over the control endpoint.
Alex
 

Online NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: Anyone know how to write a basic USB stack?
« Reply #53 on: October 20, 2017, 08:13:36 pm »
Is there any pointer on what is happening when a USB device is being reenumerated?

http://www.usb.org/developers/docs/usb20_docs/usb_20_100617.zip

You need a file called usb_20.pdf

or in popular form:

http://www.usbmadesimple.co.uk/ums_4.htm
 

Offline technixTopic starter

  • Super Contributor
  • ***
  • Posts: 3507
  • Country: cn
  • From Shanghai With Love
    • My Untitled Blog
Re: Anyone know how to write a basic USB stack?
« Reply #54 on: October 20, 2017, 08:47:14 pm »
I get HID Vendor Class Device enumeration. Source code here: https://github.com/SushiBits/LightSwitchUSB-Firmware

Now I need to fill in the actual code to turn HID reports on the interrupt endpoints into actions. Since the USB stack is entirely interrupt driven I think I have the main() loop all to this task. Or maybe I should run a timer to perform timed data synchronizes and leave main() be the loop of low power mode?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Anyone know how to write a basic USB stack?
« Reply #55 on: October 20, 2017, 08:52:35 pm »
From the quick look at the code, you just call usbd_ep_write() and the rest will happen automatically. Host will send an IN request (when software asks for it), and USB controller will send the data.
Alex
 

Offline technixTopic starter

  • Super Contributor
  • ***
  • Posts: 3507
  • Country: cn
  • From Shanghai With Love
    • My Untitled Blog
Re: Anyone know how to write a basic USB stack?
« Reply #56 on: October 21, 2017, 09:44:02 pm »
It worked with macOS now. The host app is built with libhidapi, and somehow it is likely I can submit it to the Mac App Store after a makeover and some polishing. I am going to take a nap and start writing code for Linux and Windows. (My VB.net is rusty now, not having touched it for years...)
 

Offline funkathustra

  • Regular Contributor
  • *
  • Posts: 150
  • Country: us
Re: Anyone know how to write a basic USB stack?
« Reply #57 on: October 21, 2017, 09:50:46 pm »
It worked with macOS now. The host app is built with libhidapi, and somehow it is likely I can submit it to the Mac App Store after a makeover and some polishing.
It's nice that HID API actually calls native IOKit stuff, instead of relying on LibUSB.

I am going to take a nap and start writing code for Linux and Windows. (My VB.net is rusty now, not having touched it for years...)
Out of curiosity, why not C#? You're obviously a capable C/C++ programmer.
 

Offline technixTopic starter

  • Super Contributor
  • ***
  • Posts: 3507
  • Country: cn
  • From Shanghai With Love
    • My Untitled Blog
Re: Anyone know how to write a basic USB stack?
« Reply #58 on: October 22, 2017, 05:47:08 am »
It worked with macOS now. The host app is built with libhidapi, and somehow it is likely I can submit it to the Mac App Store after a makeover and some polishing.
It's nice that HID API actually calls native IOKit stuff, instead of relying on LibUSB.
libhidapi have four backends now: native Windows, native macOS (IOKit), libusb on Linux, and hidraw on Linux.
I am going to take a nap and start writing code for Linux and Windows. (My VB.net is rusty now, not having touched it for years...)
Out of curiosity, why not C#? You're obviously a capable C/C++ programmer.
I had a history with VB.net: back when I was mainly developing for Windows I was using that language over C#.
 

Offline josip

  • Regular Contributor
  • *
  • Posts: 151
  • Country: hr
Re: Anyone know how to write a basic USB stack?
« Reply #59 on: October 26, 2017, 08:28:44 pm »
IMHO, it's the best way to learn how USB works.

Exactly.

I had a plenty of free time, and didn't know anything about USB. Tried with some books, but gave up (what the hell is endpoint  :-//).

Started assembler coding, by analyzing TI MSP430 open source USB stack (written in C), and soon all become clear. Found (I guess) all undocumented staff (related to USB module), and at the end, it (CDC) was fast (1MByte/s, unlimited buffer) small (almost 1 KByte) and lite for CPU. Later, I also made CDC bootloader, with (software) AES, and interface commands that fit in 2 Kbytes.

Now, there is no more plenty of free time, but there is no way that I will use any prepared USB stack for different MCU family.

 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Anyone know how to write a basic USB stack?
« Reply #60 on: October 27, 2017, 06:39:32 am »
Quote
and at the end, it was fast small, and lite for CPU
"and now I know enough that vendors' USB stacks all look even worse than they used to!"

Serious question: have you written another USB stack for a different chip?   If not, how much do you think the understanding you've gained would help, writing for the 2nd chip?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Anyone know how to write a basic USB stack?
« Reply #61 on: October 27, 2017, 06:42:37 am »
Serious question: have you written another USB stack for a different chip?   If not, how much do you think the understanding you've gained would help, writing for the 2nd chip?
I did port mine across multiple different Atmel MCUs (with different USB controllers). I can say, it helped a lot.

Now instead of asking a question "where do I get a sample code for this controller, because USB is hard", I ask questions like "how do I do X on this controller", and I know exact set of Xs that are required to make USB work. It is much easier this way.

And my simple "stack" is structured in a way that you only need to re-implement one file to do the porting, so you pretty much have a minimal list of functions you need to make a USB stack work.
« Last Edit: October 27, 2017, 06:45:16 am by ataradov »
Alex
 

Offline josip

  • Regular Contributor
  • *
  • Posts: 151
  • Country: hr
Re: Anyone know how to write a basic USB stack?
« Reply #62 on: October 29, 2017, 10:15:52 pm »
"and now I know enough that vendors' USB stacks all look even worse than they used to!"

Vendors just give you example, how things can be done, and that's it. There are 3 options for user. If there is no performance / size / bug issue, original stack can be used as it is. Original stack can be optimized (MSP430, for example, http://www.indigresso.com/_blog/?p=33), or written from zero (as I did).
 
Serious question: have you written another USB stack for a different chip?   If not, how much do you think the understanding you've gained would help, writing for the 2nd chip?

I agree with Alex. All MSP430 devices have identical USB module, and my USB stack will work with all. Till today I didn't write USB stack for another family, but I have plan for the next year, to start with Cortex-M0+ (again, from zero, in assembler). And I don't expect significant problems. From my point of view, it is little more complicated, than writing code for UART on different families. If I be able to find some (undocumented) tricks (related to USB hardware module) to boost it up, like with MSP430, is another topic.
 

Online NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: Anyone know how to write a basic USB stack?
« Reply #63 on: October 30, 2017, 03:53:39 am »
Serious question: have you written another USB stack for a different chip?   If not, how much do you think the understanding you've gained would help, writing for the 2nd chip?

It took me about 2 weeks to get working USB on PIC16F1454. Most of that time was studying not-so-clear USB docs. Fortunately, the PIC's module was documented very well, so there was no problem there. If I needed to do it for other chip (and most likely I will have to do it soon for PIC32MZ, which is generally undocumented), I'd estimate 2, may be 3 days.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Anyone know how to write a basic USB stack?
« Reply #64 on: October 30, 2017, 04:11:34 am »
Quote
is there any guide on writing a simple USB stack from the ground up

Getting away from particular implementations, my understanding of USB Device in General goes something like this:

  • Data is exchanged in "messages."  In general, messages are queued by the device and sent when polled by the hosts (at about 1kHz, for low and full speed.)
  • Most USB device will have hardware that handles messages "per endpoint", and support multiple endpoints (number of endpoints varies.  Amount of buffering (# messages) per endpoint varies.  Max size of messages varies.)
  • Endpoint 0 is the "control" endpoint and is magic and required.  When a device comes up, it communicates on EP0 about what it is, what other endpoints exist, and so on ("enumeration.")  EP0 is bidirectional (all other endpoints are unidirectional.)
  • A lot of what passes for a "USB driver" is setup of the initial enumeration, going from some human-readable description of the device to the rather verbose message formats and initial communications.  Once everything is set up, a USB device is pretty similar to any other time-sliced message-based  flow-controlled communications.
  • Which means that things like performance and latency depend pretty heavily on buffering strategies, particularly when going to/from byte-stream sources (CDC.)  You get so many messages-per-second, and high throughput requires putting as much data as possible in each message, as well as making sure that data that's been sent from user APIs is ready to be sent as a USB message when the host requests it.
  • (this essentially skips whatever you'd need for really high-speed and superspeed comm.  Yeah, usb1.x!)
An corrections on the basic outline would be appreciated...
 
The following users thanked this post: splin

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Anyone know how to write a basic USB stack?
« Reply #65 on: October 30, 2017, 04:18:15 am »
Your biggest problem would be figuring when to send STALL, when to send Zero Length Packets, when to send nothing, and all that higher level stuff.

I just recently updated my VCP implementation, since it had very incorrect implementation for the control transfers (they use one more level of abstraction). I never needed them before, so it was not a huge deal, but I needed them for another projects, and discovered a problem. This may be an argument for using "professional" stacks, but it took a couple hours to fix, and I learned more about USB in the process, so time well spend, really.

With USB everything related to control endpoint is very messed up. Regular endpoints are very easy.

Supporting specific classes adds a whole new level of problems, especially given pretty poor USB documentation. But it is solvable as well.
« Last Edit: October 30, 2017, 04:24:01 am by ataradov »
Alex
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf