2006-12-27 20:14:30

by loyeyoung

[permalink] [raw]
Subject: The Input Layer and the Serial Port

To the King of Penguins and the Wise Architects of the Kernel:

Greetings and Smooth Compiling to All,

I, a humble pilgrim in the Land of Tux, have spent over a year seeking a simple answer to what seems to me a simple question: How do I expose my RS232 barcode scanner to the input layer so that the scanned information shows up in applications? Basically, I need the scanner to act like another keyboard. Scan a code, see the numbers.

This can't be difficult. I must be overlooking something. Every cash register in America has a barcode scanner. Surely SOME of them must run Linux or Unix. Someone out there knows something I don't. The lowly serial port is still very much a fact of life in industry. I believe I recall reading the judgment of The King of Penguins himself that the kernel must continue support for serial ports generally, and barcode scanners in particular, but I can't find the edict now so maybe my memory is playing tricks on me.

Reading ASCII characters coming in the serial port should be as easy as selling donuts to cops. I have learned, however, that when it comes to the Mysteries of the Kernel, simple answers are sometimes hard to find.

+I have studied the writings of the Weekly Pundit, Little Redstone, and the One-With-Two-Last-Names. http://lwn.net/Kernel/LDD3.
+I have consulted the Oracles of Mepis. http://www.mepis.org/node/9104.
+I have wandered in the Valley of X. http://lists.freedesktop.org/archives/xorg/2006-December/020579.html.
+I have read under the Scribe of the Text Terminal How-To. http://www.linux.com/howtos/Text-Terminal-HOWTO.shtml
+I have been to the Source. /usr/src/linux-source-2.6.17/drivers/input/*.
+I have searched the chronicles of the children of Debra and Ian. http://lists.debian.org/search.html

Alas and alack, knowledge of the secret still eludes me, and I am not alone. What follows is a partial list of what I have found.

Apparently, the input layer has been cussed and discussed for several years now. See, e.g., http://linuxconsole.sourceforge.net/input/input.html (2000), http://kerneltrap.org/node/2947 (2004), http://kerneltrap.org/node/2199 (2004), http://www.frogmouth.net/hid-doco/linux-hid.html (??). I have found no final announcement of "The Way Things Are" or "The Way Things Ought To Be," however. The USB bus admittedly provides a much more robust technical platform upon which to build new devices, and it is well documented and integrated into the input layer. http://www.usb.org/developers/hidpage/.

Vojtech Pavlik has written a plethora of input device drivers for the serial port, and much of the input layer itself. His work on the joystick included inputattach. Although the man page says it is to "attach a serial line to a joystick device," inputattach also configures a variety of serial character devices. Unfortunately, inputattach has options for specific brands of devices (re-mapping various keys and functions), but doesn't have a generic character input device option that I can tell. When I read the source code, I see that generic keycodes are in the code, but each option changes the generic list in some way. (Is it mere coincidence that VP is from a land that limits the use of vowels? Does the path to understanding input run through Prague? Is Alan Cox really the alter ego of the evil leader of the underground gnomes? Mysteries too great for me.)

"Do you pine for the days when men were men and wrote their own device drivers?"

I wish that I knew how to program in C, and that I knew how to recompile the kernel. If I did, I could probably write the "trivial keyboard driver" that has been suggested. http://lists.freedesktop.org/archives/xorg/2006-December/020596.html. I'd probably even make a patch to inputattach or some other userspace program to bring barcode scanners to Linux. I might even would write a generic driver specifically for barcodes. But C is Greek to me. Besides, it is a language so holy that it cannot be spoken.

I may be quacking up the wrong tree. (Do penguins quack? Squawk? Yet another mystery . . .) The kernel's serial driver seems to work just fine. If I issue from the command line "cat /dev/ttyS0" and then scan something, I get my numbers. (I did have to wander around in the dark for many months until I found that stty must throttle the port speed down to 9600.) However, seeing the number in the console doesn't help me much. I need the information in applications.

If the input layer recognized the data coming in through the serial port as data from an input device (or if I could somehow tell it to do so), and if it showed up as an event under /dev/input/, I could use evdev to send the information through the X server as an InputDevice. But I don't know how to tell evdev what to do, and I can't find documentation that tells me how.

There is much written about the big fracas over the CueCat scanner, which was a serial barcode scanner, but the related drivers around are special to it. (The CueCat scanner even has its own documented device name "/dev/scanners/cuecat" and "major/minor number 10/199". http://public.www.planetmirror.com/pub/linux/docs/device-list/?fl=l) There is an old driver "linbar" from 1999, but it only works for a console and it doesn't do anything in 2.6. Most of the links to it are dead.

I must emphasize that I in no way intend any criticism towards anyone. My problem is trivial in the grand scheme of things, and I am extremely grateful to those who have built the Shining Kernel on the Hill. (World domination being a worthy cause, sharks with lasers notwithstanding.)

Oh great King of the Land of Tux! Have mercy on me, your most unlearned and unworthy user!

May Tux Live Forever,

Loye Young
Laredo, Texas

PS - [solemn look on face, right hand on Bible, left hand raised, typing with nose] I certify, under penalty of exile from the Land of Tux, that I have read, marked, and inwardly digested the mailing list FAQ. http://www.tux.org/lkml/.
rial driver seems to work just fine. If I issue from the command line "cat /dev/ttyS0" and then scan something, I get my numbers. (I did have to wander around in the dark for many months until I found that stty must throttle the port speed down to 9600.) However, seeing the number in the console doesn't help me much. I need the information in applications.

If the input layer recognized the data coming in through the serial port as data from an input device (or if I could somehow tell it to do so), and if it showed up as an event under /dev/input/, I could use evdev to send the information through the X server as an InputDevice. But I don't know how to tell evdev what to do, and I can't find documentation that tells me how.

There is much written about the big fracas over the CueCat scanner, which was a serial barcode scanner, but the related drivers around are special to it. (The CueCat scanner even has its own documented device name "/dev/scanners/cuecat" and "major/minor number 10/199". http://public.www.planetmirror.com/pub/linux/docs/device-list/?fl=l) There is an old driver "linbar" from 1999, but it only works for a console and it doesn't do anything in 2.6. Most of the links to it are dead.

I must emphasize that I in no way intend any criticism towards anyone. My problem is trivial in the grand scheme of things, and I am extremely grateful to those who have built the Shining Kernel on the Hill. (World domination being a worthy cause, sharks with lasers notwithstanding.)

Oh great King of the Land of Tux! Have mercy on me, your most unlearned and unworthy user!

May Tux Live Forever,

Loye Young
Laredo, Texas

PS - [solemn look on face, right hand on Bible, left hand raised, typing with nose] I certify, under penalty of exile from the Land of Tux, that I have read, marked, and inwardly digested the mailing list FAQ. http://www.tux.org/lkml/.


2006-12-27 21:10:26

by James Simmons

[permalink] [raw]
Subject: Re: The Input Layer and the Serial Port


> To the King of Penguins and the Wise Architects of the Kernel:
>
> Greetings and Smooth Compiling to All,
>
> I, a humble pilgrim in the Land of Tux, have spent over a year
> seeking a simple answer to what seems to me a simple question:
> How do I expose my RS232 barcode scanner to the input layer so
> that the scanned information shows up in applications? Basically,
> I need the scanner to act like another keyboard. Scan a code,
> see the numbers.

By the magic of serio. Take for example the AT keyboard which is
one of the most common keyboards in the world. I have seen and
used it attached to a PC via parport, serial port and the standard
PS/2 port. So to handle cases like this the input layer created a
serio interface. This way it does matter what bus the keyboard is
attached to the same code can be used to drive the keyboard.
The good news for you is that a serial port serio exist already.
All you need to do is write the device interface. I recommend you
take a look at sermouse.c in the drivers/input.mouse directory
for a guide.

P.S
In fact I have been playing with serio for a way to
work with LCD panels that can be wired via parport, gpio etc.
Its just so flexiable :-)

2006-12-27 23:50:27

by loyeyoung

[permalink] [raw]
Subject: Re: The Input Layer and the Serial Port

"Nothing is hard if you already know how." -- Unknown

"Nadie nace enseñó." -- Mexican proverb. ("Nobody is born taught.")

>All you need to do is write the device interface.

I wish that I knew how to program in C, and that I knew how to recompile the kernel. But C is Greek to me. Besides, it is a language so holy that it cannot be spoken.

Surely this has been done before. Perhaps you have already, because you say:

>Take for example the AT keyboard which is
>one of the most common keyboards in the world. I have seen and
>used it attached to a PC via parport, serial port and the standard
>PS/2 port. So to handle cases like this the input layer created a
>serio interface.

If plain ASCII text is coming in the serial port, would the kernel know or even care what device was generating the characters? Could I just use whatever interface you did?

How does the input subsystem and udev know how to populate /dev/input? Does evdev automagically pick up everything in /dev/input?

>I recommend you take a look at sermouse.c
>in the drivers/input.mouse directory
>for a guide.

I looked, but the source code I have (2.6.17, Debian) doesn't have anything called sermouse.c in the /drivers/input directory.

I'm still Clue Minus One on how to make my scanner work.

[Warning Will Robinson! Danger! Rant mode ON!]

"Cobbler, you have no shoes."

Perhaps I am misunderstanding something, but why does the world need a unique, handwritten, geek-speak device driver for every gadget in the universe? I have to think that writing the device drivers and interfaces for most input devices is a huge exercise in reinventing the wheel all over again. (This is admittedly the luxury of one such as myself, who has never written one.) And, even assuming there are such instances, why should the kernel developers be the only ones writing them.

(The following was written by someone who doesn't know what he is talking about, to those who do. It is likely that the latter will think the former is ignorant in whole or in part, because such are the facts. Suspension of critical thinking at the micro level is consequently necessary.)

When I read (though not understood) Linux Device Drivers, 3d edition, the question that kept coming to my mind is "Why can't this be automated? Can the Three Wise Men most of LDD3 in C instead of English?"

The kernel has a discrete, documented set of inputs. Well, they will be documented when OSDL hires that technical writer. Or maybe sometime else. In any event, there are specific, well-known actions that the kernel can be told to do. The King Penguin and his Court know ex ante the complete list of such actions. Code has or can be written for each possible command to the kernel. Let the count of such kernel commands be equal to K.

Likewise, there are a limited number of buses over which the information to and fro all the various devices can be sent. Again, we know ex ante what they are and should be able to code the translations between what comes in from the bus and what commands get issued. Let the count of such buses be equal to B.

The count of all possible input commands for all buses (let such count be equal to I) is K times B. (K x B = I) "I" may be a large number, but not an insurmountable one.

In particular, input devices such as character generators and pointers have a discrete set of outputs. Engineers of the devices design their widgets with a target set of outputs in mind. They know that the devices will be attached to computers and design the devices for a particular bus. They know the requirements for the bus they are designing for. (Pardon the ending preposition.) Consequently, it must be possible to anticipate the possible universe of outputs from most devices on a particular bus and allow a user to map the device outputs to the appropriate command. In most cases, we know what the device will send, or most of it anyway, so a default list of commands will work just fine.

All that is remaining is to configure the idiosyncratic events that some engineer felt was way-cool and different. A generic program can be written to listen for what the device sends and map it to one of I commands. There are "snoop" programs available for most, if not all, buses. It must be possible, therefore, to automate the entire process in a user-space program. First, the program would interview the user. It would start off by making an attempt to discover all devices connected and presenting a list to the user. "Which device do you want to configure?" The user would have an "Other Device" option to tell the machine which connection on which bus the device is using. Next, the program would ask for the type of device being configured (character generator, pointer, etc.) and for any relevant information not obtainable via PnP (manufacturer, model, etc.). Now the program knows quite a bit about the device and can narrow the field of likely choices from I to a subset of K. The user then teaches the program the device's lingo. Fire off the device, assign a command. Fire of the device, assign another command.

At the end of the process, the program can write the source code and documentation for the driver, compile the binary, and even offer to insert the module into the kernel on the fly. And, so that the King Penguin is never surprised by any sharks with lasers, the program will offer to email the driver and binary to someone in a land that vowels forgot or to someone with a hyphen in his name for the benefit of all Penguins. Perhaps the Three Wise Men would be able to tweak the driver for efficiency, but they would have the benefit of a first draft generated by a program they wrote or at least reviewed.

I'm not the only one who has thought along these lines. A program with similar functionality as what I am describing has been written for USB keyboards. See http://keytouch.sourceforge.net/.

[End Rant Mode]

All this, is far afield of my original question. How do I tell the input layer to send the information coming in from my serial port barcode scanner to the applications on my box?

Respectfully submitted,

Loye Young
Laredo, Texas


way-cool and different. A generic program can be written to listen for what the device sends and map it to one of I commands. There are "snoop" programs available for most, if not all, buses. It must be possible, therefore, to automate the entire process in a user-space program. First, the program would interview the user. It would start off by making an attempt to discover all devices connected and presenting a list to the user. "Which device do you want to configure?" The user would have an "Other Device" option to tell the machine which connection on which bus the device is using. Next, the program would ask for the type of device being configured (character generator, pointer, etc.) and for any relevant information not obtainable via PnP (manufacturer, model, etc.). Now the program knows quite a bit about the device and can narrow the field of likely choices from I to a subset of K. The user then teaches the program the device's lingo. Fire off the device, assign a command. Fire of the device, assign another command.

At the end of the process, the program can write the source code and documentation for the driver, compile the binary, and even offer to insert the module into the kernel on the fly. And, so that the King Penguin is never surprised by any sharks with lasers, the program will offer to email the driver and binary to someone in a land that vowels forgot or to someone with a hyphen in his name for the benefit of all Penguins. Perhaps the Three Wise Men would be able to tweak the driver for efficiency, but they would have the benefit of a first draft generated by a program they wrote or at least reviewed.

I'm not the only one who has thought along these lines. A program with similar functionality as what I am describing has been written for USB keyboards. See http://keytouch.sourceforge.net/.

[End Rant Mode]

All this, is far afield of my original question. How do I tell the input layer to send the information coming in from my serial port barcode scanner to the applications on my box?

Respectfully submitted,

Loye Young
Laredo, Texas


2006-12-28 13:51:35

by Matthias Schniedermeyer

[permalink] [raw]
Subject: Re: The Input Layer and the Serial Port

Loye Young wrote:
>>Take for example the AT keyboard which is
>>one of the most common keyboards in the world. I have seen and
>>used it attached to a PC via parport, serial port and the standard
>>PS/2 port. So to handle cases like this the input layer created a
>>serio interface.
>
>
> If plain ASCII text is coming in the serial port, would the kernel know or even care what device was generating the characters? Could I just use whatever interface you did?

A problem at this point may be that a AT-keyboard doesn't spit out ASCII
but Scan-Codes, so a serial device spitting out ASCII would have to be
put into the loop AFTER the stage that makes conversions, or you would
have to convert ASCII back to Scan-Codes before.

Btw. I'm not normaly into barcode-scanning, but for something at work i
tried a USB-scanner (From Symbol AFAIR) to see what is stored in the
barcodes that are on the prints that i have to generate. The scanner
just registered as a plain HID-device, which resulted in the data
comming as key-presses. It was just "Plug & Play", i didn't need any
software or anything else. I just plugged the device in, opened a
text-editor to catch the data, then i scanned the bar-codes and was
happy. :-)

So if you aren't nailed to a serial scanner, you just may try a USB-scanner.

>>I recommend you take a look at sermouse.c
>>in the drivers/input.mouse directory
>>for a guide.
>
>
> I looked, but the source code I have (2.6.17, Debian) doesn't have anything called sermouse.c in the /drivers/input directory.

# find /usr/src/linux-2.6.19 -name "*sermouse*"
/usr/src/linux-2.6.19/drivers/input/mouse/sermouse.c





Bis denn

--
Real Programmers consider "what you see is what you get" to be just as
bad a concept in Text Editors as it is in women. No, the Real Programmer
wants a "you asked for it, you got it" text editor -- complicated,
cryptic, powerful, unforgiving, dangerous.

2006-12-28 16:15:46

by Richard Purdie

[permalink] [raw]
Subject: Re: The Input Layer and the Serial Port

On Wed, 2006-12-27 at 13:54 -0600, Loye Young wrote:
> I, a humble pilgrim in the Land of Tux, have spent over a year seeking
> a simple answer to what seems to me a simple question: How do I expose
> my RS232 barcode scanner to the input layer so that the scanned
> information shows up in applications? Basically, I need the scanner to
> act like another keyboard. Scan a code, see the numbers.

I can give you some hints but it will involve writing a program. It can
all be done in userspace though, saving any pain of messing with the
kernel internally/kernel recompiling.

The kernel has a driver called uinput which lets you inject input events
into the kernel from a userspace piece of code. You can write a program
to read data from /dev/ttyS0 (at 9600bps) and pass it to this uinput
driver. That should then do exactly what you need.

Working out for to use uinput caused me a few headaches but I can point
you at some example code:

http://svn.o-hand.com/view/misc/trunk/zaurusd/apps/tskeys/tskeys.c?rev=59&view=markup

This code adds support for offscreen soft "buttons" on a touchscreen. It
passes the key events to the kernel via uinput.

Cheers,

Richard

2006-12-30 15:29:58

by Petr Štetiar

[permalink] [raw]
Subject: Re: The Input Layer and the Serial Port

Loye Young <[email protected]> [2006-12-27 13:54:33]:

> To the King of Penguins and the Wise Architects of the Kernel:
>
> Greetings and Smooth Compiling to All,
>
> I, a humble pilgrim in the Land of Tux, have spent over a year seeking a
> simple answer to what seems to me a simple question: How do I expose my
> RS232 barcode scanner to the input layer so that the scanned information
> shows up in applications? Basically, I need the scanner to act like another
> keyboard. Scan a code, see the numbers.

Maybe http://kbde.sourceforge.net/ it's what you're looking for.

-- ynezz

2007-01-02 12:06:30

by David Greaves

[permalink] [raw]
Subject: Re: The Input Layer and the Serial Port

Loye Young wrote:
> Basically, I need the scanner to act like another keyboard. Scan a code, see the numbers.

Depends, do you want to get the job done or play with drivers?

If the former then get yourself to eBay and buy a brand new PS/2 barcode reader
for circa $10-$20 that plugs between the ps/2 port and the keyboard and 'just
works' (I use mine to enter ISBN numbers into a database).

It'll probably arrive before you can finish typing another Iliad^H^H^H^email ;)

David
PS I think for just a couple of $ you can even get serial to PS/2
pass-thru/converter cables.

http://cgi.ebay.co.uk/SERIAL-RS232-PS2-RJ45-RETAIL-SCANNER-CABLE-BARCODE_W0QQitemZ190067492336QQihZ009QQcategoryZ14929QQrdZ1QQcmdZViewItem

Dunno if these will work with your scanner.

2007-06-06 11:22:49

by Lars K.W. Gohlke

[permalink] [raw]
Subject: Re: The Input Layer and the Serial Port

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

how did you solved it???

- ------------------------
Mit freundlichen Gr??en
Lars K.W. Gohlke
mailto:[email protected]
- -------------------------
Visit http://www.lars-gohlke.de.vu

06.06.2007 13:18
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (MingW32) - GPGrelay v0.959

iD8DBQFGZpgqAAomYJ1taN8RAqksAJoCDKK0eojRl1lO2unoTLVZjzV/9ACdG5Md
MtMjNdhcTh1R2kNWmuamZS4=
=I2iy
-----END PGP SIGNATURE-----


Attachments:
lkwg82.vcf (124.00 B)