Forum: Mikrocontroller und Digitale Elektronik MPC5200B Linux GPIO Kernelmodul


von Thomas S. (dreamer2000)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich würde gerne ein Kernelmodul schreiben, über welches ich den GPIO 
Wakeup 7 Pin steuern kann.

Den Foreneintrag Beitrag "MPC5200B mit Linux, leicht planlos" habe ich 
bereits gelesen. Ich habe mich dabei auch an die vorgeschlagenen 
Literatur https://ezs.kr.hsnr.de//TreiberBuch gehalten.

Das Modul ist soweit aufgesetzt, compilier-bar und betriebsbereit. Über 
insmod hello.ko hänge ich dieses ein und setze mit "mknod hellodevice c 
240 0" ein neues Device. Mit "cat hellodevice"  + STRG-C öffne ich den 
Treiber und beende ihn wieder.

Allerdings habe ich in der "driver_open" Funktion Probleme mit dem 
setzen der GPIO Register.

Kann mir jemand sagen, ob ich da total am Holzweg bin oder ob die 
Richtung soweit passt. Mir ist der MBAR Ausdruck im PowerPC Datenblatt 
auch noch nicht ganz klar - hole ich mir mit "ioremap((u32)0x80000c08, 
(u32)4)" überhaupst die Adresse auf das "echte" GPIO-Direction Register?
Wenn das ganze funktioniert sollte ein LED auf dem Host-Board blinken...

Vielen Dank,
Grüße Thomas

LISTING BEGIN

#include <linux/fs.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#define DRIVER_MAJOR 240

// Metainformation
MODULE_AUTHOR("Thomas Schweighofer");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A virtual device, which returns hallo.");
MODULE_SUPPORTED_DEVICE("none");

static char hello_world[]="Hello World\n";

static int driver_open( struct inode *geraete_datei, struct file 
*instanz )
{
    unsigned int base_adr;

    printk("driver_open called\n");

    //base_adr = (unsigned int) ioremap(0x80000c08, 0x04);
    base_adr = ioremap((u32)0x80000c08, (u32)4);
    if (base_adr != 0){
      printk("Base Address: 0x%x\n", base_adr);
      *((unsigned int *)(base_adr)) = 0;
      printk("Writing 0x80000000 to Base Address\n");
    }
    else
      printk("Error Base Address\n");

    return 0;
}

static int driver_close( struct inode *geraete_datei, struct file 
*instanz )
{
    printk("driver_close called\n");
    return 0;
}

static ssize_t driver_read( struct file *instanz, char *user, size_t 
count,
            loff_t *offset )
{
    int not_copied, to_copy;

    to_copy = strlen(hello_world)+1;
    if( to_copy > count )
        to_copy = count;
    not_copied=copy_to_user(user,hello_world,to_copy);
    return to_copy-not_copied;
}

static struct file_operations fops = {
    .owner= THIS_MODULE,
    .read= driver_read,
    .open= driver_open,
    .release= driver_close,
};

static int __init mod_init(void)
{
    printk("Init Module called\n");
    if(register_chrdev(DRIVER_MAJOR, "Hello", &fops) == 0)
        return 0;
    printk("register_chrdev failed!\n");
    return -EIO;
}

static void __exit mod_exit(void)
{
    printk("Exit Module called\n");
    unregister_chrdev(DRIVER_MAJOR,"Hello");
}

module_init( mod_init );
module_exit( mod_exit );

ENDE LISTING

von Oliver R. (superberti)


Lesenswert?

Hi,

Bist Du Dir sicher, dass sich Dein MBAR auf 0x80000000 befindet?
Normalerweise wird das im Bootloader festgelegt und bei den mir 
bekannten Modulen befindet es sich auf 0xf0000000.
Ich vermute mal, Du benutzt einen 2.6er Kernel. Dann sollte der 
GPIO-Kram auch im Device Tree File aufgeführt sein und im Treiber 
spricht man das ganze mit (Als Beispiel dienen hier die Timer):

void __iomem *GptStart = mpc52xx_find_and_map("mpc5200-gpt");

und beim Entladen

iounmap(GptStart);

nicht vergessen.

Weiterhin musst Du auch erst einmal sicherstellen, dass Dein GPIO-Pin 
nicht schon von einem anderen Gerät benutzt wird, da die Pins auf dem 
MPC5200 heftigst gemultiplext sind.

Gruß, Oliver

von Thomas S. (dreamer2000)


Lesenswert?

Hi Oliver,

vielen Dank erstmal für deine Antwort - werde mich mit deiner Antwort 
und den Begriffen weiter auseinander setzen.

Hast du noch einen WEB-Literaturvorschlag bzgl. Device Tree?

Der Pin den ich ansprechen möchte, ist im Moment als Output an ein LED 
aktiv - den Prozess der das LED blinken lässt, habe ich gestoppt. 
Allerdings ist es so, dass noch ein "Gerätetreiber", welcher vom Board 
Support Package stammt, auf dem Pin sitzt. Damit ist es möglich über ein 
sys-device den Outputpegel zu setzen... Genau dieses Device möchte ich 
selbst nachstellen - allerdings als richtigen Treiber mit erweiterter 
Funktionalität.

Ziel sollte einfach sein - etwas in die Treiber/Modul Programmierung zu 
kommen...

Grüße Thomas

von Oliver R. (superberti)


Lesenswert?

Hallo Thomas,
> Hi Oliver,
>
> vielen Dank erstmal für deine Antwort - werde mich mit deiner Antwort
> und den Begriffen weiter auseinander setzen.
>
> Hast du noch einen WEB-Literaturvorschlag bzgl. Device Tree?
>

Du findest im Kernel unter Documentation/powerpc die Datei 
"mpc52xx-device-tree-bindings.txt".

> Der Pin den ich ansprechen möchte, ist im Moment als Output an ein LED
> aktiv - den Prozess der das LED blinken lässt, habe ich gestoppt.
> Allerdings ist es so, dass noch ein "Gerätetreiber", welcher vom Board
> Support Package stammt, auf dem Pin sitzt. Damit ist es möglich über ein
> sys-device den Outputpegel zu setzen... Genau dieses Device möchte ich
> selbst nachstellen - allerdings als richtigen Treiber mit erweiterter
> Funktionalität.

Wenn es einen Grundlegenden Treiber dafür schon gibt, dann könntest Du 
doch den Quellcode von diesem als Grundlage für Deinen eigenen Treiber 
nehmen. Normalerweise wird der Quellcode mitgeliefert.
Such' in den Kernel-Makefiles nach dem Treibermodul, dann hast Du auch 
die Quellen dazu.

>
> Ziel sollte einfach sein - etwas in die Treiber/Modul Programmierung zu
> kommen...
>
> Grüße Thomas

Falls es auch etwas Geld kosten darf, dann würde ich mir lieber ein Buch 
dazu kaufen. Aufgrund eines Tipps aus dem Forum würde ich momentan 
"Essential Linux Device Drivers" empfehlen, welches wohl zur Zeit am 
aktuellsten und umfangreichsten ist. Ich hab das Buch hier gerade 
liegen, sieht recht vielversprechend aus!

Gruß, Oliver

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.