Sep 27, 2010

Can now communicate between gadgets and Windows

Three days for the investigation. I have googled a lot and most of the results are not reasonable. I have borrowed a book from the University Library, called

USB COMPLETE

Surprisingly, it is written by Jan Axelson which I have found his website useful before... (See the entry before, I have added his webpage for reference) Chapter 11, 12, 13 were all about the HID device.

Notes jot on these days (the weekends)
  1. Windows keeps polling the HID keyboard device. This is why we cannot use the generic Winodws API to help us writing report to the gadget device. Indeed, we can try creating a composite device, that is to combine both keyboard and an USB pipe (can be any HID device that not recognized as a system device). This way, windows handles all our key sent and we do have to make a customized program ourselves. To do this, we may have to modify linux device driver code located at: /linux-2.6.35/drivers/usb/gadget/ There are some codes stating the device descriptors. We found a file called autoepdescriptor. However, exploiting it will be not easy.
  2. Then we stick to a "joystick" approach. The joystick can also be recognized automatically by windows. Unfortunately, at first we enumerate the board as a joystick, the test program failed to send report to our device. We doubt that if this may be due to the absence of the OUT endpoint.
  3. On the day before mid-autumn festival, I take the board from MF and start investigating the possibility of opening the pipe. I crashed the file system and recovered it following some steps.
  4. Studying the possibility of adding some output report to the keyboard descriptor, but it fails as usual. One of the M$ document states that a way to make a "multi-functional" keyboard can be done by adding one more collection to the hid descriptor, but it is also not working. I doubt if the HID gadget device sticks to only 1 interrupt endpoint, which is by default 0x81 and that is why we cannot write report to the endpoint. Jan, the writer of the book, suggested that we can send report to the keyboard only by the way of writing feature report. I start trying to figure out why.
  5. Reading from the book as well as the pdf file from usb.org, I found that there can be only one way to send report to the interrupt IN endpoint. That is through having a control request. I also discovered that indeed the feature report is sent in the way of control transfer (p.328; p.321) when the OUT endpoint is absent. Then I start to enumerate the keyboard with the feature report descriptor. Certainly, it did not work.
  6. Googling from the web, I saw someone suggests that we can indeed make our customized, or called vendor defined HID. I saw some code from the net. One of them can successfully be implemented on our board. In the past when the HID report descriptor were written wrongly, windows would say "Cannot recognize the device". This time the device manager showed me that one INPUT DEVICE and HID COMPLIANT was installed. Since that device is enumerated with a feature report descriptor, I cannot find the way to send things to the board. Then I changed the report descriptor 0xB1 to 0x91 and start the test_hid program. Things can be sent from Windows to the board by calling winAPI (WriteFile) and the generic (Read on linux). However, it is hard to send things from the device to Windows since I mess up the format inside the report. I tried refer to the book to see what each field means and make my own vendor defined HID.
  7. I found important information from the book, ch12, starting from p.370.
    [Usage Page] The upper 16 bits is shared as a global item and the lower 16 bits is used to identify local item. (p.370)...
    That is why the keyboard is recognized as a keyboard through its report descriptor. I modified the Usage page and each Usage Item to see if the device is still working. It can be recognized by Windows, without any changes of other descriptor. Then I started the test program on hyper terminal (Though, we have to study further the format of the report). The typed code can be sent to windows and displayed on the C# program. Similarly, the report can be written to the board from Windows.
To do list -
  1. Understand how to write an appropriate report so that it can be written from linux to windows successfully.
  2. Create the Virtual Keyboard Application with C#. Ask MF if the programs should be installed as an apps on Windows or not.
  3. Start GUI side on friendlyarm.

Sep 23, 2010

setup

  1. dnw.exe connect USB to PC, driver is downloaded from friendlyArm.net
  2. hyperterminal and COMport
  3. build kernel, type make zImage
  4. open hyperterm, press k
  5. send file using dnw
  6. on hyperterm, press b
  7. attach again the USB
Create shareFolder in vBox sudo mount -t ubuntuTmp windowsTmp
http://www.cygnal.org/ubb/Forum9/HTML/001381.html Explanation on keyboard descriptor

Why do I receive "Access denied" when attempting to access my HID?

Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and HidD_GetFeature (if the device supports Feature reports).

Things to do after installing ubuntu

  1. Install nautilus-open-terminal "sudo apt-get install nautilus-open-terminal" ; Do have to restart terminal, do it by "nautilus -q". It does the trick.
  2. Install scite; A GUI notepad++ like editor in ubuntu
  3. Add workspace switcher to panel; Click on panel and select add to panel; Choose workspace switcher
  4. mount -t vboxsf FYP wintmp
ARM-Linux-gcc

1. 安装标准的C开发环境,由于Ubuntu安装默认是不安装的,所以需要先安装一下:

sudo apt-get install gcc g++ libgcc1 libg++ make gdb 2.安装交叉编译器下载交叉编译器cross的包,然后解压

sudo tar jxvf cross-2.95.3.tar.bz2 (根据版本不同解压文件不同),然后将解压后的文件都转移到/usr/local/arm下(若/usr/local/下没有arm文件夹,可先建一个):

sudo mv 2.95.3/ /usr/local/arm 3.把交叉编译器的路径加入到PATH

sudo vim /etc/bash.bashrc 在后面加入如下代码:

QUOTE: if [ -d /usr/local/arm/2.95.3 ] ; thenPATH=/usr/local/arm/2.95.3/bin:"${PATH}"fi 4.使新的环境变量生效

# source /etc/profile 5.检查是否将路径加入PATH的方法:

echo $PATH 如果显示的内容中有/usr/local/arm/2.95.3/bin,说明已经将交叉编译器的路径加入PATH自此,交叉编译环境安装完成。下面我们就来测试一个简单的例子。/*Hello.c*/#include

main(){printf("hello ubuntu!\n");}程序输好以后确认无误,保存。进入程序文件所在目录执行:

arm-linux-gcc hello.c –o hello arm -linux-gcc是第一次出现,有人可能会问这个哪里来的,不妨打开刚才安装的交叉编译工具目录 /usr/local/arm/2.95.3/bin/可以发现里面有一个arm-linux-gcc文件,这个就是针对arm的CPU 的gcc编译器了。以后用其它编译工具链式也可以通过这种方法看看其编译器是什么了。编译好了以后就可以下载到目标机进行测试了。当然也可以先在PC机上测试正误。用gcc hello.c –o hello就可以生成PC机上程序了,在运行./hello 就可以发现终端显示hello!字样。用arm-linux-gcc编译的程序在PC机上是不能运行的,运行后给出错误报告:无法执行二进制文件。说明经过交叉编译环境编译出的文件是硬件可执行的二进制代码文件。





Sep 20, 2010

Going to do

To do list

  1. Develop the HID descriptor as a force feedback device; Or to ensure there at least one endpoint.
  2. Try sending force feedback report to the real joystick, making it vibrate.


1. What is composite device
Composite device is defined in the USB spec as follows (usb_20.pdf 5.2.3),
"A device that has multiple interfaces controlled independently of each other is referred to as a composite device."

Using composite device, multiple functions are combined into a single device.
Ex.
- Keyboard + Mouse
- Video + USB Hard disk
- I/O device (HID + USB_bulk)

Another advantage of composite device is that it eases the device driver development.
OS assigns a separate device driver to each Interface of the composite device as follows. Therefore, a dedicated monolithic driver is not required for newly designed device; you can realize it using existing drivers.

  +----------------------------+      +----------------------
| Composite Device | | Host PC
| | |
| Function 0 -- Interface 0 --------- Device driver A <--->
| | |
| Function 1 -- Interface 1 --------- Device driver B <--->
+----------------------------+ +-----------------------

When OS has some required drivers as built-in, they are available for the composite device. These OS built-in device drivers are called as USB class driver.
"Approved Class Specification Documents" from USB.org
http://www.usb.org/developers/devclass_docs#approved

Windows have these built-in class drivers.
"USB FAQ: Introductory Level - USB Class Drivers" from MS WHDC
http://www.microsoft.com/whdc/system/bus/usb/USBFAQ_intro.mspx

Please note, available drivers for a composite device are not limited only to class drivers. Any driver can be applied, as long as it doesn't require a device class (class defined in device descriptor). For example, SiLabs USB_INT and USB_bulk drivers are also applicable for composite devices.


src: http://www.cygnal.org/ubb/Forum9/HTML/001050.html

Sep 19, 2010

Mid September

We have stuck in the process of how windows sends message to HID device. On this stage, we successfully enumerate the mini2440 as a HID keyboard to Windows. The thing left was sending the right HID report to the device.

It seems that windows does not allow us to send any HID report to the keyboard, any HID device other than keyboard or mouse, it will be fine. There are many sites talking about this. winAPI provides two basic function for developers to send the HID reports to the target USB HID device. They are called, (quoted from MSDN, http://msdn.microsoft.com/en-us/library/ff542417(v=VS.85).aspx)

  1. ReadFile(...), WriteFile(...)
  2. HID_setXXX(...), HID_getXXX(...)
They are quoted without test, hopefully tomorrow we will test it on mini2440. Several useful references were quoted. http://courses.cs.tau.ac.il/embedded/projects/fall2009/HID-Host/ This site shows how they use win32 API to make a customized device.

For generic USB HID concept, a PDF file is downloaded and stored in the vBox. From this point of view, we knew that the interface is a collection of endpoints. The endpoints work as accepting or sending control messages to or from the host. Tommorow we will try making one more interface or one endpoint as a port for win32 to send the command.

Quoted from offical Linux Gadget HID driver:

At this writing there are several public "gadget drivers", each implementing a single common USB function so it will work with virtually any USB peripheral controller. (Drivers for composite gadgets, or for audio/video drivers requiring isochronous transfers, would not be able to work on at least some controller hardware. The gadget API does support such drivers.) You should plan on testing these in conjunction with the controller driver and system board you'll be using.

  • Gadget Zero ... is essential for controller driver testing. It provides two configurations: one for bulk traffic source/sink, and another for bulk traffic loopback. On the device side it helps verify that the driver stack pass USB-IF and other tests (needed for at least USB branding). On the host side it helps test the USB stack, such as the Linux-USB HCDs and usbcore. If built as a module, start it by modprobe g_zero; no other initialization is needed. (Use the autoresume=N module parameter to make it try triggering remote wakeup N seconds after it's suspended.)
  • ………………………………………..
  • GadgetFS ... since not every developer wants to program in the kernel, or rely specifically on the Linux kernel APIs, a user mode API is available. An example user mode driver is usb.c. (It also needs usbstring.c and usbstring.h.) Notice how the device is initialized by writing its configuration and device descriptors to a file (such as /dev/gadget/$CHIP), and how the endpoints are initialized in similar ways (writing descriptors to /dev/gadget/$ENDPOINT). After initializing them, just read or write to the files to transfer data; or to handle events including control requests to retrieve string descriptors, configure alternate settings, and implement class or vendor requests. On Linux 2.6 AIO (Async I/O) support is available, helping user mode drivers avoid i/o latencies and letting them stream data as quickly as in-kernel drivers can stream it. Note that user mode gadget drivers do not necesarily need to be licensed according to the GPL.
Quoted from M$
It isn't possible to open a handle to a mouse or keyboard collection because the system input thread has opened these devices exclusively. Furthermore, these devices don't appear in the enumeration of the HID interface GUID. (HIDCLASS doesn't advertise the HID interface GUID for keyboard and mice so as to prevent some random user-mode program from opening those devices before the system's own raw input thread can do so.) It does you no good to register a private interface GUID for your device because HIDCLASS will fail an IRP_MJ_CREATE directed to the main device object. Consequently, there is no way to communicate with a custom mouse or keyboard driver using standard methods.


Useful website:

Sep 9, 2010

This is the first week of September.
Finished stuffs:
[Pretend to be the HID device on the ARM9 board] Part done by Ka Chun
  1. Flash in the latest kernal version, 2.6.3X (This was done by Ka Chun); Reason: To use usbgadget. The old kernal does not support feature of pretending the usb slave device. We cannot use the port provided by mini2440.
  2. Play tricks on the kernal code. This is beacause not all ports can be used from the new kernal code. We have to edit it, enable features so that the correct hardware can be activated.
  3. The touch screen was once not working. Ka Chun fixed this
[Windows platform]
  1. Successfully hook the event to the application. Once the correct event is captured, we can perform winAPI to find out the handle of the window that throw us the event. HWND is useful as it acts as an unique identifier to provide rich information such as process ID, text on the window for us to analysis.
  2. Indeed, the old method we have used is Polling but it wasted CPU resourses so much. To get rid of it, we once considered making use of just a typical single thread. I have written a simple program using hook with Cplusplus. However, the program terminated soon. That is why we have to turn in to GUI program. The GUI thread is supposed to run infinitely until it is killed by user.
  3. Since the C sharp is used for GUI program. (The reason for not using C++ is that GUI C# provide more fancy interface for designing. C# provides more objects for GUI design.) The other issue will be the driver program, which supposed to be written in C language (To help communicating with low level device). Originally, Libusb-win32 was introduced as an API to send and read data from the USB device. After some searching from the NET, we found that a further improved version of Libusb is provided called LibUSBDotNet. .Net stands for C# GUI class.
[Things to be Developed soon]
  1. Make sure bytes can be sent to the mini2440 and read from mini2440 correctly.
  2. Study the QT extended on mini2440 (Time consuming)
  3. Study the source code of the test program of the HID device.