posts - 20 , comments - 57 , trackbacks - 0

Intel USB Host Controller

When using Intel hardware for your embedded platform, you most likely will include the UHCI (1.1) and/or EHCI (2.0) USB drivers in your Windows CE image. Already some time ago I noticed that when unplugging a USB device (keyboard, mouse, memory stick …) and inserting it again, the UI stalled for a moment while the USB device was inserted again. I also noticed on a particular hardware platform where 2 CAN channels were used, that the CAN communication failed with timeouts of a few 100milliseconds. This happens with the sample USB Windows CE 6/7/8 drivers shipped by Microsoft.

I already knew that the UHCI and EHCI USB driver code had some bugs, but I patched them already long ago with the fixes you can obtain from BSquare or Adeneo. Still no luck.

After investigation (together with my work colleague Kevin) it turned out that the UHCI driver was responsible for that behaviour. The problem is located in HCD\UHCD\chw.cpp, more precisely in the function CHW::ResumeHostController(). This function implements a 20msec delay by running a for-loop 600000 times. Ugh! As this code runs at a pretty high thread priority (around (driver) priority level 100), it blocks any lower thread priority code running at the same time. The code intended to pause for 20msec, but in reality it did so for ±300msec. Killing on a real-time OS!

The CAN driver IST thread ran at a lower priority, but it buffers the CAN messages properly in a FIFO. No CAN messages were lost, but the application (actually the thread) that processed these CAN message had a timeout built in (between transmitting command and waiting for response) and as a result the application failed.

Windows CE UI threads run typically at the default thread priority level 251, it is obvious that the UI stalled during this for-loop period.

Here is the code snippet with the problem

VOID CHW::ResumeHostController()
{
        
// I need 20 ms delay here 30(30ns)*1000*20
for (DWORD dwIndex =0; dwIndex<30*1000*20; dwIndex++)
Read_USBCMD();
}

And the obvious fix

VOID CHW::ResumeHostController()
{
// I need 20 ms delay here 30(30ns)*1000*20
Sleep(20);
}

 

Print | posted on Monday, December 30, 2013 12:40 PM | Filed Under [ Windows CE Windows Embedded Compact USB UHCI EHCI ]

Feedback

Gravatar

# re: Intel USB Host Controller

Apparently, using Sleep() in a Power Handler is a definite no as it can cause page faults. See http://developce.blogspot.co.uk/2009/05/dont-sleep-in-power-handler.html
1/28/2015 3:45 PM | Richard Lewis
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: