This is about some discoveries and experimentation with the picotux units. These have shown to be very useful.
Back in 2005 when they first appeared, they were advertised as the smallest Linux-based computers in the world; even if there may now be others, even smaller ones, they are certainly not very big physically, but there is still quite a lot inside the package.
This document is forever under construction. I'll add to it as time goes on and I get the inspiration or make new discoveries.
On 2010-12-17, the page picotux.com failed to load. I hope this is just a temporary problem. Yes, according to the main Kleinhenz page, they have suffered a server crash and will soon be back. I was worried about Picotuxes becoming unobtainum...
This is a small complete computer sold by Kleinhenz Elektronik. I bought two versions of them, the PT100, which is just the unit itself, and needs external connections to be useful, and the PT112, where some of the essential hardware is provided on a small circuit board. One PT112 came as part of the "starter kit", which also includes necessary development software, compilers for C and FORTRAN. The units are not self-programmed; there is an image available that includes editors and compiler, but that fills the entire memory. It could be possible to NFS mount to a remote volume that includes a self-compiler and libraries even without replacing the existing image, but the cross-compiling job works just fine.
The utilities are the Busybox set, which has a bit of application loading time, since there is basically one common 355K executable for everything, and all the commands in /bin are hard links under various names. As space is at a premium, this is a useful way to handle this. Although there is no editor program, it is possible to use head, tail, cat and similar programs to cut and paste lines of text files. Shell scripts work fine if they are started with the #!/bin/sh line and chmod 755.
The root file system is read-only, notably, the set of startup options in /etc is fixed. /usr is mounted on the non-volatile memory as read/write, and as /usr/bin is part of the path, it is a natural place to put the created executable files. There is a /mnt directory that is useful for attaching NFS network shares, and these will also become read/write, though the processes in the Picotux will show up as "nfsnobody". And /etc/passwd contains only the one record defining root, so there is no support for any different user. This isn't a great big deal, most files are moved into the Picotux not out of it. Only if there is so much data IO that it makes sense to use an NFS connection with all its overhead of maintenance, instead of just messaging via udp or tcp, this will be of interest.
The unit itself runs on 3.3V. There is a power converter on board the PT112, which allows for 7.5 V or so power input from a separate supply. The starter kit further includes a suitable power supply, that plugs into the mains, a serial cable, and a network cable.
For the PT100s I have used an LM317 on one project and an LP2252 on two other projects. The 317 requires about 6.5 V, while the LP2252 can be run off the 5V supply for other TTL circuits that may be connected to the GPIO lines.
The supplied software runs a Busybox shell on the serial port. This is at 38400 Baud. Unfortunately this is too fast for those old glass-TTYs that I have lying around, and although it is possible to issue the command stty 9600 to lower the speed to 9600 Baud, there isn't any easy way of doing this without having a 38400 Baud serial emitter at least!
I have tried out a "banger" arrangement, that reacts to the initial prompt from the shell and returns a command-line; that would then refer to some shell script which sets the hostname, gets the correct time from a server or a local RTC chip; then maybe starts up a server program, and so forth. This seems to work reasonably well: the garage supervision and weather station all use some variety of this scheme.
I've also managed to manipulate the serial port (which is the standard input and standard output from the main running program) to make it communicate with other, slower devices. The set-up here is a bit cumbersome and highly manual, starting with stty 1200 to lower the speed of the interface, then start a server program from a 1200 baud terminal, then hook up the actual instrument which also talks 1200 baud serial. This kind of arrangement would find battery backup most appropriate, though a PIC16F628A or similar could be made to switch speed while the Picotux switches speed with the stty command. This is no big deal, as the PICs work fine at 38400 as they do now.
Although there are alternate GPIO functions for the transmit and receive line, they are more useful as a serial port rather than digital IO.
However, the control of the serial lines through the serial driver as opposed to the GPIO isn't that straightforward. The TIOCMGET and TIOCMSET commands for ioctl() are not implemented in the driver at all, and while TIOCGICOUNT and TIOCMIWAIT are there, they don't seem to work: TIOCGICOUNT stays at zero and TIOCMIWAIT waits forever... So that part of the notes in Serial Programming on Linux do not apply to these devices.
This is what makes the unit stand out: the Ethernet connection. On power-up or reset, it will use DHCP to determine the IP-address. Programming the networking IO is straightforward, via the usual Berkeley sockets. I have ported a number of small, simple servers and client programs.
It does only power up the Ethernet interface on startup. To enable local loopback, and use TCP or UDP for inter-process communication, there is a command such as:
ifconfig lo up 127.0.0.1
that will work.
Now a client program can run on the same CPU as a server program, and they can talk to each other.
However, enabling this seems to mess up the NFS, so during testing and development or in applications where the Picotux is expected to operate as a NFS client, this mechanism is not available.
There is also a telnet server, which runs the same Busybox utilities as the serial console. Very useful for remote access through the LAN, or when the unit has the serial-port reassigned to instrument IO and it is not available for use as a console. To find the IP-address, I used arping in a loop on the host machine, where the IP-address and MAC address correlation is found. With the router I have here, each new reset of a Picotux unit, whether software or power-cycling, makes it assign a new IP-address within DHCP range. A more capable router can be set to a constant IP-address for the known MAC addresses, and give the same one out whenever it can.
The Picotux can run as an NFS client, and this makes development and testing easy: just have it mount a directory on the host system where the executable filea can be run from. There is a directory /mnt that is suitable for this. Once the programs work satisfactorily, they can be copied to /usr/bin or similar.
The system is 32-bit, big-endian, and must have pointers alined to 4-byte boundaries (bits 1 and 0 are both 0). It took some experimentation with older code to discover how important this was...
There is no MMU, and thus the fork() system function has to be replaced by vfork(). Multi-processing thus may require sub-process program code in a separate executable, invoked using one of the exec() functions. This also means that dynamical allocation of memory has to be done with care, and that wild pointer values could access data in some other process.
SysV interprocess communication elements, that is, semafores, shared memory segments, and message queues, are available, as are the usual Berkeley sockets for network programming. The localhost interface is not turned on by default.
There is nominally 5 GPIO lines available. On the Picotux 112 they have been assigned as two outputs and three inputs, for the RS232-style signals. It is necessary to remove some 0 ohm resistors on the board in order for the three inputs to be useable as outputs.
There are a couple more lines available, first of all, there is the /INIT pin that is only reserved for start-up and can be used as another GPIO line, and there is the green LED near the network connector, that can be used. Subsequent investigations into what appeared to be an unused I2C-interface on the Picotux 112 revealed that at least one of the three reserved and undocumented pins actually is another GPIO port that seems to be unused. A second of these three lines is also associated with a port and defaults to be an input on power-up. Then there are the two serial lines, that can be re-appropriated as GPIO lines also, though these are occupied by the shell so this has to stopped and the lines released. And as there is already the support for serial IO in the software, so these seem to remain more useful if retained as a serial port, in particular when talking to another controller over that line.
Name | Port | Org. Function | PT100 Pin | PT112 Pin |
RXD | PORTA3 | RXD Input | 7 | D9(3) |
TXD | PORTA7 | TXD Output | 8 | D9(2) |
GPIO4 | PORTA5 | RTS Output | 9 | D9(7) J5(5) |
GPIO5 | PORTA6 | DTR Output | 10 | D9(4) J5(4) |
GPIO2 | PORTA1 | CTS Input | 11 | D9(8) J5(2) |
GPIO3 | PORTA2 | DSR Input | 12 | D9(6) J5(3) |
GPIO1 | PORTA0 | DCD Input | 13 | D9(1) J5(1) |
RFG0 | PORTC4 | Reserved, SDA | 17 | JP2(2) |
RFG1 | PORTC1 | Reserved, input | 18 | JP2(3) |
/INIT | PORTC5 | INIT signal, SCL | 20 | JP4(1) |
LED | PORTC6 | Green LED | N/A | N/A |
The signals run at 3.3V, so direct connections to CMOS at 3.3V is straightforward. The required levels for driving TTL also match, but I find it most comfortable, driving the Picotux inputs from open-collector stages, with pull-up resistors to the 3.3V busbar.
The calls to the service function gpio_write() to toggle one of the GPIO outputs takes a minimum of 45 microseconds, more if there is other activity going on. This gives an indication on how fast any approximated "real-time" application can run, and how fast any associated circuitry has to be.
The reset input (pin 14 on the device, JP on the PT112 assembly) stays low for about 1/3 second after power-on before it goes high. This can be used as a power-on-reset(L) signal for other devices in a system.
There is a reference to an i2c interface on the system. However, no-one has been documenting this anywhere, so I will tell about what I found out on a separate, long page.
This is really quite interesting, as i2c circuits are easy to connect, just two bus wires, and several different units can sit on this bus.
I have some projects where I have tried out the Picotuxes, and I get new ideas as time goes on.
One project that is deployed replaces a PC that sat in the garage and controlled relays for the outside lights, the battery charger in the car, and monitored the battery voltage of the car. The Picotux- based unit controls 4 relays and can monitor 8 analog and 4 binary inputs as well as the internal temperature of the case.
Another projects is an investigation into how the Picotux can use the GPIO to communicate and control a slaved 8085 processor, that can handle a larger number of I/O devices.
Typical IO expansion is done by controlling a counter and reading from a multiplexer for input, and shifting bits out into a shift-register for output.
I've also made some circuitry that can invoke a command-line on the serial console when the unit is started or restarted. This is typically a shell script that sets the hostname, gets the time from a known time-serving machine in the network, maybe mounts a NFS disk somewhere, and then starts some kind of server or recording program.
Lately I figured out that instead of having to use some 20-odd ICs for an automated startup function, I can use a PIC16F628A or PIC16F690 to do that entire serial IO job, and which is fast enough for the 38400 Baud of the Picotuxes. The 16F690 is even capable of generating 38400 Baud without an external oscillator, making more pins available for other use. The two PIC16F variants also have the ability to generate PWM signals; there are some comparators and timers, and the 16F690 has a 10-bit A-D converter. An alternate to that would be the PCF8591 connected via I2C, which is just as easy to use here, though only 8 bits. There's also the extension of this idea, so that other information about the PICs counters or events on its interrupt-inputs can be conveyed via the serial lines. The PIC16F690 also can talk I2C.
I haven't tried this yet, as the existing configuration is easy to use and do interesting stuff with. However, it would be useful eventually to have some kind of easily changed startup code, to start some custom server program, announce the IP-address, set the initial time to something other than January 1 1970, hostname to something other than "picotux" (which gets confusing when there are more than one of them on the network) and similar, without intervention on each power-up.
Of course, as I have done in some cases, it is possible to arrange some electronics to feed some serial bits into the shell when it starts, corresponding to a command-line such as /usr/bin/rc, but that does require quite a number of extra additional chips, kinda obviating the advantage of the Picotux' small size. It ends up sitting in a corner of a huge board. Now, when using the PIC16F628A or PIC16F690 as a co-processor, there are fewer extra chips, so this is also less of an issue.
I got the cross-development kit almost working, but it looks like that if I re-flash the devices I will lose the i2c-bus functions. That is not so great, so until I discover otherwise, I'll keep initial configuration of the Picotuxes for now.