Wednesday, December 30, 2009

Creating udev rules on Linux

I spent some time figuring out how to customize behaviour when hot pluging devices on linux, so I might as well post my notes in case I forget. :)

You can use udev to trigger events, to write custom linux scripts for hot plugged device.

Here's one of the more clever ideas with custom hotplug scripts using a standard usb stick as a key to unlock the computer. This will secure a workstation to only the person with the key:

http://raftaman.net/?p=300

Here's a simple example of writing a custom image processor for a camera (most cameras are already supported, but this is an example from the ground up).

Basically what is needed is:

a. figuring out the name of the device on the system
b. figuring out the full signature of the device
c. writing a rule to match the signature
d. writing a program that will be triggered

First you have to figure out the name of the device on the system. When the device is unplugged, take a snapshot of all the device on the system. IMO an easy way is to look at the /sys/ directory. It will contain nodes for all hotplugged devices. First take a snapshot when the device is unplugged.

find /sys > /tmp/dev_out.txt

Then plug in the device, and take another snapshot:

find /sys > /tmp/dev_in.txt

Now you can compare the differences in the two snapshots. Note that one physical device can actually be several devices (for example if it has multiple partitions). You will want a short name.

diff /tmp/dev_out.txt /tmp/dev_in.txt

An alternate way to find the name of device nodes, run this, and plug in device.

udevadm monitor

The name might look like /sys/path/to/device. Then get complete signature of the device:

udevadm info -a -p /sys/path/to/device

Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices... The complete signature of the device looks like a bunch of gibberish, but it's just key/value pairs:


looking at device '/devices/pci0000:00/0000:00:1f.4/usb2/2-2/2-2:1.0/host13/target13:0:0/13:0:0:0/block/sdc':
KERNEL=="sdc"
SUBSYSTEM=="block"
DRIVER==""
ATTR{range}=="16"
ATTR{ext_range}=="256"
ATTR{removable}=="1"
ATTR{ro}=="0"
ATTR{size}=="429569"
ATTR{capability}=="53"
ATTR{stat}==" 87 996 1083 1820 0 0 0 0 0 1016 1820"

looking at parent device '/devices/pci0000:00/0000:00:1f.4/usb2/2-2/2-2:1.0/host13/target13:0:0/13:0:0:0':
KERNELS=="13:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{device_blocked}=="0"
ATTRS{type}=="0"
ATTRS{scsi_level}=="0"
ATTRS{vendor}=="VTech "
ATTRS{model}=="Kidizoom "
ATTRS{rev}=="1.21"
ATTRS{state}=="running"
ATTRS{timeout}=="30"
ATTRS{iocounterbits}=="32"
ATTRS{iorequest_cnt}=="0x28a"
ATTRS{iodone_cnt}=="0x28a"
ATTRS{ioerr_cnt}=="0x8"
ATTRS{modalias}=="scsi:t-0x00"
ATTRS{evt_media_change}=="0"
ATTRS{queue_depth}=="1"
ATTRS{queue_type}=="none"
ATTRS{max_sectors}=="240"

looking at parent device '/devices/pci0000:00/0000:00:1f.4/usb2/2-2/2-2:1.0/host13/target13:0:0':
KERNELS=="target13:0:0"
SUBSYSTEMS=="scsi"
DRIVERS==""

...

These two lines should basically describe the device:

ATTRS{vendor}=="VTech "
ATTRS{model}=="Kidizoom "

Forming a rule is basically a matter of picking out a few lines from the complete signature and putting them all on one line seperated with commas. Files go under

/etc/udev/rules.d/

The name of the rule starts with a number (order executed) and ends with .rules
There can only be at most one parent in matching rules.
RUN will trigger a program to execute after device is mounted
ACTION can be "add" or "remove"

# EXAMPLE:
# FILE /etc/udev/rules.d/99-camera-copy.rules
# This will trigger /path/to/your/program
# when the device is plugged in
ACTION=="add", SUBSYSTEM=="block", ATTRS{vendor}=="VTech ", ATTRS{model}=="Kidizoom ", ATTRS{rev}=="1.21", RUN+="/path/to/your/program"

Also, udev will pause until the program called is finished. You can also run the program in the background to return immediately (recommended for longer processes). To detach bash script, enclose it in braces and end with &:


#!/bin/bash
{
echo "hello there" >> /tmp/udev_test.log
} &

All programs will be run as root user (full permissions). To lauch graphical programs as a regular user:

#!/bin/bash
{
# what program to run?
run=picasa
user=`who grep :0\) cut -f 1 -d ' '`
export DISPLAY=:0.0
su $user -c "xhost local:$user; $run"
} &


For more information, here's an older writeup (the tool "udevinfo" has changed to "udevadm info")

http://www.reactivated.net/writing_udev_rules.html


Also, thank you Rcspam for an example of using the kidizoom on Ubuntu 10.04+:
http://rcspamsblogen.blogspot.com/2011/01/kidizoom-and-ubuntu-maverick.html
(English)

Wednesday, December 16, 2009

Understanding "Imaginary" Numbers

In grade school, when I learned about negative numbers, I thought they made a lot of sense. Until I learned that multiplying two negatives make a positive number:

-1 * -1 = 1

I recall this seemed completely backwards, intuitively. And most the class agreed. But the teacher explained to everyone that they were wrong. However, the beauty of math is that it really is just a set of rules, and the rules can be anything as long as they are consistent.

This is just one definition of multiplication. We can imagine a different system of numbers, with a different system of multiplication rules.  And as long as we can make the rules consistent, each system of numbers is just as valid.

One way to think about this is, we can think of two different concepts of "negative" numbers: "fully negative" numbers, and "partially negative" numbers.  Multiplying two "partially negative" numbers will produce a "fully negative" number.  

For example, somewhat like defining short '-' and long '--' negative symbols:

-1 * -1 = --1

IOW, multiplying two "partially negative" 1's will produce a "fully negative 1."

However, if we have two number systems, we of course can't have the same symbol mean two different things or it's hard to read. So we can define the more intuitive '-1' with a special symbol like 'i' (perhaps to stand for something like "intuitive -1").

Then we can connect the two number systems together like:

i * i = -1

Then we can treat 'i' like any other unit of measure. As in: 1i, 2i, 3i, ...

A 'complex number' makes use of both number systems, and can be visualized the same way as two-dimensional XY coordinate system. The difference is that each axis has a different number system attached to it. These can written as a sum:

x = a + bi

The term 'imaginary' is a horribly confusing term though, since these numbers are no more or less imaginary than ordinary negative numbers. If anything, they are based in more intuitive rules about negative numbers.

If anything, you can just think of i as "a more intuitive -1" which follows an alternative multiplication rule: two "intuitive" negative numbers multiplied together equal a "regular" negative number.  This is entirely consistent with the standard rule: two "regular" negatives multiplied together equal a "regular" positive number.

Monday, December 7, 2009

Making sense of bad electronic notation

One thing that used to really bug me about electrical notation is that electron flow is actually going in the opposite direction of the conventional current notation. The current is typically shown moving from the positive terminal to the negative terminal in conventional current notation. However, the electrons are actually moving from the negative to the positive terminal.

The problem is, when Ben Franklin came up with labels 'positive' and 'negative' it was a clever guess. What are the odds of being wrong about current flow? 50/50? By the time people figured out the details, the counter-intuitive notation had firmly cemented itself in electric nomenclature. :)

Anyway, counter-intuitive notation is confusing to me, so I finally came up with a work-around of making sense of conventional diagrams. Instead of thinking of a circuit as an electron-powered device, you can also think of a circuit as a vacuum-powered device. Then the positive terminal has a "surplus of vacuum" as compared to the negative terminal.

If two sealed jars are connected by tube, the difference in air pressure between them represents the voltage. The one with the lowest pressure would be the positive end (which can be seen as driving the system). The actual number of particles flowing through the tube would be the current (amps).

The Amps, Volts and Resistance are somewhat circularly defined. Ideally, a pressure difference of 1 Volt will allow 1 Amp of current (6.242 x 10 ^ 18 charge carriers / sec) to move through a tube with 1 Ohm of resistance.

I suppose, it doesn't really matter as to the direction of the current in a circuit, as long as the notation is consistent. In some cases, it might be easier to visualize something as a vacuum-powered device rather than an electron-powered device. Just like it's sometimes easier to think in terms of 'conductance' vs 'resistance' -- as two sides of the same coin.

Clever Clock Design

"This clock, spotted at Design Miami, features an LCD face playing a 12-hour loop of a man erasing and redrawing the time every minute."