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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.