Friday 3 December 2010

Kernel crash!

Haven't had one of these in a while. Caps lock and scroll lock suddenly started flashing at me. No morse code though, unless it was meant to be just and endless ............ as in the Morse error symbol.

What was I doing? I was grabbing frames from the webcam. It had been going fine a while earlier, when I used a shell script to take one frame at a time, but now I'm trying to let webcam grab multiple frames separated by 0.2 seconds (hint: it can't - the delay parameter is an integer).

System info:

Linux bernd-desktop 2.6.31-22-generic #68-Ubuntu SMP Tue Oct 26 16:38:35 UTC 2010 i686 GNU/Linux

Modules:

Module Size Used by
binfmt_misc 8356 1
nfsd 241104 9
lockd 67724 1 nfsd
nfs_acl 2844 1 nfsd
auth_rpcgss 36672 1 nfsd
sunrpc 191776 8 nfsd,lockd,nfs_acl,auth_rpcgss
exportfs 4412 1 nfsd
snd_hda_codec_realtek 203328 1
snd_hda_intel 27016 2
snd_hda_codec 75708 2 snd_hda_codec_realtek,snd_hda_intel
snd_usb_audio 84224 2
snd_usb_lib 16284 1 snd_usb_audio
snd_pcm_oss 37920 0
snd_mixer_oss 16028 1 snd_pcm_oss
snd_seq_dummy 2656 0
snd_pcm 75296 4 snd_hda_intel,snd_hda_codec,snd_usb_audio,snd_pcm_oss
snd_hwdep 7200 2 snd_hda_codec,snd_usb_audio
snd_seq_oss 28608 0
snd_seq_midi 6464 0
snd_rawmidi 22176 2 snd_usb_lib,snd_seq_midi
snd_seq_midi_event 6940 2 snd_seq_oss,snd_seq_midi
snd_seq 50224 6 snd_seq_dummy,snd_seq_oss,snd_seq_midi,snd_seq_midi_event
snd_timer 22276 2 snd_pcm,snd_seq
snd_seq_device 6920 5 snd_seq_dummy,snd_seq_oss,snd_seq_midi,snd_rawmidi,snd_seq
snd 59236 21 snd_hda_codec_realtek,snd_hda_intel,snd_hda_codec,snd_usb_audio,snd_pcm_oss,snd_mixer_oss,snd_pcm,snd_hwdep,snd_seq_oss,snd_rawmidi,snd_seq,snd_timer,snd_seq_device
iptable_filter 3100 0
ppdev 6688 0
soundcore 7264 1 snd
parport_pc 31940 1
snd_page_alloc 9156 2 snd_hda_intel,snd_pcm
gspca_zc3xx 47580 0
ip_tables 11692 1 iptable_filter
x_tables 16544 1 ip_tables
gspca_main 22812 1 gspca_zc3xx
pwc 81632 0
videodev 36736 2 gspca_main,pwc
v4l1_compat 14336 1 videodev
psmouse 57332 0
serio_raw 5280 0
lp 8964 0
parport 35340 3 ppdev,parport_pc,lp
fbcon 36640 72
tileblit 2460 1 fbcon
font 8124 1 fbcon
bitblit 5372 1 fbcon
softcursor 1756 1 bitblit
floppy 54916 0
8139too 22620 0
8139cp 19260 0
mii 5212 2 8139too,8139cp
i915 227528 3
drm 160096 3 i915
i2c_algo_bit 5760 1 i915
video 19380 1 i915
output 2780 1 video
intel_agp 27996 2 i915
agpgart 34988 2 drm,intel_agp

And my ~/.webcamrc:

[grab]
device = /dev/video0
text = "%Y-%m-%d %H:%M:%S"
infofile = foo
fg_red = 255
fg_green = 255
fg_blue = 255
width = 640
height = 480
delay = 0.2
wait = 3
input = usb
#norm = pal
rotate = 0
top = 0
left = 0
bottom = -1
right = -1
quality = 75
trigger = 0
once = 0

[ftp]
host = localhost
user = webcam
pass = xxxxxx
dir = public_html/snapshots
file = webcam.jpeg
tmp = uploading.jpeg
passive = 1
debug = 1
auto = 0
local = 1
ssh = 0

Finally, the script:

#!/bin/sh

i=1
while true; do
sleep 0.1
webcam >/dev/null 2>&1 &
mv public_html/snapshots/webcam.jpeg `date +public_html/snapshots/webcam-%Y%m%d-%H%M%S-$i.jpeg` || continue
i=$(($i+1))
done

Astute readers will notice that it's a forkbomb-lite, spawning a new webcam process every 0.1 seconds! Still, no userland process should be able to make the kernel panic, right?

I don't really feel like investigating this too far. Reboots are SO disruptive!

Thursday 8 July 2010

Back-annotation to gschem

I've added the capability to back-annotate pin swaps to gschem, to my fork of the gEDA project. Notice the commit "Add scheme function to swap pins."

To implement this, I took heed of David Wheeler's advice: "All problems in computer science can be solved by another level of indirection ..." (I stopped reading right there). Applying this to the gEDA data structures, I've added some magic behaviours to some attributes:
  • vpads - stores a map between a chip's functions and its pads. Think: "virtual pads". This is the one that pin swapping will affect.
  • packagepins - stores a map between a chip's pads and the pins on the package it is in. We need this to deal sanely with the same chip in different packages: PLCC vs QFP.
  • uuid - to uniquely identify a component. More unique than refdes! Uniqueness should survive the text editor, and it should survive having multiple sheets loaded with different "U101" in each.
That should give you an idea of how I implemented pin swapping. There's more though, and it relates to a slotting mechanism I've built earlier and that doesn't fail the "mental model = program model" test. In fact the pin swapping works only in the context of this alternate slotting mechanism.
  • pinnumber - you don't actually write a pinnumber anywhere explicitly - the slotting mechanism will derive the right pin number for you from the other attributes.
  • pinfunction - the symbol defines this. abstract/opamp.sym, for example, has "pinfunction=noninv" on the pin next to the "+" label.
  • slotowner - in a symbol, it references (by uuid) a component that has slots, presumably slots that are "compatible" with the symbol.
  • slotname - defines which slot to use. In linear/lm324-slots.sym, I've defined slots named "opamp1", "opamp1-powered", ... (copies for 2, 3, 4) ..., "power".
  • slotrewrite - defines which attributes in the symbol should "inherit" their value from the component they're attached to. Useful for refdes and part.
  • slotmap - a map from symbolic pin function to an entry in the vpads map.
(Some of the map-like attributes are inferred to be identity maps if they are missing, or are missing specific entries.)

Time for some screenshots. I'll do only one pin swap to illustrate what PCB might one day do as part of a sequence of swaps that, together, effect a gate swap. Let's supppose I have two opamps, and the PCB tracks want to route crazy, unless I can swap them. Before I touch anything, I have opamp1's pins as 1, 2 and 3, and opamp2's as 5, 6 and 7.

But I don't like that. I want them exactly the other way round. I'll start with the output pin:

(Notice the use of uuid - which PCB can certainly know via its own attributes.) Oh, did you see the pimped-up REPL I added?

Hey presto! opamp1's output pin is now 7, and opamp2's is 1!


I'll leave it as an exercise to the reader to do the other two pins. Bonus points for teaching PCB to understand DJ Delorie's syntax for specifying swappable groups of "THINGS". I'm not sure what the right specifier for a 324 should be. Maybe ([2,3,1],[6,5,7],[9,10,8],[13,12,14])? But I don't see the power pins - 4 and 11 - in there. Meh, that's for another day.

Wednesday 12 May 2010

Coordinate prompts in gschem

Way back when I was a kid I learned a bit of AutoCAD, having spent some time at a naval architect firm on Friday afternoons while my stepdad was having a beer with his mates. I wasn't big into beer, rather into computers, so Christo put me in front of their CAD station and showed me a few basics. Somewhere along the line I also had AutoCAD at home (probably a bootleg copy), and there I learned about AutoLISP, probably even programmed a few simple macros in it.

The possibility of giving gschem a similar capability has been haunting me for quite a while, knowing that it couldn't possibly be that hard, since it already uses Guile for its scheme magic. And now, recently I've taught gschem to let a scheme expression ask for coordinates:



Here I'm getting the REPL to trigger a prompt for a place to put a NAND gate. Actually running this script is a little less in-your-face, and you might not notice it in the screenshot, so I'll apply my magic red marker:


I won't show you a screenshot of the NAND gate once it's on the schematic, because that'd just be boring. Also this function exposes a bug in gschem: the drawing area doesn't refresh after the call to (add-component-at-xy ...)

I'm still tying up some loose ends in the interface related to keyboard focus going to the wrong widget, and I'm not convinced the combobox is the right affordance. Alternatives?