Tutorial: Interrupt-Driven Event-Counter on the Raspberry Pi

From dftwiki3
Revision as of 19:14, 23 July 2013 by Thiebaut (talk | contribs) (Getting the Environment Ready)
Jump to: navigation, search

--D. Thiebaut (talk) 19:57, 23 July 2013 (EDT)


This page is under construction. Its purpose is to illustrate how to implement a user-level interrupt in C on a Raspberry Pi to count events.


Page under construction!
UnderConstruction.jpg


Getting the Environment Ready

Install the WiringPi Library

  • Get the WiringPi library from drogon.net
  • Follow the directions on the Web site to download to the Pi. In my case the Pi is connected to my Mac through an ethernet cable, so I downloaded the tgz archive from https://git.drogon.net/?p=wiringPi;a=summary and sftp it over to the pi. I renamed the actual library to wiring.tgz, which is easier to type than its actual name.
sftp pi@169.254.0.2
sftp> pwd 
Remote working directory: /home/pi
sftp> put wiring.tgz
Uploading wiring.tgz to /home/pi/wiring.tgz
wiring.tgz                                                                            100%  108KB 107.8KB/s   00:00    
sftp> quit
  • Connect to the RPI and build the library
 tar -xzvf wiring.tgz 
 cd wiringPi-cbf6d64/
 ./build 
wiringPi Build script
=====================


WiringPi Library
make: Warning: File `Makefile' has modification time 1.4e+07 s in the future
[UnInstall]
[Compile] wiringPi.c
[Compile] wiringSerial.c
...
[Compile] drc.c
[Link (Dynamic)]
[Install Headers]
[Install Dynamic Lib] 
make: warning:  Clock skew detected.  Your build may be incomplete.

WiringPi Devices Library
make: Warning: File `Makefile' has modification time 1.4e+07 s in the future
[UnInstall]
[Compile] ds1302.c
...
[Link (Dynamic)]
[Install Headers]
[Install Dynamic Lib] 
make: warning:  Clock skew detected.  Your build may be incomplete.

GPIO Utility
make: Warning: File `Makefile' has modification time 1.4e+07 s in the future
[Compile] gpio.c
[Compile] extensions.c
[Compile] readall.c
[Link] 
make: warning:  Clock skew detected.  Your build may be incomplete.
make: Warning: File `Makefile' has modification time 1.4e+07 s in the future
[Install]
make: warning:  Clock skew detected.  Your build may be incomplete.

All Done.

NOTE: This is wiringPi v2, and if you need to use the lcd, Piface,
  Gertboard, MaxDetext, etc. routines then you must change your
  compile scripts to add -lwiringPiDev

  • Add the new library to the libray path, as explained in the INSTALL file of the wiringPi distribution.
 sudo nano /etc/ld.so.conf
and add the following line to it:
  /usr/local/lib
  • Tell the system to configure the libraries:
  sudo ldconfig

Interrupt Service Routine

/*
isr4pi.c
D. Thiebaut
based on isr.c from the WiringPi library, authored by Gordon Henderson
https://github.com/WiringPi/WiringPi/blob/master/examples/isr.c
Compile as follows:

    gcc -o isr4pi isr4pi.c -lwiringPi

 */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>


// What GPIO input are we using?
//This is a wiringPi pin number

#define BUTTON_PIN 0

// globalCounter:
//Global variable to count interrupts
//Should be declared volatile to make sure the compiler doesn't cache it.

static volatile int globalCounter = 0 ;


/*
 * myInterrupt:
 *********************************************************************************
 */

void myInterrupt (void) {
  ++globalCounter ;
}


/*
*********************************************************************************
* main
*********************************************************************************
*/

int main (void) {
  int myCounter = 0 ;

  if (wiringPiSetup () < 0)     {
      fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ;
      return 1 ;
  }

  if ( wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0 ) {
      fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ;
      return 1 ;
  }


  for (;;) {
      printf ("Waiting ... "); 
      fflush (stdout) ;

      while (myCounter == globalCounter)
         delay (100) ;

      printf(" Done. counter: %5d\n", globalCounter );
      myCounter = globalCounter ;
    }

  return 0 ;
}

Compilation