PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : interrupt-driven module



f0rtex
19-03-2004, 10:06
Hallo Leute

Ich muss ein Kernel Modul schreiben, welches bei einem Interrupt den Ausgang an der seriellen Schnittstelle togglet. Nun bin ich wie folgt vorgegange:



#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/modversions.h>
#define MODVERSIONS

#include <linux/sched.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h>

/* http://linuxassembly.org/syscall.html */
#include <linux/fs.h>

#include <linux/ioctl.h>

MODULE_AUTHOR("Dragan und Alder ;-)");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Noser Module");

void irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
int fd, reg, toggle, test;

fd = sys_open("/dev/ttyS0", O_RDWR, 600);

/*
* Ready to Send Register
*/
reg = TIOCM_RTS;
toggle = TIOCMBIS;

switch(toggle)
{
case TIOCMBIC:
toggle = TIOCMBIS;
break;
case TIOCMBIS:
toggle = TIOCMBIC;
break;
default:
printk("error!!!\n");
}

sys_ioctl(fd, toggle, &reg);

sys_ioctl(fd, TIOCMGET, &test);
if (test & TIOCM_RTS)
printk("Serial Port not set\n");
else
printk("Serial Port set\n");

sys_close(fd);
}

int init_module(void)
{
return request_irq(7, /* The number of the keyboard IRQ on PCs */
irq_handler, /* our handler */
SA_SHIRQ,
"knoser", NULL);
}

void cleanup_module()
{
free_irq(7, NULL);
}


Man beachte, dass ich sys_open, sys_close und sys_ioctl benutze (da ich gehört habe, dass open, close und ioctl im kernel mode nicht funzen).

Das Modul kompiliert auch schön, jedoch wenn ich ein insmod mache, bekomme ich folgende Fehlermeldungen:


unresolved symbole: sys_ioctl


Any hints?

Danke im Voraus

greets
f0rtex

panzi
19-03-2004, 16:16
Hab von kernelprogrammierung null ahnung, aber vieleicht musst du vorher noch ein anderes modul, in dem sys_ioctl definiert ist, laden. Wobei diese Funktion klingt so als müsste sie sowieso im kernel sein.....

f0rtex
22-03-2004, 17:22
Ich habe das Problem mit den ioctl wie folgt umgangen:



#include <sys/io.h>
...
void irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
int serial=inb(0x3f8+4);
outb(~serial,0x3f8+4);
}


Dabei ist 0x3f8 die Adresse der ersten seriellen Schnittstelle. Die Addition von 4 bewirkt, dass ich ins Modem-Kontrollregister des UART's schreibe.

greets
f0rtex