Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - How to use a USB barcode reader as an HID device: (5 Items)
   
How to use a USB barcode reader as an HID device  
We have a minimal QNX installation on an embedded device.  Very early in the startup, I redirect all console I/O to a 
serial port.  Our application uses advanced graphics to write to the LCD screen, but all processes use the serial port 
for stdio for debug purposes.

I was recently asked to try to interface a USB barcode reader to our unit.  This reader acts like a standard PC USB 
keyboard.  Reading a barcode spits out a sequence of keystrokes.  It works with any Windows PC and our laptop with a 
full QNX with Photon installation.

To try this out on our device, I started io-hid and devc-con-hid:

# io-hid -d usb
# devc-con-hid

I can plug the reader into the USB port and scan barcodes without error.  This tells me that someone is properly 
consuming the keystrokes.  I then wrote a simple program to try and read the characters.  I developed and ran it under 
QNX Momentics Debugger.

It opens "/dev/con1" without error.

It calls "select" to wait for activity.  It pends until I read a barcode and indicates that there is something to read 
on the file descriptor.

I call ioctl FIONREAD to read the number of bytes available.  This call returns with EFAULT error.

I try reading one byte with "read" and this never returns.

What am I doing wrong?
Re: How to use a USB barcode reader as an HID device  
I found my original problem of why read is blocking.  The console driver is running in editing mode and is awaiting for 
a carriage return to unblock the read.  The barcode readier is issuing a string of characters followed by a tab 
character.  I can not change this behavior.  I started the console driver with the '-E' argument and my simple test 
program now works:

devc-con-hid -E

I put the code in our application, and now it only reads a few characters before the reader indicates an error.  The 
application has many threads that run at higher priority that the rest of the system.  The barcode thread is running at 
priority 12. most other threads are running at a higher priority, some as high as 25.  I can only guess that some kind 
of timeout or overrun is occurring.  

Any ideas for fixing this?
Re: How to use a USB barcode reader as an HID device  
In your program which opens /dev/con1, try setting the device to "raw".  You can use "stty -a </dev/con1" to verify all 
settings.

In particular, make sure you see -icanon.
Re: How to use a USB barcode reader as an HID device  
I have verified that the console is in raw mode.  I found the setup program for the barcode reader that lets me 
configure some parameters.  I programmed it to issue a carriage return after a read, and ran devc-con-hid in edit mode. 
 This didn't help.

I found that if I boosted the priority of the usbdi_event_handler(6) task in io-hid to 15, the problem went away.  This 
priority is above the UI, logging, and Ethernet tasks and even with our serial communications task.

I could boost this task's priority in our application when it starts, but I only want to do this as a last resort.  Is 
there any native way to boost this task in io-hid?

I would be satisfied by a custom version of io-hid, but access to the source code is nearly impossible now.
Re: How to use a USB barcode reader as an HID device  
I used renice to boost the priority of io-hid until its receive thread went from 21 to 25.  This seems to have fixed the
 problem.  I believe the fault lies in the io-hid or devh-usb.so drivers.  If I power up the reader without USB 
communications, when reading a barcode, the reader will fault after 3 seconds.  The problem I'm seeing is that the fault
 is issued immediately on reading the code.

RS-232 barcode readers do not have this problem as the UART drivers are interrupt driven and buffer the characters.  The
 reader itself is only issuing less than 20 characters per read.

Is there a better solution than having our application adjust the priority of external processes to fix this?