Toon posts:

[Python] Signal van kernel-module naar user-process *

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi, ik ben bezig met een projectje om onder linux een zelfgemaakt interface kaartje te besturen.
Ik gebruik python om via de parallele port signalen van een AD convertor in te lezen.

Omdat ik niet de hele tijd de poort wil pollen wil ik via de "IRQ 7 pin" elke keer als er nieuwe signalen zijn een interrupt handler oproepen, dit kan helaas niet onder python want die draait in user-space, wel kan ik in python op dezelfde manier een signal handler oproepen als bijv. SIGUSR1 binnenkomt.

Ik heb dus een kernel-module nodig met een interrupt 7 handler die SIGUSR1 naar de pid van m'n python process stuurt. Na flink wat zoeken heb ik een module gevonden en aangepast om interrupt 7 te testen, elke keer als er een interrupt gebeurt word er een bericht geprint in dmesg, dit werkt ook goed.

Het signaal wilde ik versturen met
code:
1
 kill(pid, SIGUSR1);
waarbij de pid uit een file zou moeten worden gelezen.
maar deze functie wordt gedeclareerd in /usr/include/signal.h en volgens mij kan ik alleen files uit /usr/src/kernel-build-2.4.22-1/k6/include/ gebruiken.
uit de files (signal.h, siginfo.h, asm/signal.h, etc.) die hierin staan kan ik geen "kill" vinden of iets wat met het versturen van signalen naar processen te maken heeft.

Het gaat dus eigenlijk maar om een regeltje, maar aangezien ik verder geen ervaring in het programmeren met C heb kom ik er niet echt meer uit.

Source van de module:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
test.c
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/signal.h>
 #include <asm/io.h>

 #define MODULE_VERSION "1.0"
 #define MODULE_NAME "Interupt 7 Handler"

 #define SPPDATAPORT         0x378
 #define SPPSTATUSPORT       (SPPDATAPORT + 1)
 #define SPPCONTROLPORT      (SPPDATAPORT + 2)
 #define SSPINTERRUPTENABLE  0x10

 #define INTERRUPT 7

 /*
  * This function is the interrupt handler for interrupt 7.
  */
 void interrupt7(int irq, void *dev_id, struct pt_regs *regs)
 {
    printk("Interrupt has occured\n");
/*    kill(pid, SIGUSR1);                                                            Dit werkt dus niet*/
 }

 static int __init init_interrupt7(void)
 {

   int rv = 0;

   /* request interrupt from linux */
   rv = request_irq(INTERRUPT, interrupt7, 0,
                    "interrupt7",NULL);
   if ( rv ) {
     printk("Can't get interrupt %d\n", INTERRUPT);
   }

 /* enable parallel port interrupt generation */
   outb(SSPINTERRUPTENABLE,SPPCONTROLPORT);

 /* everything initialized */
   printk(KERN_INFO "%s %s initialized\n",MODULE_NAME, MODULE_VERSION);
   return 0;
 }

 /*
  * This function frees interrupt 7
  */
 static void __exit cleanup_interrupt7(void)
 {
 /* disable parallel port interrupt reporting */
   outb(0x00,SPPCONTROLPORT);

 /* free the interrupt */
   free_irq(INTERRUPT,NULL);

   printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERSION);
 }

 module_init(init_interrupt7);
 module_exit(cleanup_interrupt7);

 MODULE_AUTHOR("Craig");
 MODULE_DESCRIPTION("Interrupt 7");

 EXPORT_NO_SYMBOLS;

  • igmar
  • Registratie: April 2000
  • Laatst online: 29-06 18:56

igmar

ISO20022

1) Files lezen vanuit kernel mode gaat niet zonder meer. Het beste is /proc hiervoor
2) Signals sturen doe je met force_sig(SIGNAL, struct task_struct *)

Verwijderd

Topicstarter
Probleem opgelost door de pid van de process via de commandline te geven bij het laden.
insmod test.o pid=666
daarna de taskstuct van de pid krijgen met get_task(pid_t pid), en send_sig(SIGUSR1, task) naar de process sturen.

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/signal.h>
#include <asm/io.h>

#define MODULE_VERSION "1.0"
#define MODULE_NAME "Interupt 7 Handler"

#define SPPDATAPORT 0x378
#define SPPSTATUSPORT (SPPDATAPORT + 1)
#define SPPCONTROLPORT (SPPDATAPORT + 2)
#define SSPINTERRUPTENABLE 0x10
#define INTERRUPT 7

static int pid = 999999;
MODULE_PARM (pid, "i");

/* gcc -O2 -D__KERNEL__ -DMODULE -I/usr/src/kernel-build-2.4.22-1/k6/include/ -c -o interrupt7.o interrupt7.c */

struct PyPort
{
int pid;
} PyPort;

struct task_struct *get_task(pid_t pid)
{
struct task_struct *p = current;
do {
if (p->pid == pid)
return p;
p = p->next_task;
}
while (p != current);
return NULL;
}

/*
* This function is the interrupt handler for interrupt 7.
*/
void interrupt7(int irq, void *dev_id, struct pt_regs *regs)
{
printk("Interrupt has occured\n");
send_sig(SIGUSR1, get_task(PyPort.pid), 1);
}

static int __init init_interrupt7(void)
{

int rv = 0;

/* request interrupt from linux */
rv = request_irq(INTERRUPT, interrupt7, 0,
"interrupt7",NULL);
if ( rv ) {
printk("Can't get interrupt %d\n", INTERRUPT);
}

/* enable parallel port interrupt generation */
outb(SSPINTERRUPTENABLE,SPPCONTROLPORT);

PyPort.pid = pid;

/* everything initialized */
printk(KERN_INFO "%s %s initialized\n",MODULE_NAME, MODULE_VERSION);
printk("Sending SIGURS1 to process pid %i\n", PyPort.pid);
return 0;
}

/*
* This function frees interrupt 7
*/
static void __exit cleanup_interrupt7(void)
{
/* disable parallel port interrupt reporting */
outb(0x00,SPPCONTROLPORT);

/* free the interrupt */
free_irq(INTERRUPT,NULL);

printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERSION);
}

module_init(init_interrupt7);
module_exit(cleanup_interrupt7);

MODULE_AUTHOR("Tekniq DHDT");
MODULE_DESCRIPTION("Interrupt 7");
MODULE_LICENSE("GPL");

EXPORT_NO_SYMBOLS;
[/code]