rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Introducing USPi - A bare metal USB driver written in C

Wed Nov 26, 2014 11:49 am

After some weeks of porting and development I want to introduce the USPi library which provides a light implementation of an USB driver stack useable from bare metal C applications (e.g. self-made OS kernels, bare metal games). It was tested on Raspberry Pi Model A+, B and B+ and should run on all existing models.

Currently the USPi library supports the following USB devices:
  • Keyboard
  • Mouse
  • GamePad/Joystick
  • Mass storage device (USB flash stick or hard disk)
  • Ethernet controller (on Model B(+) only)
  • Standard hub (max. 8 ports)
USPi requires some services like memory allocation, interrupt and timer support which should be available in an OS kernel or game environment. It is MMU-ready and is able to run from virtual memory.

The USPi library was suggested by macca who has also implemented the GamePad support and maintains it. Many thanks to him!

USPi release 0.10 is available on GitHub:

https://github.com/rsta2/uspi/releases/tag/Release_0.10

Feedback is welcome!

Rene

User avatar
ShiftPlusOne
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 6460
Joined: Fri Jul 29, 2011 5:36 pm

Re: Introducing USPi - A bare metal USB driver written in C

Wed Nov 26, 2014 12:24 pm

That looks like it took a while and killed some brain cells. Impressive

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Wed Nov 26, 2014 1:44 pm

ShiftPlusOne wrote:That looks like it took a while and killed some brain cells. Impressive
Yes, it took some time. The main work was done in May/June last year. It was written in C++ first and than ported to C. I have to say that I could rely on the work of others done before (e.g. the Linux DWC OTG driver and CSUD). I got a lot information from it. So it was just work and shouldn't be impressive. But we (macca and me) would be happy if it's useful for somebody and if we would hear from it. Thank you!

BTW because some time is gone since then we all lost some brain cells. It happens all the time. ;)

User avatar
experix
Posts: 204
Joined: Mon Nov 10, 2014 7:39 pm
Location: Coquille OR

Re: Introducing USPi - A bare metal USB driver written in C

Wed Nov 26, 2014 10:31 pm

Is it specialized for RPi, or more generally useful?
Is it optimized for RPi, making it a better choice than libusbx or something else?
Does it provide basic transfer operations like libusbx does, or is is more high-level?

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 7:48 am

experix wrote:Is it specialized for RPi, or more generally useful?
Is it optimized for RPi, making it a better choice than libusbx or something else?
Does it provide basic transfer operations like libusbx does, or is is more high-level?
USPi is a bare metal library especially for the Raspberry Pi. Unlike libusb(x) it does not need Linux.

It provides high-level access to the devices listed in my first posting. USB is mostly hidden from the application.

fsantanna
Posts: 2
Joined: Sun Aug 04, 2013 11:50 pm

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 10:54 am

rst wrote: Currently the USPi library supports the following USB devices:
  • Keyboard
  • Mouse
  • GamePad/Joystick
  • Mass storage device (USB flash stick or hard disk)
  • Ethernet controller (on Model B(+) only)
  • Standard hub (max. 8 ports)
Looks impressive!
Do you have test applications for any of these devices?
(I have to admit that I don't know where to start.)

Thanks,
Francisco

dpotop
Posts: 108
Joined: Mon Nov 24, 2014 2:14 pm

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 1:33 pm

Hello,

First of all: nice work !

Second: I have a question: While reading uspios.h I saw that you require
a 100Hz timer. Is this enough to handle Ethernet ?

Yours,
Dumitru
dpotop

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 1:44 pm

fsantanna wrote:Looks impressive!
Do you have test applications for any of these devices?
(I have to admit that I don't know where to start.)
Thanks! First I have to say that for the mass storage devices and the Ethernet controller USPi provides the basic device access on sector or frame level only. You need a separate file system driver or network stack to use it. Once you have an USB host controller driver it doesn't take so much time to write a function driver for a specific device. That's why it can support these devices.

Unfortunately there are currently no test applications to be included in the release. I have tested it with Circle (also recently mentioned in this forum) which provides a C++ environment but also has its own USB driver stack. So it makes not much sense to use it further with USPi.

To start you should first develop some basic functions (frame buffer support, memory allocation, interrupt and timer support). The required functions are declared in the file include/uspios.h. That takes time but it may be fun to get it all running.

I read more then once in this forum that there are ready self-made OS kernels out there which should get USB support. I think this is where USPi could be used well.

Perhaps we will think about making the start easier with it but this will take time and it is not clear what will be the result.

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 2:05 pm

dpotop wrote:First of all: nice work !
Thanks!
Second: I have a question: While reading uspios.h I saw that you require
a 100Hz timer. Is this enough to handle Ethernet ?
This definition can be changed. In fact the timer resolution is set by the environment not by USPi. If your timer runs at 1000Hz you have to set HZ to 1000. USPi needs this value to know the delay handed over to StartKernelTimer() not more.

As I mentioned in my previous answer there is no networking stack included in USPi. I have developed a small TCP/IP stack on my own and it worked. It wasn't very fast but I think that's not easy to achieve. As far as I know TCP/IP uses three timers (retransmission, time wait and user timeout). Its timeout lies in seconds and maybe tenth of a second. So that should be enough. But that's all done outside USPi. USPi uses the timer mainly for interrupt transfers to HID devices (e.g. keyboard).

But there are for sure other people out there who know much more about TCP/IP then me.

macca
Posts: 195
Joined: Tue Oct 16, 2012 9:14 am

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 2:06 pm

fsantanna wrote:Do you have test applications for any of these devices?
Sample applications for keyboard and joysticks can be found on my repository:

https://github.com/maccasoft/raspberry-pi

template/main.c Implements the initialization and raw keyboard handler
SDL2 Implements both keyboard and joystick interfaces, it is a bit more complicated to locate the actual code but a search for 'USPi' should find everything.

For a ready to run application you can download my Abbaye des Morts game release, it supports only the keyboard but the source supports both keyboard and a game controller through SDL2 (just need to recompile and upload a new release, once I have a fixed a minor glitch in the game).

I don't have implementations for other devices yet, but the API is really straightforward.

dpotop
Posts: 108
Joined: Mon Nov 24, 2014 2:14 pm

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 4:28 pm

[
Second: I have a question: While reading uspios.h I saw that you require
a 100Hz timer. Is this enough to handle Ethernet ?
This definition can be changed. In fact the timer resolution is set by the environment not by USPi. If your timer runs at 1000Hz you have to set HZ to 1000. USPi needs this value to know the delay handed over to StartKernelTimer() not more.[/quote]

Ok, so if I understand it right, it's not tested for the Ethernet part.
No problem, but good to know.

Thanks a lot,
Dumitru
dpotop

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 7:12 pm

dpotop wrote:Ok, so if I understand it right, it's not tested for the Ethernet part.
Ethernet has been tested on the receive path with USPi. The dedicated transmit path is very small and has been tested in my self-made OS kernel with the mentioned TCP/IP stack. This system was written in C++. USPi was mechanically ported from its USB part. In fact it is possible that we get some problems when a networking stack is tested on it. But so far such stack does not exist.

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 7:26 pm

Should be pretty easy to port either uIP or LWIP.

dpotop
Posts: 108
Joined: Mon Nov 24, 2014 2:14 pm

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 7:33 pm

Ok, I understand, thank you.
My interest is in directly using Ethernet. I guess 100Hz will be enough if the frequence of
sending frames is small enough. Then, I'll just have to test in order to find the good frequency for the throughput I need.
It's good to know that it was tested.

Yours,
Dumitru
dpotop

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Thu Nov 27, 2014 8:24 pm

tufty wrote:Should be pretty easy to port either uIP or LWIP.
I have read something about it. Looks interesting.

ali8
Posts: 11
Joined: Mon Jul 22, 2013 11:21 pm

Re: Introducing USPi - A bare metal USB driver written in C

Thu Dec 25, 2014 3:35 pm

Thanks for the great work--appreciated. I wonder how easy it would be to use your code with a usb camera?

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Fri Dec 26, 2014 10:04 am

ali8 wrote:Thanks for the great work--appreciated. I wonder how easy it would be to use your code with a usb camera?
Thank you! To support a new device class there are some requirements to be fulfilled:
  • There must be a USB device class specification which is public available.
  • This specification must be used by a sufficient amount of devices of that class.
  • The specification should be small enough to be implemented.
  • The specification should only use features which are supported by the USB base driver.
  • Such device must be available for testing.
While there is a Audio/Video class specification available I'm not sure if this is used by many USB camera devices. It seems many USB cameras come with their own driver and do not use a class driver. There are many different modes for USB cameras defined by this specification. Although there is a bulk transport defined in this specification which is supported by USPi I suppose most cameras use an isochronous transfer which is not supported by USPi so far.

Taking this all together I think it is unfortunately not easy to support USB cameras. But I am not very familiar with this topic.

GentlemanEngineer
Posts: 3
Joined: Fri Jun 21, 2013 5:25 am

Re: Introducing USPi - A bare metal USB driver written in C

Sun Jan 04, 2015 6:44 am

rst wrote:
dpotop wrote:Ok, so if I understand it right, it's not tested for the Ethernet part.
Ethernet has been tested on the receive path with USPi. The dedicated transmit path is very small and has been tested in my self-made OS kernel with the mentioned TCP/IP stack. This system was written in C++. USPi was mechanically ported from its USB part. In fact it is possible that we get some problems when a networking stack is tested on it. But so far such stack does not exist.
I am currently enacting such an attempt to port to the FreeRTOS+TCP Stack. From an initial view, it would appear that you have placed an effort not insignificant into said library.

I have made note that there exists not functionality for the creation of an event handler for the receiving of data (as exists for the keyboard and storage handling). Would there exist a particular reasoning why this is absent?

You stated that this Ethernet functionality was tested. Was this accomplished via polling for received frames?

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Sun Jan 04, 2015 10:41 am

GentlemanEngineer wrote:I have made note that there exists not functionality for the creation of an event handler for the receiving of data (as exists for the keyboard and storage handling). Would there exist a particular reasoning why this is absent?
On the USB side the Ethernet NIC receiver has to be polled via a bulk endpoint anyway. When USPiReceiveFrame() gets called this will be done. I could have implemented some polling scheme in the USPi library but I decided to let this be done by the user of the library.
You stated that this Ethernet functionality was tested. Was this accomplished via polling for received frames?
Yes.

mimi123
Posts: 583
Joined: Thu Aug 22, 2013 3:32 pm

Re: Introducing USPi - A bare metal USB driver written in C

Tue Feb 17, 2015 11:58 am

Can you release your small TCP/IP stack?

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Tue Feb 17, 2015 2:44 pm

mimi123 wrote:Can you release your small TCP/IP stack?
Thanks for your interest! But currently this is difficult because it will not build. It was written in C++ for my hobby OS and needs system tasks. I thought about providing system tasks in Circle (see: http://www.raspberrypi.org/forums/viewt ... 72&t=90130) but haven't done this because it changes the programming model of Circle and my task implementation is not very reliable. It is difficult to debug.

Furthermore this TCP/IP stack has some known issues. Somebody could tell it is dangerous to release it because it may generate some "illegal Internet traffic".

If you want to have a look at it anyway please send me a personal message with your Email address. I will send you a ZIP file than.

User avatar
DavidS
Posts: 4642
Joined: Thu Dec 15, 2011 6:39 am
Location: USA

Re: Introducing USPi - A bare metal USB driver written in C

Tue Feb 17, 2015 5:46 pm

Having just taken a quick look through the source I am impressed. Should not be to difficult to rewrite in assembly, making it even more usable.

Very nice work. USB is a nightmare, one that I would not want to revisit from the ground up. Thank you very much for putting in this effort, and giving us a bare metal and OS-Dev USB Stack that is reasonably complete.

Now I can get serious with my OS development on the RPi again. I had given it up do to having already been through the USB ringer, you have provided the perfect tool.

Thank you again.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers.

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Tue Feb 17, 2015 8:14 pm

DavidS wrote:Having just taken a quick look through the source I am impressed. Should not be to difficult to rewrite in assembly, making it even more usable.

Very nice work. USB is a nightmare, one that I would not want to revisit from the ground up. Thank you very much for putting in this effort, and giving us a bare metal and OS-Dev USB Stack that is reasonably complete.

Now I can get serious with my OS development on the RPi again. I had given it up do to having already been through the USB ringer, you have provided the perfect tool.

Thank you again.
Thank you very much for your words. I am happy when USPi is useful for you. Please note that the gamepad driver was written by macca. Good luck with your OS development!

Avoncliff
Posts: 35
Joined: Fri Dec 09, 2011 5:24 pm

Re: Introducing USPi - A bare metal USB driver written in C

Thu Feb 19, 2015 10:17 pm

I am also very impressed with your work, thanks.
Have you done any work on the speed. I am finding it slows down the code I am linking it to dramatically.
I can look at rewriting critical bits in assembler but the slow down looks larger than this.
I have no understanding of the USB stack but is it likely to be hogging the processor?
So far I am only using the keyboard and framebuffer, is it possible other parts of your library are using processor time?
Any pointers for how to debug this?
Thanks again
David

rst
Posts: 554
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Introducing USPi - A bare metal USB driver written in C

Fri Feb 20, 2015 10:43 am

Avoncliff wrote:I am also very impressed with your work, thanks.
Thank you.
Have you done any work on the speed. I am finding it slows down the code I am linking it to dramatically.
USPi is not optimized for performance. I have noted this in the main README file. There is an issue that the continous interrupt transfers from the keyboard may drop the performance (especially if the MMU and caches are not enabled) remarkable. This is caused by the implementation of the frame scheduler. It's not easy to change this.

Return to “Bare metal, Assembly language”