This section describes the software installed in the Master. This device is in charge of turning on/off different components as well as supporting the software updates and addresses assignments.

GPIO’s initial configuration

The Linux kernel for Raspberry Pi 2 makes use of device tree block. The default configuration for some GPIO pins is not what we need because they are initialized in output mode and sending 0. This means that by default the stacks connected to such GPIO pins would be on when the master starts. To change this behavior, we can either compile a complete device tree block or define an overlay to override the default device tree block. We recommend the second approach. Below, you will find the source code for this overlay. It simply sets all GPIOs to in mode and pull mode none. To compile this overlay, read device-tree

/dts-v1/;
/plugin/;
/ {
    compatible = "brcm,bcm2835";

    fragment@0 {
        target = <&gpio>;
        __overlay__ {
            auto_pwrsup: auto_pwrsup {
                brcm,pins = <17 27>; /* gpio pins */
                brcm,function = <0 0>; /* boot up direction:in=0 out=1 */
                brcm,pull = <0 0>; /* pull direction: none=0, 1=down, 2=up */
            };
        };
    };

     fragment@1 {
        target-path = "/soc";
        __overlay__ {
            gpiopull:gpiopull {
              compatible = "gpio-poweroff";
              pinctrl-names = "default";
              pinctrl-0 = <&auto_pwrsup>;
              status = "okay";
           };
        };
     };
};

In order to install this overlay, you only need to add the following line to the file config.txt in the boot partition of the MASTER PI.

dtoverlay=

Enabling I2C

On the master you have to enable both I2C buses. At least on raspbian, it’s really easy to do, simply edit /boot/config.txt

dtparam=i2c=on
dt-overlay=i2c0-bcm2708

Stack addresses

Each stack should have an unique address by bus. This address is configured through jumpers (noted A0, A1, A2) and the bus is configured via 2 jumpers (on the other side of the board named SDA/SCL). Note that the bus is selected by theses two jumpers, both jumpers should be in the same direction (0 or 1).

Warning: If you enable power meters, A1 should be 0. This limits the number of stack to 4 by bus (48 Slave maximum).

Enabling serial communication (UART)

UART pins are provided on each stack but only the one with a master on it is usable. Moreover you should enable this feature on /boot/config.txt

# Enable UART
enable_uart=1
# force_turbo=1

Scripts to turn on/off different components in the cluster

A library to access the different sensors using the I2C bus is under development.

The code below is used to test the library and the PCB. So far we don’t have a complete application to use the cluster, but creating such application using our library and this example as base case should relatively easy.

#!/usr/bin/env python

import logging
logging.basicConfig(level=logging.INFO)
from grape import *
from RPi import GPIO

for i, s in stacks.items():
    print("STACK: {0:o} {1}".format(i, s.devices))

STACK = 011
if STACK in stacks:
    stacks[STACK][PowerSwitch].stop_all()
    print(stacks[STACK][PowerSwitch].status())
    stacks[STACK][PowerSwitch][0] = True
    print(stacks[STACK][PowerSwitch].status())
    print(stacks[STACK][Temperature].get())
    print(stacks[STACK][PowerMeter].current())
    print(stacks[STACK][PowerMeter].voltage())
    print(stacks[STACK][PowerMeter].power())

if display is not None:
    display.btn_handler = ButtonPrinter()

    for i in range(5):
        display.led(Display.RED, i % 2 == 1)
        display.led(Display.GREEN, i % 2 == 0)
        sleep(.3)

    display.clear_screen()
    display.print_str("Hello grape ...")
    display.home(1)
    display.print_str("Bye")
    while True:
        sleep(.01)
        display.interrupt(INTERUPT_PIN)

Additional software requirement

The workers use TFTP during boot time to decide whether an update of the system is needed; hence, the master must also provide a TFTP server.

This TFTP server must provide the following files:

  • image (copy.img.gz)
  • checksum of image (image_crc32.txt)
  • upgrade script (quick_fix.sh)
  • checksum of upgrade script (quick_fix_crc32.sh)

If you want to use the scripts provided in this website without modifying them, you must enforce a static IP address in the master 192.168.0.13, and the DHCP server must offers addresses above 192.168.0.15.

Updating the workers

Turn off the workers you want to update. The network switch, the TFTP server and the DHCP server must be running. Suppose that file grape-agent.img represents the SDCard you want to have on each worker. The following command:

fdisk -l grape-agent.img

produces:

Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0009bf4f

Device           Boot  Start      End  Sectors Size Id Type
grape-agent.img1        8192   129023   120832  59M  c W95 FAT32 (LBA)
grape-agent.img2      133120   155647    22528  11M 83 Linux
grape-agent.img3      262144 17039359 16777216   8G 83 Linux

The first partition is boot, the second partition is Tiny Core and the third partition is Raspian. Usually you one to update the third partition. So you must mount it as a loop device and copy its content to a file. Finally, use commands gzip to produce file copy.img.gz and crc32 to produce file image_crc32.txt.