4

Good afternoon. My goal is writing a simple c program that run on my beagleboard-xm and open a led on gpio pin every 100 ms. I want to use timer interrupt to achive this. I'm trying to follow this tutorial

http://www.kunen.org/uC/beagle/omap_dmtimer.html

but i miss something. Do i need some kernel manipulation? I have installed native gcc compiler on beagleboard-xm and a cross compiler with Code Sourcery on windows 7 and i can build simple programs to manipulate leds, but both compiler don't recognize the headers used in the tutorial:

#include <linux/module.h>       
#include <linux/kernel.h>       
#include <linux/init.h>         
#include <linux/clk.h>      
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/io.h>         
#include <mach/dmtimer.h>   
#include <linux/types.h>

Any suggest will be much appreciated. Thanks in advance Here i post the code that I have used for GPIO manipulate

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

void sig_handler(int signo) {
    if (signo == SIGINT) {
        FILE *fp;
        if ((fp = fopen("/sys/class/gpio/gpio157/direction", "w")) == NULL ) {
            exit(1);
        } else {
            fprintf(fp, "low");
            fclose(fp);
        }

        fp = fopen("/sys/class/gpio/unexport", "w");
        fprintf(fp, "157");
        fclose(fp);
        printf("Closing and cleaning \n");
    }

}

void main() {
    FILE *fp;

    printf("\n*************************************\n"
            "*  Welcome to PIN Blink program      *\n"
            "*  ....blinking pin 22 on port GPIO  *\n"
            "*  ....rate of 1 Hz............      *\n"
            "**************************************\n");

    if (signal(SIGINT, sig_handler) == SIG_ERR )
        printf("\ncan't catch SIGINT\n");

    fp = fopen("/sys/class/gpio/export", "w");
    fprintf(fp, "157");
    fclose(fp);

    printf("...export file accessed, new pin now accessible\n");

    while (1) {
        if ((fp = fopen("/sys/class/gpio/gpio157/direction", "w")) == NULL ) {
            printf("Error \n");
            exit(1);
        }
        fprintf(fp, "high");
        fclose(fp);
        sleep(1);

        if ((fp = fopen("/sys/class/gpio/gpio157/direction", "w")) == NULL ) {
            printf("Error \n");
            exit(1);
        }
        fprintf(fp, "low");
        fclose(fp);
        sleep(1);
    }

}
Flavio Barisi
  • 472
  • 6
  • 9
  • Install the kernel Header files and if that doesn't fix your problem, install the kernel source code. – JimR Jun 03 '13 at 15:24
  • In your code, you open and close the "/sys/class/gpio/gpio157/direction" file over and over. It would be much faster to just open that file outside of the while() and close it after the while(). Then inside, you can just write to it.. every second. But, even so.. check out my comment to my answer below for the setitimer/getitimer link. You should use that instead of sleep() – Steve Lazaridis Jun 06 '13 at 13:21

1 Answers1

1

If you want to be able to manipulate the GPIO pins from userspace then you'll have to build a kernel driver/module to do that for you. And then you can send messages via ioctl,proc, or other kernel APIs to your driver to manipulate the GPIO pins.

The tutorial looks like a kernel driver example. You cannot build a regular user-space program with these headers. You'll need to either just build an example 'test driver' or do what I said above.

There are tons of resources online about kernel drivers. Here's one you should start with.

Linux Device Drivers, Third Edition

Steve Lazaridis
  • 2,210
  • 1
  • 15
  • 15
  • I have add the program that I used to manipulate GPIO pins from userspace. As you can see I use sleep, beacuse I didn't know how to request a timer and write a interrupt routine. Thanks – Flavio Barisi Jun 03 '13 at 16:12
  • Using sleep isn't a good idea. There are timer APIs that allow you to use timers in Linux. Like setitimer/getitimer. See: http://man7.org/linux/man-pages/man2/setitimer.2.html – Steve Lazaridis Jun 06 '13 at 13:17