Olimex Support Forum

OLinuXino Android / Linux boards and System On Modules => A20 => Topic started by: Kampi on July 12, 2014, 09:19:39 PM

Title: C Programm for accessing GPIO
Post by: Kampi on July 12, 2014, 09:19:39 PM
Hello Guys,

I have written a small C-Programm to Access GPIO over /dev/mem


#include <stdio.h> // Standard Ein-/Ausgabe
#include <sys/mman.h> // Für die mmap() Funktion
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define GPIO_Basis 0x01C20800

// Struct zur Beschreibung der Peripherie
struct A20_Peripherie {
unsigned long Adresse; // Adresse der entsprechenden Peripherie
int Memory; // Filedescriptor /dev/mem
void *Map; // Zeiger auf den markieren RAM Bereich für die Peripherie
volatile unsigned int *Addr; // Die physikalische Adresse im RAM die beschrieben werden soll
};

struct A20_Peripherie GPIO = {GPIO_Basis}; // Neues Struct für die GPIO generieren und darin die GPIO Adresse speichern

int RAM_Map(struct A20_Peripherie *Peripherie)
{
Peripherie->Memory = open("/dev/mem", O_RDWR | O_SYNC);

if(Peripherie->Memory < 0)
{
printf("Oeffnen von /dev/mem fehlgeschlagen!\n");
return -1;
}

// RAM Zugriff beim Betriebssystem anmelden
Peripherie->Map = mmap(
NULL, // Gesamten RAM zur Auswahl stellen
getpagesize(),
PROT_READ | PROT_WRITE, // Zugriffsmodi auf den RAM
MAP_SHARED, // Updates im Mapping werden für andere Prozesse sichtbar gemacht
Peripherie->Memory, // Filehandle übergeben
Peripherie->Adresse // Zu mappende Adresse übergeben
);

if(Peripherie->Map < 0)
{
printf("Mapping fehlgeschlagen!\n");
return -1;
}

Peripherie->Addr = (volatile unsigned int *)Peripherie->Map; // Die Adresse zeigt jetzt auf das Mapping -> Beschreiben der Adresse
// bewirkt ein Beschreiben des gemappten Bereiches
return 0;
}

// Aufheben des Mappingbereiches
void Delete_RAM_Map(struct A20_Peripherie *Peripherie)
{
munmap(
Peripherie->Map, // Zu löschende Mapping übergeben
getpagesize()
);
}

int main()
{
if(RAM_Map(&GPIO) == -1)
{
printf("Mappen der GPIO fehlgeschlagen!\n");
return -1;
}

*(GPIO.Addr + 0xD8) = 1 << 0;
*(GPIO.Addr + 0xE8) = 1 << 0;

while(1)
{

}

return 0;
}



If I want to execute it, I got the Error "Segmentation fault". I start this Programm as root.
Why I get this Error?

Thank you!
Title: Re: C Programm for accessing GPIO
Post by: MBR on July 13, 2014, 06:46:03 AM
See http://stackoverflow.com/questions/13124271/driving-beaglebone-gpio-through-dev-mem (http://stackoverflow.com/questions/13124271/driving-beaglebone-gpio-through-dev-mem) and http://elinux.org/RPi_Low-level_peripherals#C (http://elinux.org/RPi_Low-level_peripherals#C), maybe http://www.linuxquestions.org/questions/linux-embedded-and-single-board-computer-78/gpio-access-from-users-pace-656817/ (http://www.linuxquestions.org/questions/linux-embedded-and-single-board-computer-78/gpio-access-from-users-pace-656817/)
Title: Re: C Programm for accessing GPIO
Post by: Kampi on July 15, 2014, 10:57:39 PM
Hello,

tested it with this Programm (works on Raspberry Pi):


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

#define BLOCK_SIZE 4096
#define Peripherie_Basis 0x20000000
#define GPIO_Basis 0x01C20800

// Struct für die nötigen Peripherie Informationen
struct BCM2835_Peripherie {
unsigned long Adresse;
int Memory;
void *Map;
volatile unsigned int *Addr;
};

// Startadresse des GPIO-Controllers in das Struct rein schreiben
struct BCM2835_Peripherie GPIO = {GPIO_Basis};

int RAM_Map(struct BCM2835_Peripherie *Peripherie);

// Funktion zum markieren der Speicherbereiche
int RAM_Map(struct BCM2835_Peripherie *Peripherie)
{
Peripherie->Memory = open("/dev/mem", O_RDWR | O_SYNC);

if(Peripherie->Memory < 0)
{
printf("Oeffnen von /dev/mem fehlgeschlagen!\n");
return -1;
}

Peripherie->Map = mmap(
NULL,
BLOCK_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
Peripherie->Memory,
Peripherie->Adresse
);

if(Peripherie->Map < 0)
{
printf("Mapping fehlgeschlagen!\n");
return -1;
}

Peripherie->Addr = (volatile unsigned int *)Peripherie->Map;
return 0;
}




int main()
{
if(RAM_Map(&GPIO) == -1)
{
printf("Mappen der GPIO fehlgeschlagen!\n");
return -1;
}

*(GPIO.Addr + 0xD8) = 001 << 21;
*(GPIO.Addr + 0xE8) = 1 << 17;

return 0;
}


Change the Adresses, but the Error is still there.
Title: Re: C Programm for accessing GPIO
Post by: JohnS on July 16, 2014, 02:30:01 AM
RPi uses BCM cpu.  Its a lot different.

Maybe datasheet for cpu you have will be enough to change code as needed.

John
Title: Re: C Programm for accessing GPIO
Post by: Kampi on July 16, 2014, 10:04:59 AM
Yes, I know that the RPi use the BCM2835.
But I think that accessing GPIO over /dev/mem is still the same procedure. So I take my Raspberry Pi Programm and change the Adress of GPIO Base and the Register:

http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf

Or is there something else, which I have to change in the Code?
Title: Re: C Programm for accessing GPIO
Post by: Mouchon on July 17, 2014, 07:59:56 AM
Hi you can may be have a look at https://github.com/lephiloux/oa20gpiolib

Kr
Title: Re: C Programm for accessing GPIO
Post by: Kampi on July 17, 2014, 10:53:13 AM
Thank you for that link.
I compare it with my Programm and then I will see what´s wrong.
Title: Re: C Programm for accessing GPIO
Post by: herter on July 17, 2014, 03:13:20 PM
Hello,

Mouchon, this code seems not to manage the interrupts?

Thanks
Title: Re: C Programm for accessing GPIO
Post by: JohnS on July 17, 2014, 04:24:46 PM
That's what the kernel's for (else better not to use interrupts).

John
Title: Re: C Programm for accessing GPIO
Post by: herter on July 17, 2014, 04:31:01 PM
Ok even for external interrupts?
Title: Re: C Programm for accessing GPIO
Post by: JohnS on July 17, 2014, 06:39:10 PM
You lost me.  An interrupt is an interrupt.

Are you wanting to run "bare metal" i.e. no Linux & no Android?

John
Title: Re: C Programm for accessing GPIO
Post by: Mouchon on July 17, 2014, 06:43:30 PM
This code doesn't handle interrupt. The only way to handle it is to use gpio drivers and use

/sys/class/gpio fs. Or make your own kernel module.

kr
Title: Re: C Programm for accessing GPIO
Post by: Kampi on July 18, 2014, 07:57:25 AM
Don´t understanding my Problem... don´t find my misstake.
>.<