- Main Linux kernel home page
- Memory management
- udev (device manager and dynamic
/devdirectory) - IEEE 802.11 (networking)
- USB stack
- IEEE 1394/FireWire
- BlueZ (Bluetooth stack)
- Memory technology devices (e.g. flash)
- ALSA (audio drivers)
- FFADO (IEEE 1394/FireWire audio
- UVC (USB Video Class) drivers (webcams)
2009-06-01
Linux kernel subsystem home pages
2009-05-04
Shell History Stats
Inspired by reading an old thread on my local Linux user group mailing list:
$ history | awk '{a[$2]++ } END{for(i in a){print a[i] " " i}}' | sort -rn | head
94 povray
58 source
55 ./wacdump
32 l
31 cd
25 dcraw
22 cp
21 gimp
20 less
19 gvim
:) I should run that more often. Maybe feed to Twitter. Or not.
2009-05-02
Arduino mouse control for Pure Data using Expect
Here’s a little Expect script for getting a control stream into Pure Data, in my case from a butchered Genius serial mouse that I wrote an interrupt-driven Arduino driver for. The driver sends a “+” or “-” down the serial line each time the optical rotary encoder in the mouse guts moves a click. This assumes the Arduino is connected on /dev/ttyUSB0 (e.g. on Linux). Use a [netreceive 3000] (or whatever port you like) in Pure Data to receive.
Note: this only uses one mouse axis, requiring two interrupts. Apparntley the Arduino Mega has six interrupt lines externally available, so I'll be adding another axis of control soon.
#!/usr/bin/expect
# Take Arduino mouse '+'/'-' stream and convert into Pure Data FUDI format, without buffering.
# To run:
# expect mouse-pd.expect | pdsend 3000
# TODO: this should probably use Expect's stty command to set the serial port up to match the Arduino program.
eval spawn -noecho cat /dev/ttyUSB0
log_user 0
while (true) {
expect {
+ {send_user "1;\n"}
-- {-} {send_user -- "-1;\n"}
}
}
Here’s the Arduino code:
// Simple interrupt-driven driver for quadrature encoder input (e.g. from a disassembled photoelectric ball mouse).
// Many Arduino boards provide only two interrupts, I believe: INT0 (on pin 2) and INT1 (on pin 3):
const int intA = 0, intAPin = 2;
const int intB = 1, intBPin = 3;
volatile int A = 0, B = 0; // For storing the pin states for future reference to determine rotation direction
int A_Prev = 0, B_Prev = 0; // Should these be volatile, too?
void setup()
{
// Configure digital input pins for interrupt-driven timing:
pinMode(intAPin, INPUT); digitalWrite(intAPin, LOW);
pinMode(intBPin, INPUT); digitalWrite(intBPin, LOW);
Serial.begin(115200);
// Read initial state of the pins:
A_Prev = digitalRead(intAPin);
B_Prev = digitalRead(intBPin);
A = digitalRead(intAPin);
B = digitalRead(intBPin);
attachInterrupt(intA, changeA, CHANGE);
attachInterrupt(intB, changeB, CHANGE);
}
void changeA()
{
A = !A;
output();
A_Prev = A;
}
void changeB()
{
B = !B;
output();
B_Prev = B;
}
void output()
{
if (A == B_Prev)
Serial.print("+");
else if (B == A_Prev)
Serial.print("-");
else
Serial.print('?');
}
void loop() {}
Microcontroller programming is fun, BTW! I’d never written a driver or an interrupt handler until two days ago.
2008-01-29
Using find and xargs
Bah, I can never remember the options for making these play nicely with unusual filenames (spaces, quotation marks), so here is a note-to-self:
find . -print0 | xargs -0 -i echo {}
2007-12-02
Accessing PostgreSQL from Tcl
From version 8.0 of PostgreSQL, the Tcl client library (pgtcl) has apparently been dropped from the core distribution. On Gentoo GNU/Linux, the Tcl client library does not seem to be built, even with the tcl USE flag. There are apparently three PostgreSQL-for-Tcl packages now available separately on PgFoundry:
http://pgfoundry.org/projects/pgtclng/http://pgfoundry.org/projects/pgintcl/http://pgfoundry.org/projects/pgtcl/
AFAICT, pgtclng is the current one to get. I downloaded, built and installed this from pgtcl1.6.0.tar.gz and tested availability as follows:
$ tclsh % package require Pgtcl 1.6.0
So far so good...
2007-10-28
2007-10-26
Tape Backups: Keeping the Tape Streaming
An LTO-3 tape drive requires a pretty high sustained data input rate in order to keep streaming. If the tape cannot be kept streaming, it will stop and restart, and possibly start “shoe-shining”: frequent stopping and restarting due to buffer under-runs. This behaviour incurs much more wear and tear on the tape and drive.
There are several things I have tried with good results to reduce or avoid this problem:
- Disable compression on the tape drive.
- Use previous generation media (LTO-2 media should work fine in an LTO-3 drive, but at LTO-2 speeds).
- Use the host system’s RAM to buffer the stream.
The third option assumes your host system has quite a bit of free memory, but can be very effective. A useful utility for doing this is mbuffer.
In the following example, a 1 GiB buffer is used (-m 1024M), with a tape block size of 262 144 bytes (-s 262144), and the output rate is limited to 25 MiB/s (-R 25M). The input stream is provided by tar, using the same block size (tar measures it in units of 512 bytes). You may have to tune the rate to suit the source drive and workload.
$ tar -b 512 -cpf - /.../wherever | mbuffer -s 262144 -R 25M -m 1024M -P 100 --md5 -f -o /dev/nst0