BeagleBoard Black (BBB) and GPIO

When you buy a Beagleboard Black (a.k.a. BBB), it comes with a pre-installed version of debian with more or less everything you need to get started. I purchased the board for another purpose and develop seL4 components on top of it. But before starting to develop on seL4, it is useful to know exactly how the board works: once you know how the board works, you can start to write your code and know for sure that the bug comes from your code.

In this article, I will explain quickly how to set up a simple circuit to test the GPIO of the beaglebone.

cape-headers-digital.png
Mapping between pin numbers and GPIO ID from bone 101

Setting up the circuit

To test the circuit, you need only a breadboard, a resistance and a LED. Simple.

Connect the PIN 14 (which is mapped to GPIO id 50, see table) from bank P9 (green cable on the picture) on the breadboard. Connect it to a resistance and a LED. The other pin of the LED is then connected to the ground (last PIN of P9).

board
Wiring scheme of the example

 

Controlling the GPIO in Linux

In Linux, the GPIO can be controlled using the SysFS abstraction layer. You can access it through /sys/class/gpio. I am using the pre-installed debian software on the board.

To control a particular pin, you must export it. You do it by writing the value of the pin you want to export into /sys/class/gpio/export. Then, a new directory is /sys/class/gpio/gpio<PIN-NUMBER> is created with many different files to control the pin (direction, value, etc.).

In our example, the pin 14 from the bank P9 correspond to GPIO 50. You can see the corresponding mapping between the pin and GPIO number in the beaglebone 101 document.

So, let’s start by exporting this pin:

echo 50 > /sys/class/gpio/export

Then, a new directory /sys/class/gpio/gpio50 is created.

Let’s set its direction to out

echo out > /sys/class/gpio/gpio50/direction

And let’s set its value to 1

echo 1 > /sys/class/gpio/gpio50/value

 

And finally, if you want to make the LED blinks every second, you can use this command:

while [ 1 ]; do echo 1 > /sys/class/gpio/gpio50/value ; sleep 1 ; echo 0 > /sys/class/gpio/gpio50/value ; sleep 1 ; done

 

 

Sources

BeagleBoard Black (BBB) and GPIO

Xmas homework(s)

Among the joy of being an expatriate is that you do not have to go in your family and take advantage of this holiday period to rest, do some personal projects and dedicate time to things you wanted to do.

Since the last couple of days, I am trying to use SeL4, a security-oriented kernel that has been formally proven. Sounds sexy, right? For now, I am not quite sure to fully understand how it works and the development environment is huge. It reminds me my old days, when working on taste that requires a full virtual machine just to work. Ah, the joy of development environments that are designed like a Russian jail, so convenient and easy to use!

The goal of this project is to be able to generate SeL4 secure applications from architecture models (mostly AADL). The high-level security requirements would be verified at the model level and would ultimately be transformed into code. This is what I am trying to do during this holiday period.

I am also trying to train for Worlds Ends 100 that will take place in May. Some friends have been there last week-end and told me the course is challenging and intense. As there is an aggressive 19 hours cut-off, I need to work my ass right now in order to finish the race on time. Unfortunately, I do not have the opportunity to train on the course and all I can do is mimic the elevation profile in the parks around Pittsburgh.

On a side note, I am now an official pacer for the Pittsburgh Half-Marathon. If you are running the half and plan to finish in 1:45, I will be around you.

The weather in Pittsburgh is still surprisingly hot. More than 16C.

Happy Holidays.

Xmas homework(s)

It is an architecture problem

The big news today (that got my attention!) is the Washington post about Linus’ thoughts on security, especially in the linux kernel.You probably do not know but today, Linux is one of the most used kernel in the world. Every Android device rely on it – most of non-critical embedded devices use it. You are probably not aware of it but you are probably using more Linux-powered devices than Windows or Mac.

The article is well written and explain most of the issues to a non-technical people. Great. But sometimes, it messes things up. For example, when the article reports that the ashley madison data breach, it is totally unrelated: the article focuses on the kernel, not the userspace. This is just not accurate to connect this attack with the linux kernel, it could happen with the same software running on a different kernel.

What users must understand is that security comes at a cost and while this is an important requirement for us, this is not the most critical and people do not pay attention to it until a big attack appears. Achieving high security impact other requirements and characteristics, such as performance. At the end, the question is: are you willing to have your system running slower to protect yourself against a potential security attack against your contact list that has not been discovered yet and would be fixed as soon as it is discovered?

Are you willing to pay the cost of security without affecting other attributes?

It totally depends on your objective and priorities: if your system is a smartphone, you probably do not care because once discovered, the attack will be fixed and your phone will be automatically upgraded. But if you design a nuclear power plant, there is no room for a second chance, millions of people are already dead. So, you do not want that to happen at any cost.

Linus made a good point on that as well: if you are running a safety-critical system, you just do not use Linux. If you are concerned about the security of Linux, solutions exists (e.g. selinux, grsecurity). And if tomorrow the kernel needs more security, the community will work the existing kernel and add the necessary layers – this is just that it has not been the focus so far or has been done through individual efforts. But at the end, if you really want to isolate software according to their criticality, this is no longer a matter of code but an architecture concern: you have to design your system and isolate components according to their security levels. Many existing approaches address that issue (for example, MILS) and there are many solutions to such design: gatekeepers (filtering insecure data before they are forwarded to the secure components), physical or logical separation, etc.

This is also what has been shown by the attack on the Jeep by Miller and Valasek: the entertainment system is connect to several networks connecting critical and non-critical devices without any filtering. By attacking the entertainment system, attackers were able to control a car from their couch. Great. Some will argue this is a software issue but I am still convinced this is an architecture issue: the entertainment system should not be connected to critical equipment without any filtering or protection mechanism.

The Washington post article is interesting but the whole discussion on the Linux kernel is just too much. Rather than putting the fault of an insecure Internet on linux developers, it would rather be more interesting to understand the real architecture defects of the network. And why people choose such insecure software: if Linux is so bad, why is it still soused? There are still many open questions but this article demonstrates how cybersecurity is not understood and addressed today, in our now over-connected world.

It is an architecture problem

Change takes time

When multi-core processors were released in the mid-2000s, developers had to face a new programming paradigm: multi-threading. For sure, SMP (Symmetric Multiprocessing) was already there since years but such machines were dedicated to particular applications.

This new processor design had some side effects: since applications were no longer executed on a single processor and developers had to synchronize shared data and avoid what we call race condition. Interestingly,  most of the time, a race condition will crash the application. When multi-core processors were introduced, many popular applications had such issues (see this discussion for iTunes) – mostly because developers did not design an application with synchronization constraints in mind. Of course, now, this design constraints is understood by most developers.

During a current project, I am investigating the common software vulnerabilities/weaknesses and their evolution over time. Among the most popular, the “race condition” issue. There is the picture.

number of issues related to synchronization issues
Number of issues related to synchronization issues

If we look closely, there was very few reports until multi-core were introduced. It continues to increase until 2012 (why it decreases in 2011 is still unknown) and then start to decrease. Interestingly, there are still a lot of issues related to synchronization today.

The take away from this data? Change takes time. A. Lot. It took almost 10 years for software developers to address the matter and stop writing buggy code. And there are still a lot of reported issues. Developers had to take this new constraint into account while they were not familiar with this paradigm. Teachers had to explain this issue and address the matters in class.

Change takes time and it is very difficult to predict the impact of a change – I assume nobody assumed that it would take so long for the industry to adapt to this new constraint.

Change takes time

How to get geocoding information in Java without Google maps API?

For some project, you might want to use geocoding information, which means get the GPS coordinates from an address. If you want to use Google services, you are limited to a certain number of requests but your usage is connected with your account. There is a nice geocoding API available but

You might want to have as many requests as you want but also avoid Google to look at your applications are doing. After all, these requests are sent by the users of your own application, not you.

So, yes, sure, there is a nice geocoding API available with Google. But it seems to be restricted/limited. So, let’s not use it. The alternative is to use the open website OpenStreetMap (a.k.a. OSM), which has a webservice to get geocoding information. It does not provide a full Java API but rather the data in a JSON or XML fornat. So, all we have to do is to write a Java API what issue requests to the webservice and retrieve the geocoding information from the JSON/XML.

I chose to get the information with the JSON format, this is pretty easy to use. To parse the JSON data from the service, I use json-simple available on maven.

Getting the geocoding data

Basically, the code issue a request to the geocoding webservice from OpenStreetMap, get the result and convert it into a JSON object. It then get the latitude/longitude information from the JSONObject.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;

public class OpenStreetMapUtils {

    public final static Logger log = Logger.getLogger("OpenStreeMapUtils");

    private static OpenStreetMapUtils instance = null;
    private JSONParser jsonParser;

    public OpenStreetMapUtils() {
        jsonParser = new JSONParser();
    }

    public static OpenStreetMapUtils getInstance() {
        if (instance == null) {
            instance = new OpenStreetMapUtils();
        }
        return instance;
    }

    private String getRequest(String url) throws Exception {

        final URL obj = new URL(url);
        final HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        con.setRequestMethod("GET");

        if (con.getResponseCode() != 200) {
            return null;
        }

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        return response.toString();
    }

    public Map<String, Double> getCoordinates(String address) {
        Map<String, Double> res;
        StringBuffer query;
        String[] split = address.split(" ");
        String queryResult = null;

        query = new StringBuffer();
        res = new HashMap<String, Double>();

        query.append("http://nominatim.openstreetmap.org/search?q=");

        if (split.length == 0) {
            return null;
        }

        for (int i = 0; i < split.length; i++) {
            query.append(split[i]);
            if (i < (split.length - 1)) {
                query.append("+");
            }
        }
        query.append("&format=json&addressdetails=1");

        log.debug("Query:" + query);

        try {
            queryResult = getRequest(query.toString());
        } catch (Exception e) {
            log.error("Error when trying to get data with the following query " + query);
        }

        if (queryResult == null) {
            return null;
        }

        Object obj = JSONValue.parse(queryResult);
        log.debug("obj=" + obj);

        if (obj instanceof JSONArray) {
            JSONArray array = (JSONArray) obj;
            if (array.size() > 0) {
                JSONObject jsonObject = (JSONObject) array.get(0);

                String lon = (String) jsonObject.get("lon");
                String lat = (String) jsonObject.get("lat");
                log.debug("lon=" + lon);
                log.debug("lat=" + lat);
                res.put("lon", Double.parseDouble(lon));
                res.put("lat", Double.parseDouble(lat));

            }
        }

        return res;
    }
}


Testing the service

Then, to use the service, you can just use a main program like the following code.

public class GetCoordinates {

    static String address = "The White House, Washington DC";

    public static void main(String[] args) {
        Map<String, Double> coords;
        coords = OpenStreetMapUtils.getInstance().getCoordinates(address);
        System.out.println("latitude :" + coords.get("lat"));
        System.out.println("longitude:" + coords.get("lon"));
    }
}

 

Checking

When running the previous example, the program prints the following information:

  • latitude :38.8976989
  • longitude:-77.036553192281

Let’s then check where are these coordinates! When putting the coordinates on Google Maps, I then got the following map. Sounds like it works!

coordinates

How to get geocoding information in Java without Google maps API?