Stephen Smith's Blog

Musings on Machine Learning…

Posts Tagged ‘gcc

C Programming on the Raspberry Pi

with 2 comments

Introduction

I blogged on programming Fortran a few articles ago, this was really a tangent. I installed the Code::Blocks IDE to do some C programming, but when I saw the Fortran support I took a bit of a side trip. In this article I want to get back to C programming on the Raspberry Pi. I’ve been a C programmer for much of my professional career starting at DREA and then later on various flavours of Unix at Epic Data and then doing Windows programming at a number of companies including Computer Associates/Accpac International/Sage. I’ve done a lot of programming in the object oriented extensions to C including C++, Java, C# and Objective-C. But I think at heart I still have a soft spot for C and enjoy the fun things you can do with pointers. I think there are a lot of productivity benefits to languages like Java and C# which take away the most dangerous features of C (like memory pointers and memory allocation/deallocation), I still find C to be very efficient and often a quick way to get things done. Admittedly I do all my programming these days in Python, but sometimes Python is frustratingly slow and then I miss C.

In this article we’ll re-implement in C our flashing LED program that I introduced here. We’ve now run the same program in Python, Scratch, Fortran and C. The Raspberry Pi is a great learning environment. If you want to learn programming on very inexpensive equipement, the Raspberry Pi is really excellent.

GCC and C

The Gnu Compiler Collection (GCC) is the main C compiler for Linux development and runs on many other platforms. GCC supports many programming languages now, but C is its original and main language. The GCC C Compiler implements the 2011 C language standard C11 along with a large collection of extensions. You can define compiler flags to enforce strict compliance to the standards to improve portability, but I tend to rely on GCC portability instead. A number of the extensions are very handy like being able to define the loop variable inside a for statement which is a feature from C++.

Code::Blocks

Although you don’t need an IDE to do C development, you can just edit the source files in any text editor then use GNU Make to do the build. Then run the GNU Debugger separately to do any debugging. But generally it’s a bit easier to use an IDE especially for debugging. Code::Blocks is a popular IDE that runs on the Raspberry Pi (and many other things), it’s fairly light weight (certainly compared to Eclipse, XCode or Visual Studio) and has all the standard IDE features programmers expect.

A number of people recommend programming on a more powerful computer (like a good Mac or Windows laptop) and then just transferring the resulting executable to the Pi to run and test. For big projects this might have some productivity benefits, but I find the Pi is up to the task and can quite happily develop directly on the Raspberry Pi.

Accessing the GPIO

From C you have quite a few alternatives in how to access the GPIO. You can open /dev/mem and get a direct memory mapping to the hardware registers. This requires running as root, but it is more direct. I’m going to go the same route as I did for the Fortran program and use the easier file access from the Raspbian GPIO device driver. This one works pretty well and doesn’t require root access to use. A good web page with all the ways to access the GPIO from various languages including C is here. If you want to see how to access GPIO hardware registers directly, go for it. Like the Fortran program I needed a delay after opening the main devices file and before accessing the separate file created for the GPIO pin. There seems to be a bit of a race condition here that needs to be avoided. Otherwise a fairly simple C program and accessing the GPIO is pretty standard as accessing Linux devices go.

C Code

Here is the C code for my little flashing lights program. Three source files main.c and then gpio.h and gpio.c for the gpio access routines.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include “gpio.h”

int main()
{
   int i;
int sleepTime = 200000;

   if (-1 == GPIOExport(17) ||
        -1 == GPIOExport(27) ||
        -1 == GPIOExport(22))
   return(1);

   // Necessary sleep to allow the pin
   // files to be created.
usleep(10000);

   /*
    * Set GPIO directions
*/
if (-1 == GPIODirection(17, OUT) ||
        -1 == GPIODirection(27, OUT) ||
        -1 == GPIODirection(22, OUT))
       return(2);

   for ( i = 0; i < 10; i++ )
   {
        if (-1 == GPIOWrite(17, HIGH))
             return(3);
       usleep(sleepTime);
if (-1 == GPIOWrite(17, LOW))
            return(3);
       if (-1 == GPIOWrite(27, HIGH))
            return(3);
       usleep(sleepTime);
if (-1 == GPIOWrite(27, LOW))
            return(3);
       if (-1 == GPIOWrite(22, HIGH))
            return(3);
       usleep(sleepTime);
if (-1 == GPIOWrite(22, LOW))
            return(3);
   }
return( 0 );
}

// gpio.h

#define IN  0
#define OUT 1

#define LOW  0
#define HIGH 1

extern int GPIOExport(int pin);
extern int GPIOUnexport(int pin);
extern int GPIODirection(int pin, int dir);
extern int GPIORead(int pin);
extern int GPIOWrite(int pin, int value);

/* gpio.c
 *
* Raspberry Pi GPIO example using sysfs interface.
* Guillermo A. Amaral B. <g@maral.me>
*
* This file blinks GPIO 4 (P1-07) while reading GPIO 24 (P1_18).
*/

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include “gpio.h”

int GPIOExport(int pin)
{
#define BUFFER_MAX 3
    char buffer[BUFFER_MAX];
    ssize_t bytes_written;
    int fd;

    fd = open(“/sys/class/gpio/export”, O_WRONLY);
    if (-1 == fd) {
         fprintf(stderr, “Failed to open export for writing!\n”);
         return(-1);
    }
    bytes_written = snprintf(buffer, BUFFER_MAX, “%d”, pin);
    write(fd, buffer, bytes_written);
    close(fd);
    return(0);
}

int GPIOUnexport(int pin)
{
    char buffer[BUFFER_MAX];
    ssize_t bytes_written;
    int fd;

    fd = open(“/sys/class/gpio/unexport”, O_WRONLY);
    if (-1 == fd) {
         fprintf(stderr, “Failed to open unexport for writing!\n”);
        return(-1);
     }

     bytes_written = snprintf(buffer, BUFFER_MAX, “%d”, pin);
     write(fd, buffer, bytes_written);
    close(fd);
    return(0);
}

int GPIODirection(int pin, int dir)
{
static const char s_directions_str[]  = “in\0out”;

#define DIRECTION_MAX 35
    char path[DIRECTION_MAX];
     int fd;

   snprintf(path, DIRECTION_MAX, “/sys/class/gpio/gpio%d/direction”, pin);
    fd = open(path, O_WRONLY);
    if (-1 == fd) {
        fprintf(stderr, “Failed to open gpio direction for writing!\n”);
        return(-1);
    }

    if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3)) {
         fprintf(stderr, “Failed to set direction!\n”);
         return(-1);
    }
    close(fd);
    return(0);
}

int GPIORead(int pin)
{
#define VALUE_MAX 30
    char path[VALUE_MAX];
    char value_str[3];
    int fd;

    snprintf(path, VALUE_MAX, “/sys/class/gpio/gpio%d/value”, pin);
    fd = open(path, O_RDONLY);
    if (-1 == fd) {
        fprintf(stderr, “Failed to open gpio value for reading!\n”);
        return(-1);
    }

    if (-1 == read(fd, value_str, 3)) {
        fprintf(stderr, “Failed to read value!\n”);
        return(-1);
    }

    close(fd);

    return(atoi(value_str));
}

int GPIOWrite(int pin, int value)
{
static const char s_values_str[] = “01”;

    char path[VALUE_MAX];
    int fd;

    snprintf(path, VALUE_MAX, “/sys/class/gpio/gpio%d/value”, pin);
    fd = open(path, O_WRONLY);
    if (-1 == fd) {
        fprintf(stderr, “Failed to open gpio value for writing!\n”);
        return(-1);
    }

    if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1)) {
        fprintf(stderr, “Failed to write value!\n”);
        return(-1);
    }

    close(fd);
    return(0);
}

Summary

This was a quick little introduction to C development on the Raspberry Pi. With the GCC compiler, Code::Blocks, GNU Debugger and GNU Make you have all the tools you need for serious C development. I find the Raspberry Pi is sufficiently powerful to do quite a bit of development work with good productivity. As a learning/teaching environment its excellent. It’s really amazing what you can do with a $35 single board computer.

Advertisements

Written by smist08

December 23, 2017 at 10:48 pm

Fortran Lives

with 3 comments

Introduction

I was looking at a programming IDE called Code::Blocks that seems popular on the Raspberry Pi. Much lighter weight than Eclipse or Visual Studio, but it has a great deal of the same functionality including debugging, project templates, code highlighting and auto-complete. One thing that caught my interest was that Code::Blocks has direct support for Fortran programming. Back when I took first year Computer Science at UVic, all the programming labs were done in WATFIV (Waterloo Fortran IV) and then one of my Co-op work terms was at the the Institute of Ocean Sciences analysing experimental data from the Arctic, writing in Fortran using the extensive Fortran scientific and visualization libraries that were state of the art for the time (on a Univac mainframe).

One thing I noticed when playing with Machine Learning and Python programming was that if I installed something that didn’t have a binary for the particular flavour of Linux I was using then it would download the source code and compile that. What surprised me was the number of Fortran source files it would compile. Part of the reason for this is the giant library of efficient and well tested numerical libraries written in Fortran that have either been donated to the public domain or originated that way from various University research projects. It turns out that many of the popular array, numerical and algorithm libraries for Python are all written in Fortran and a large part of the popularity of Python is the easy access to all these libraries (like LAPACK).

GCC

Many people think of GCC just as the Gnu C compiler for Linux. However officially GCC stands for the Gnu Compiler Collection and supports C, C++, Objective-C, Objective-C++, Fortran, Java, Ada, Go and OpenMP. This then provides a great free cross platform compiler for Fortran that supports most of the things in the latest standard. As a result you can do Fortran programming easily anywhere including the Raspberry Pi. GCC is the compiler that the Code::Blocks IDE runs to compile your Fortran programs.

Fortran isn’t pre-installed on the Raspberry Pi, so to compile a Fortran program you need to add Fortran support to GCC which you do from a terminal window by:

sudo apt-get install gfortran

GPIO

I thought as an experiment I would port my simple flashing light program that I showed in Python and Scratch in my previous blog posting on breadboarding over to Fortran. So Python and Scratch come with GPIO libraries pre-installed and was really easy. For Fortran I didn’t see any such library, but fortunately for Unix/Linux you can usually access any hardware devices via the file metaphor. Basically you control the hardware by opening a file (usually in /dev) and then cause things to happen by writing various things to these special files. Similarly you read these files to get input or status. A good description of how to control the GPIO lines via files is given here. For instance if we want to turn on our LED we wired to pin 17, we would send 17 to the file /sys/class/gpio/export. We can do this from a terminal command line via:

echo 17 > /sys/class/gpio/export

This causes a number of files under /sys/class/gpio/glio17 to be created that we can now access. First we setup pin 17 for output via:

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

Then we turn pin 17 on via

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

And turn it off via:

echo 0 > /sys/class/gpio/gpio17/value

Since most programming languages have file I/O libraries, under Linux this then makes most devices accessible.

Fortran Code

Creating the program was quite easy. I found a library on the Web that provides the GPIO access via the files which I’ll list later. The only problem was that the Fortran sleep function takes its parameters only in seconds so you can’t do a sub-second sleep which means the LEDs flash very slowly. Fortunately it turns out that you can call C runtime routines from Fortran fairly easily, so I include the interface to the C usleep (sleep in microseconds) function so we can use the same 0.2 second time between flashes that we used before. Below is the Fortran source code:

 

! Flash the GPIO lights
program main
  use gpio
  implicit none
  interface
     subroutine usleep(useconds) bind(C)
      use iso_c_binding
      implicit none
      integer(c_int32_t), value :: useconds
     end subroutine
  end interface
  integer i, sleepTime

  call gpioSetOut(17)
  call gpioSetOut(27)
  call gpioSetOut(22)

  sleepTime = 200000

  do i = 1, 10
    call gpioOutput(17, 1)
    call usleep(sleepTime)
    call gpioOutput(17, 0)
    call gpioOutput(27, 1)
    call usleep(sleepTime)
    call gpioOutput(27, 0)
    call gpioOutput(22, 1)
    call usleep(sleepTime)
    call gpioOutput(22, 0)
  end do
end


Fortran has evolved a bit since my University days. There are full structured programming constructs, so you don’t need to use labels. Notice the DO loop has a DO END rather than specifying a label on a CONTINUE statement as we used to do. Fortran has added good support for modules and even object oriented programming while maintaining compatibility for all those scientific libraries everyone loves so much.

Now the GPIO module which I found here. This shows how to create a nice Fortran module. It also shows some Fortran string processing. The module didn’t work for me directly, I had to add a sleep statement after allocating the GPIO pin to allow time for the files to be created or I got file access errors. Here is the code:

 

module gpio
    implicit none
    contains
    subroutine gpioSetOut(pin)
        integer, intent(in) :: pin
        character (len=35) :: unexportChar
        character (len=33) :: exportChar
        character (len=45) :: directionChar
        write (unexportChar, '("echo ", I0, " > /sys/class/gpio/unexport")') pin
        write (exportChar, '("echo ", I0, " > /sys/class/gpio/export")') pin
        call execute_command_line(unexportChar)
        call execute_command_line(exportChar)
        call sleep(1)

        write (directionChar, '("echo out > /sys/class/gpio/gpio", I0, "/direction")') pin
        call execute_command_line(directionChar)
    end subroutine gpioSetOut

    subroutine gpioSetIn(pin)
        integer, intent(in) :: pin
        character (len=35) :: unexportChar
        character (len=33) :: exportChar
        character (len=45) :: directionChar
        write (unexportChar, '("echo ", I0, " > /sys/class/gpio/unexport")') pin
        write (exportChar, '("echo ", I0, " > /sys/class/gpio/export")') pin
        call execute_command_line(unexportChar)
        call execute_command_line(exportChar)
        call sleep(1)

        write (directionChar, '("echo in > /sys/class/gpio/gpio", I0, "/direction")') pin
        call execute_command_line(directionChar)
    end subroutine gpioSetIn

    subroutine gpioOutput(pin, value)
        integer, intent(in) :: pin, value
        character (len=45) :: valueChar

        write (valueChar, '("echo ", I1, " > /sys/class/gpio/gpio", I0, "/value")') value, pin
        call execute_command_line(valueChar)
    end subroutine gpioOutput

    subroutine gpioRead(pin, value)
        integer, intent(in) :: pin
        integer, intent(out) :: value
        character (len=28) :: valueChar

        write (valueChar, '("/sys/class/gpio/gpio", I0, "/value")') pin

        open (unit=1, file=valueChar)
        read (1,*) value
        close (1)
    end subroutine gpioRead

end module gpio


One other thing, I needed to add -lgfortran as a linker option in Code::Blocks, since for some reason a freshly created Fortran application project didn’t include the link for the Fortran runtime.

Fortran Evolution

The latest standard for Fortran came was Fortran 2008 which came out in 2010. The next version will be Fortran 2018 and we’ll see if it shows up next year. GCC supports most things in Fortran 08 plus a few other enhancements. The next 2018 release is includes quite a few things including more advanced parallel processing capabilities and easier interoperability with C. Certainly Fortran has made great strides since my University days with structured, modular and object oriented programming support along with variable length string processing. Fortran really excels at parallel processing support since it is still the goto language on most supercomputers and used for all those advanced climate, astronomical and other scientific models.

Summary

I think I’ll stick to Python as my current goto language. But playing with Fortran was fun and it’s amazing to see how much usage it still gets. If you are doing serious high performance numerical processing then you are probably going to have to get your hands dirty with Fortran. Certainly the Raspberry Pi is a good place to learn Fortran with high quality free tools like Code::Blocks and GCC Fortran.

 

Written by smist08

December 2, 2017 at 4:39 pm

Wearable Devices and Sports

with 2 comments

Introduction

I happen to be on holiday this week on the Sunshine Coast (in BC, not Aus). I’ve doing a lot of running and cycling so I thought I would blog a bit on how new devices like GPS watches, step counters and Phone Apps are helping track sports. I have a Garmin GPS watch and an iPhone 4s. So what can I do with these and what is the potential as these devices improve?

The GCC

This year Sage is again participating in the GCC (the Get the World Moving Coporate Challenge). Basically you form teams of 7 co-workers and each of you wears a pedometer for the duration of the event. You then enter your steps, meters swam and km cycled into the website each day.

You then are tracked as you walk around the world and compete with other teams, either generally, within your company or within your area. The website is quite good, provides lots of useful information and tips on how to improve your health and fitness levels.

gcc

To do this tracking just requires a pedometer and their website. No other high tech gadgetry required. It will be interesting to see if more low tech solutions like this one (though the web site and pedometer are both fairly sophisticated) or solutions requiring more hardware like smart watches and extra devices will become the norm.

Garmin GPS Watches

There has been a lot of talk about Apple, Google and Microsoft coming out with smart watches this fall. Further several manufacturers like Samsung already have devices on the market. Then there have been a number of failures like Nike’s entry in this field. I think a lot of these companies have been looking at the success Garmin has had here. Garmin has transformed itself from manufacturing standalone GPS’s (which have now largely been replaced by functionality built into every phone) to making quite useful GPS sports watches.

The watches tend to be a bit bigger than a normal watch but still not uncomfortable to wear when running. Perhaps not the greatest fashion accessory, they are really quite useful. Besides recording your speed, location, distance and elevation in great detail, they also have heart rate monitors to give you quite a bit of information. Then they have a web site that is no extra charge to store and share all your routes and runs. For instance here.

garminconnn

The info is collected by the watch and then you upload it to your PC when you get back and then from there to their web site.

Generally this then gives you all sorts of metrics where you can see how you did, your pace every kilometer, how you did on uphill’s and downhill’s, etc. You can then track your progress and have a good idea of how you are doing.

Runtastic

There are quite a few fitness tracking apps for the iPhone. I just chose Runtastic because I liked the dashboard display in their app store ad. But otherwise it’s been fine, except for a bit too much promotion for the pro version. There are ads in the app and web site, but at a reasonable level, I think for the service you are getting.

There are a lot of attachments available to mount your phone on your bike; however, I’ve found that doing this really drains your phone’s battery quickly (i.e. in about an hour) and so isn’t really all that practical.

Runtastic Road Bike

More typically it’s better to leave the display off since then it doesn’t seem to use that much battery. Also if you stop to take pictures or something, make sure you switch back to the app first. The iPhone doesn’t have good multi-tasking, so unless the app is the active one, it probably won’t be doing anything.

Once you are finished your ride, the app uploads the data to the website and allows you to share what you are doing via social media (as any of my Facebook friends know). For instance this one here.

runtastic2

Like the Garmin website, this one gives you lots of information and makes it easy to track your progress as you try to improve your sport.

The Future

I think that companies like Apple are looking at this market and hope it is a bit like the early MP3 music player market was. Then a company like Apple could come along, redefine the market, make it dead simple and create a much larger market than what the early technology startups could achieve.

Whether Apple can repeat the iPod success in this market is yet to be seen. And they are certainly going to face a lot of competition as Microsoft and Google are hoping they can do the same thing.

Garmin type devices have better battery life and better durability than phones. However phones have better apps and greatly benefit from continuous Internet connectivity. So what are successful future devices going to need? From my perspective they will need:

  • Better battery life. Operating with only a couple of hour’s batter life is insufficient. This should really be a week.
  • Better durability. They can’t just fry when they get a little wet in the rain. Cycling and running are outdoor sports performed in any weather. Athletes don’t want extra clothing or gear to keep their watch dry. Further it would be great if these work for swimming. After all there are already a great many regularly triathlon watches that work great while swimming.
  • Intelligent support for more sports. Useful metrics gathered while golfing for instance. What about soccer, football or hockey?
  • Do not require a separate data plan. If you have to pay $50 per month to a cell phone provider then they are dead in the water.

Another area where there is great research going on is developing more sensors that measure things like blood glucose levels, blood pressure, etc. It will be interesting to see how tracking these additional metrics can help athletes.

There are also appearing apps that intelligently use the Phone’s camera to do things like analyze golf swings and tennis strokes. As these improve we may reach the stage where casual players can get real professional coaching and feedback right from their phone.

On the flip side, there is a lot of concern about the possible privacy implications of these devices. For instance if I record heart rate monitor information and it starts detecting abnormal behavior, could an insurance company find out and cancel my insurance? Could it be used in other adverse ways? Generally this sort of medical information is very protected. Will these devices, services and web sites offer the necessary levels of personal privacy protection? Will I find out I have a heart condition because suddenly I start receiving ads for defibulators and pace-makers? There is certainly a lot of concern about this out there and there have been many Science Fiction stories about the possible abuses. Hopefully these won’t all turn out to be prophetic.

Summary

By Christmas shopping season we are going to be inundated by new intelligent watches and other form factors that can help us track and improve our fitness levels. They will track all sorts of metrics for us, provide feedback and even professional levels of coaching. It will be interesting to see if this sparks a greater level of interest in fitness and sports. Maybe these will even help with the current epidemic obesity levels in our society.

Written by smist08

July 5, 2014 at 4:17 pm