Thursday, 19 May 2016

Raspberry Pi Media Centre

I have a love-hate relationship with our Raspberry Pi based Kodi Media Centre. On one hand it's cheap as chips and streams all the TV shows we could want (while not being a television) but on the other it's prone to regular heart-attacks when its SD card has been written too much.

I have been in the habit of backing it up religiously every month and have been rewarded by its dying every six months or so. Time to hack some Linux!

(It goes without saying that what follows is merely an optimization of the excellent work done by Sam Nazarko on Raspbmc, now OSMC.)

First thing is to disable Kodi logging entirely. Do this by creating a file /home/pi/.kodi/userdata/advancedsettings.xml:

<advancedsettings>
  <loglevel>-1</loglevel>
</advancedsettings>

Second of all: tmpfs. First we connect the various other temporary directories to /tmp:
$ sudo rm -rf /var/tmp
$ sudo ln -s /tmp /var/tmp
$ rm -rf /home/pi/.kodi/temp
$ ln -s /tmp /home/pi/.kodi/temp

Next we overlay a couple of tmpfs filesystems over /tmp and /var/log (where all of the system daemons write their logfiles). Add the following lines to the end of /etc/fstab:

tmpfs           /tmp            tmpfs   defaults,noatime,nosuid,size=50m    0   0
tmpfs           /var/log        tmpfs   defaults,noatime,nosuid,size=50m    0   0

This creates a couple of ram-disks each limited to 50MB in size. They won't use this RAM unless it's required and if it fills up (it hasn't for me yet) a reboot will start again from scratch.

Useful tools for monitoring disk usage are iostat and fuser (the latter is in the psmisc package). Another is the humble find, for example to see all files modifed within the last day:

$ find /home -mtime 0       
/home/pi
/home/pi/.kodi
/home/pi/.kodi/userdata/Thumbnails/b
/home/pi/.kodi/userdata/Thumbnails/b/b1726aa3.jpg
/home/pi/.kodi/userdata/Thumbnails/b/b8b95467.jpg
/home/pi/.kodi/userdata/Thumbnails/b/b34fab01.jpg
...

Hmmm, looks like there's still some work to do here! Let's move the thumbnails to /tmp too:

<advancedsettings>
  <loglevel>-1</loglevel>
  <pathsubstitution>
    <substitute>
      <from>special://profile/Thumbnails/</from>
      <to>/tmp/Thumbnails</to>
    </substitute>
  </pathsubstitution>
</advancedsettings>

Now that thumbnails are being stored in /tmp, we need to clear them out every so often to avoid filling it up. Add this line to your crontab, with "crontab -e":


0 5 * * mon find /tmp/Thumbnails -type f | xargs rm -f




This will remove all thumbnails every Monday at 5am.



Update: Hackaday just ran a story on Preventing Flash Memory Corruption containing many useful tips; the most relevant one not covered here is filesystem commit interval. By mounting the root filesystem as follows (/etc/fstab again), Linux will flush its buffers to the SD card every 5 minutes instead of every 5 seconds by default:



/dev/mmcblk0p2  /               ext4    defaults,noatime,commit=300 0       0


This is a quick win because frankly who cares if a write recording the fact you watched an episode of Futurama is lost for a potential 60x reduction in the number of writes? Not me!

Monday, 19 October 2015

The Dining Philosophers

It seems as if this blog has been veering towards software for a while now, and this post is about as far from hardware as it's ever been --- but hey, it has LEDs!

The problem of the Dining Philosophers was first described by Dijkstra in 1965 as an example of resource allocation in concurrent (operating) systems. Briefly, five philosophers sit around a table with a bowl of spaghetti in the middle, spending their time alternately thinking and eating. There are five forks at the table, one between each philosopher, and in order to eat, a philosopher requires those adjacent to him.

Two important properties to be addressed by a solution to the problem are: safety and liveness. The first means that the solution is free from deadlock while the second requires that every philosopher eventually gets to eat. There are many solutions but the one implemented here is that proposed by Dijkstra himself: freedom from deadlock is ensured by introducing an asymmetry: the lowest numbered philosopher reaches for his right-hand fork first while the others reach for the fork on their left.


In the solution, each Philosopher is implemented as a Task and each fork as a Semaphore.

Tasks are non-preemptive, light-weight threads of control, they run until they call a blocking function, for example waiting on a Semaphore or sleeping for some time.

There are two kinds of task, the implicit one which runs setup() and loop(), and explicit ones which inherit from class Task and must provide their own stacks, here, 50 words.

In the example, the main setup() initialises the Task system and starts the explicit tasks; it then implements the behaviour of Philosopher #4 in its loop().



In the video, red LEDs indicate a thinking philosopher and green ones a philosopher eating spaghetti.

As always, the Task library is available on Github for Arduino and Energia.

Sunday, 11 October 2015

mspdebug

When it comes to debugging programs, the first tool in my toolbox for compiled languages like C or C++ is usually 'print'. I don't tend to bust out a debugger unless I'm in an IDE such as IntelliJ.

This can pose problems for me in a relatively print-challenged environment, such as msp430 on Linux. Last night I had found myself in just this situation when I found myself musing on why the msp430 upload tool was called mspdebug. A quick search found a nice manual and a few minutes later I was debugging away.

Here's a sample transcript:

With the sketch already uploaded to the board, this script shows how to:

  • Generate a name-list from the sketch's Elf file
  • Import these symbols into the debugger
  • Set a breakpoint by name in the program
  • Run the sketch up to the breakpoint
  • Single-step the program once the breakpoint has been reached.
If you're interested, the sketch is a rather convoluted version of Blink.

Saturday, 29 August 2015

Simple Breadboard Power Supply

It's very satisfying to build something for which you've all the parts to hand, there's no waiting around, just immediate gratification. This little build is such a thing. It's a dual-voltage (5v and 3.3v) power supply which plugs into a breadboard and is handy for projects which aren't powered from a USB tether (e.g., wireless microcontroller prototypes or projects which don't use a microcontroller at all, hard as that might be to believe).



It's loosely based on the circuit below, although I used different values for the capacitors, having first done a bit of research to discover that the 100nF ones are used to filter high-frequency noise. If I have problems with that in the future I'll add them.

Monday, 11 May 2015

Interrupted

Interrupted is a new approach to developing low-power, low-latency Arduino sketches, which was motivated by two observations:
  • That the default mode of programming for Arduino is busy-waiting, and
  • The runtime support for power management provided by avr-libc is basic, being charitable to it.
Taken together, these two points mean that Arduino sketches aren't easily battery-powered, while the second results in a cargo-cult of code copying. Lastly, timed sleep in Arduino is provided by delay(), which itself is busy-waiting. This increases latency, the response time to external events such as button-presses.

And so to an example; the sketch below manages a very simple hardware configuration composed of an ATtiny85, an LED and a button: the button turns the LED on and a timer turns it off again. (You could imagine such a sketch driving a Useless Machine.)

In the main loop, the CPU sleeps in select(), waking up when an event occurs on one of the devices it manages. Three events are possible here:
  • An external interrupt which occurs when the button drives pin PB2 low,
  • A pin-change when the LED on PB0 is turned on or off,
  • When the watchdog timer fires, one second after the LED comes on.
The value returned from select() indicates which event has woken it up, allowing the concise construction of state-machines. If more than one event source is ready, the one added earlier in setup() is returned, implementing a crude form of priority.

The sleep-mode entered by select() is the maximum which makes sense for the devices currently active. In this little example, SLEEP_MODE_PWR_DOWN will be chosen because external and watchdog interrupts still work in this mode.

Much credit is due to Nick Gammon, for the great work contained in his Interrupts and Power Saving Techniques for Microprocessors forum-pages.

Very similar techniques were employed in the runtimes of the Conic and Regis environments developed at Imperial College (as well as the select system call, of course).

The library has been ported to ATtiny84, ATtiny85 and ATMega328 processors and is, as always, at GitHub. Its code footprint varies, depending on the functionality required by individual sketches, but the little example above comes in at 2.5kB.

Work remains to be done on this library including porting it to Energia (i.e., the msp430 family), porting existing sketches to use it and completing the repertoire of supported devices (e.g., SPI handling).

Wednesday, 11 March 2015

A tiny ATtiny

Very tiny!
 Recently I was surprised to discover that although I've made several projects using one, I'd never built a development board around the ATtiny85. With any project there are always design choices and a couple of important ones here were:
  • Is a breadboard optional or required? If optional, you get the familiar Arduino form-factor, which can either be connected to a breadboard using jumper cables or populated with pre-built shields.
  • Design a PCB or something more ad hoc? I wanted something quickly --- I wasn't going into competition with the Teensy or Trinket.
  • If not designing your own PCB, use stripboard or protoboard? While I've never been a huge fan of protoboard, because you're basically making your own strips by blobbing solder across pads, you can get quite a high component density with it.
So I opted for the path not taken, requiring a breadboard and using protoboard, and the result is pictured above. Notice that protoboard allows the FTDI connector to be attached at right-angles to the chip (try that with stripboard!) and also exposes more of the breadboard for jumper cables (the 10k resistor connecting reset and Vcc is underneath the chip).

With the ever-useful Tiny-Safe-Boot bootloader and a bespoke entry in my arduino-tiny's boards.txt file, it's as easy as regular Arduino, at a fraction the cost!

Thursday, 19 February 2015

TinySensor Server

Well after almost a year I decided it was time to update this project with improvements to both its hardware and software.

On the hardware side, the server is still the original Raspberry Pi model B, but I've mounted the nRF24L01+ radio on a neat little Slice of Pi board. (These boards also have traces for mounting XBees with their unusual pin spacing. And they're cheap!)

The Slice of Pi board (left) with radio and status LEDs
While I had the soldering iron out, I added a couple of status LEDs (see picture). The green one indicates recent activity on the radio, while the red one indicates a timeout but also flashes every time a packet is received. Both of them are driven by a single GPIO line on the Pi. (This was motivated by the radio cutting out on the Pi, probably due to the original Heath-Robinson jumper cable arrangement, and since its transplant it's behaved perfectly.)

On the software side, there are now quite a few little daemons, each doing one thing well:
  • A wireless hub, running RF24-rpi, sends packets received on a TCP socket,
  • A wired hub, running remotely, polls a legacy 1-wire sensor network and sends its readings on another TCP socket,
  • A multiplexor, connected to the two data sources above, sends their streams to its connected clients, described next,
  • A MySQL client writes readings to a database,
  • A status client manages the LEDs described above,
  • An RRD client maintains a round-robin database,
  • An lcdproc client updates a wireless LCD display.
All of these are, as usual, on GitHub.

Future software components planned for this system include a simple weather service to inject local weather data into the stream, and a client for one of the various IoT services now becoming widespread. (Here is a fairly recent overview of some of these.)