Galileo GPIO Timing & why it doesn’t work for some.
The Intel Galileo is has Arduino UNO compatibility, yet often I see queries from someone asking why their favourite Arduino Shield won’t work, or why an interface they have made which works on other Arduino boards, doesn’t work with Galileo. Often they say Galileo is no use, or Galileo doesn’t do what it claims, or Galileo is slow. So why do some Sketches and Shields not work as expected, when using GPIO on Galileo? Read on for the answers…
In order to understand why Galileo is different from other Arduino UNO boards, you need to understand how Galileo is different.
Most other Arduino compatible boards have a dedicated micro-controller onboard, attached directly to the GPIO Pin headers. The Sketches that you write in the Arduino IDE are compiled and run natively on the processor. They have exclusive access to the processor, which runs nothing but the compiled sketch code. The processor runs at a fixed frequency, usually 16 MHz, and every single code instruction that gets executed has completely deterministic timing. Even if interrupts are used for inputs and to get the processors attention, these can be turned off during timing critical sections of the code, such as, for example: communicating with devices; emulating UART; accessing 1-Wire devices; or even sending Infra Red control signals, etc etc.
Galileo however is much more complex. It is based around an SoC (System on Chip) micro-processor, not a micro-controller, and runs an entire operating system. In our case the operating system is an embedded Linux distro based on the Yocto project. The processor runs at a much higher speed, at 400 Mhz and the code you write in the Arduino IDE (or any other editor for that matter) gets compiled and ran on the Galileo as just another process in amongst all the other processes running on the board. The code is abstracted from the hardware through the Linux kernel and your code will get scheduled to run in short time-slices just like every other process. You don’t get exclusive access to the hardware, and you cannot get deterministic timing to do GPIO events. Even when you do use code to toggle GPIO pins, you are not operating directly on the hardware, you are making system calls and asking the kernel to dispatch commands to a device driver which eventually operates the hardware.
In short, the Galileo is a computing system, not a processor. It is similar in architecture to a full blown desktop PC or Mac, and runs a mature operating system just like a desktop PC.
So when you are designing boards to work with Galileo you need to think more along the lines of How would I make this work with a PC? rather than How would I make this work with a micro-controller?
When you need deterministic timing for a device you have to use an interface!
By the way, if you want to know more about how Linux works, there is a fantastic book called The Linux Programming Interface, which has some great chapters on scheduling and timing in Linux programs. I highly recommend that book for anyone working in Linux.
So how do you do it?
The answer, for anything that requires absolute or deterministic timing is simple: Use an interface! And Galileo has a whole bunch of interfaces built right in: there is I2C, SPI, and both client mode USB and host mode USB, there’s a mini PCI-Express interface and a 10/100 Mbps network interface, there are two hardware UARTs, one at true RS232 Levels and one at CMOS logic levels, so take your pick, or build your own.
A real example
Say you wanted to develop a system that could send a specific Infra Red remote control code, in response to some input.
Horses for Courses
You could just knock up something quickly and easily using a small cheap micro such as the PIC12F629, attach a few external components such as a switch, IR Led and a few passives and be done with it. That is exactly what Electronics-Lab did with their “TV Be Gone” gadget. Here is their simple circuit:
That would certainly work. And it that’s all you need, then it would be the right choice. Horses for courses, as they say, use the right tool for the job. There’s no need to throw a complete Linux class PC at this one, a simple solution with a few cheap components gets the job done.
Bigger and Better
But, say you wanted the above, but you’d also like to add a network interface, so you can login form the internet and operate it remotely. Well, now you need something a bit beefier. A PIC12F629 won’t be up to that job! Galileo might be a good choice, since it has both LAN and WiFi network interfaces, and plenty of GPIO to use. So you build your Sketch in the Arduino IDE and implement a network interface, and connect the IR Transmitter directly to one of the GPIO ports. You’ve hard-coded some timing delay loops to toggle the GPIO Pin on and off at about 38KHz. It takes you a while to get the timing for the 38 KHz IR signal right, but eventually you get there. But when you put it into use it has a nasty habit of only working intermittently. You get out your Oscilloscope, or maybe your Logic Analyzer, and find that sometimes the timing for the IR signal is out. It has gaps in the signal and you can’t figure out why. That is because your Sketch is getting scheduled to run by the Linux Kernel scheduler and getting de-scheduled so other processes can run too, like for example the network stack. These interruptions occur at unpredictable moments, and will with all likelihood happen during your delay loops. This gives you non-deterministic timing, but an IR signal needs very precise timing, in other words it needs deterministic timing. Maybe “kinda works” is good enough though. If so, job done!
Biggest and Best
In the Galileo example above, we’ve forgotten what I said:
“So when you are designing boards to work with Galileo you need to think more along the lines of How would I make this work with a PC?, rather than How would I make this work with a micro-controller?”
We’ve connected the IR Transmitter to the GPIO lines and tried to drive it directly, with explicit timing. You couldn’t do that with a desktop PC, so we shouldn’t be doing that with Galileo. The best solution would be to take the PIC12F629 schematic above, or something similar, build it onto a small board, and attach that to the Galileo. Now you are using an interface! We can use GPIO lines in place of the switches, because they do not need deterministic timing!
This solution will work reliably every time. If you add more complexity to the system, say with more sensors, or a display, or whatever, the IR Transmitter will still continue to work every time.
- The Galileo is a computing system, not a processor.
- Code on Galileo gets scheduled and de-scheduled in small time-slices.
- For anything requiring precise timing, use an interface!
- Use the right tool for the job, don’t use Galileo just because it is “Arduino Compatible”.