This will be mostly about software. I’ll try and describe the process I followed to turn a smartphone into a soft-real-time vehicle controller.
So, how do you turn this:
First I removed all the plastic covers and internal accessories that I didn’t need. It’s going to have its own box and a few new wires anyway. The phone battery is unnecessary because it will be fed via USB from the main vehicle battery through a DC-DC 5 Volt “buck” converter. Then I added an RS-232 to USB converter from Sparkfun; it’s cheap and converts the 3.3V RS-232 debug serial port of the GTA02 into a USB virtual serial port that any decent computer can talk to. Both boot loaders of the GTA02 (“Qi” and “U-boot“) have serial console support, and U-Boot even lets you test the hardware. This is probably the most important accessory you can have attached to a processor board: without it you won’t be able to find out why the heck it doesn’t boot when it doesn’t boot. It’s also a good ally when you realise you’ve just knocked out all the network interfaces and you can no longer SSH into the device. Glue it onto the GTA02 board and solder the Ground, Rx, and Tx lines. Power comes from the USB plug. No, it can’t power the GTA02 too.
My main preoccupation was to set up a development platform that was very fast and easy to develop upon, and yet still allowed for near real-time performance – I’d like to be able to do at least 10 input/computing/output cycles per second. Nowadays the interpreted languages (Perl, Python, Java, etc.) run quite easily on a 400MHz processor like the GTA02 has, so that was my general intention. Interpreted languages do not require compile time or installation, and so I can develop the code directly on the target system without the need for a cross-compilation environment on a workstation.
At the time I started the project, the most complete and flexible Linux distribution for the GTA02 was SHR-Unstable (in my opinion). It’s actively being developed and it’s got a bunch of pre-compiled software packages that we can download and install directly into the target device with a simple “opkg install …” command, as long as it’s connected to the internet. Connecting to the internet is also easy to do, whether by USB or Wifi.
Of course, the SHR-U distro has all kinds of bells and whistles that make it appropriate for everyday usage as a telephone. I picked a few significant targets and “opkg remove …” all the graphical, PIM, and telephone applications. No worries there, Linux package managers are far superior to that other popular operating system on which the uninstallers always leave a trail of bread crumbs the size of elephants.
The SHR and FSO daemons, as much as I admire them, had to go too; I need all the CPU to myself. And I also don’t need power management software creating “funny” behaviours in my target system. So, after all this, I got a clean system just waiting for my commands. In idle state, “htop” consumes around 10% of the CPU time.
It’s time to install the software packages I need. I settled on developing with the Python language because it is easy, fast, powerful, and the native interpreter is already part of the distro. It’s got a large bundle of extra modules that can be installed, namely the all-important “PyGame” module that greatly simplifies the building of near-real-time applications (like games). It saved me the work of writing a USB Joystick device library in Python.
You can get the full customization script for the SHR-U image from my project’s repository.
After setting up the GTA02, I developed my project’s applications right there on the target. It’s quite practical; I connect to the GTA02 via Wifi ad-hoc and just use SSH to send console commands or edit files remotely (Debian systems using the Gnome graphical system have direct integration of SFTP in the Nautilus file explorer). Couldn’t be simpler. No compilations, flashings, downloads, or installations. Just open the file remotely on your laptop, change it, save it, and restart the application on the target: voilà, you can see the new version running.
Here you can see the process list in “htop” with the current version of my software running.
You can see there are 6 processing threads in this Python application called “sb2.py”. They are: the main thread (which runs the endless computing cycle), the LED blinking thread, the GPS input thread, the Accelerometer input thread, the Telemetry server thread, and the PyGame event pump thread. The motor power controller communications don’t need a thread because they are polled from the main thread. You can also see that the entire application currently only uses about 6% of the CPU time, although that doesn’t account for the kernel time that is used because of it. And that the “niceness” number (the relative processing priority) has been set to -10 to confer a higher priority of this application over everything else running in the system.
The whole software chain is composed of:
- An “/etc/init.d/” service daemon (written in Bash) that tweaks the system and then launches the main application on boot-up;
- The main Python application;
- Several Python modules that help deal with devices and such.
The first tests I did with NJay’s micro-controllers connected to the GTA02 revealed that each I²C read/write system call was taking more than 20ms. Since I needed to make at least a dozen of them per cycle, it would be impossible to have 10 cycles per second. After much measuring and researching, I found that the linux kernel was to blame, and that the patch for this problem had already been submitted over a year ago. So I upgraded to the latest experimental kernel in SHR-U and problem solved: each I²C access is actually faster than 1ms.
Or not. Sometimes an access gets delayed by about 20ms again. The I²C bus is shared between 2 other things on the GTA02: the “Wolfson Codec” (a.k.a. the sound card) and the PCF50633 (a.k.a. PMU – Power Management Unit). And the PMU issues one interrupt per second which is serviced by the Linux kernel because that chip is where the RTC (Real Time Clock) of the system is. So once a second, there is a train of large data bursts between the kernel and the PMU, and it was spoiling my average and made my application’s math more difficult.
So to shut up the unnecessary chatter on the bus, I removed all the kernel modules that had anything to do with sound, and reprogrammed the PMU’s interrupt controller to stop issuing the “every second interrupt”. At last, I²C silence! This configuration has to be done after every boot up. It soon became obvious that a custom made boot-up script was necessary to configure the GTA02 just right: from network interfaces to accelerometers and USB, passing through PMU and GPS, all the start-up configurations are done there. One of the things I do is to send a bunch of configuration files written in binary format to the GPS device; this makes it less NMEA-verbose and cranks up the speed to 4 samples per second. I may even use file storage for “Assisted-GPS” fast start one of these days.
Well, that’s it, folks. Use and abuse at your own discretion and responsibility, all the code (including set-up scripts) is in the repository.