 Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
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
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
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
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
Antwort schreiben
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- [c]C-Code[/c]
- [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel
- Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
"Adresse kopieren", und in den Text einfügen
|