0

I am working with a SoC FPGA. In the past I have been testing some peripherals through polling, and now I want to work with interrupts.

I have followed some tutorials and now I have a driver which can detect interrupts on the IRQ 72. The problem is that I want to reply to that IRQ and I have been trying different things but none seems to work.

The last attempt was about a C program which would do the logic part, I mean, it will perform some action when the Kernel tells it an interrupt is present. This program is writting it's PID on a file, I want the kernel to read the PID to send the program a SIGUSR1 signal, and then the program will do smth.

Kernel module:

#include <linux/module.h>  // Needed by all modules
#include <linux/kernel.h>  // Needed for KERN_INFO
#include <linux/fs.h>      // Needed by filp
#include <asm/uaccess.h>   // Needed by segment descriptors
#include <linux/init.h>   /*Needed for the macros*/
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of.h>

#define DEVNAME "test_int"

static irq_handler_t __test_isr(int irq, void *dev_id, struct pt_regs *regs){
    printk (KERN_INFO DEVNAME ": ISR\n");
    return (irq_handler_t) IRQ_HANDLED;
}

static int __test_int_driver_probe(struct platform_device* pdev){
    // Create variables
    struct file *f;
    char buf[128];
    mm_segment_t fs;
    int i;
    // Init the buffer with 0
    for(i=0;i<128;i++)
        buf[i] = 0;

    // PID file
    // It is an inteer, so i guess 4Bytes would be better
    f = filp_open("/home/root/modInt/miPID", O_RDONLY, 0);
    if(f == NULL)
        printk(KERN_ALERT "filp_open error!!.\n");
    else{
        // Get current segment descriptor
        fs = get_fs();
        // Set segment descriptor associated to kernel space
        set_fs(get_ds());
        // Read the file
        f->f_op->read(f, buf, 128, &f->f_pos);
        // Restore segment descriptor
        set_fs(fs);
        // See what we read from file
        printk("El PID es buf:%s\n",buf);
    }
    filp_close(f,NULL);
    int irq_num;
    irq_num = platform_get_irq(pdev, 0);
    printk(KERN_INFO DEVNAME ": La IRQ %d va a ser registrada!\n", irq_num);
    return request_irq(irq_num, (irq_handler_t) __test_isr, 0, DEVNAME, NULL);
}

static int __test_int_driver_remove (struct platform_device *pdev){
    int irq_num;
    irq_num = platform_get_irq (pdev, 0);
    printk(KERN_INFO "test_int: Abandonando la captura de la IRQ %d !\n", irq_num);
    free_irq(irq_num, NULL);
    return 0;
}

static const struct of_device_id __test_int_driver_id[] = {
    {.compatible = "altr , socfpga-mysoftip"},
    {}
};

static struct platform_driver __test_int_driver = {
    .driver= {
        .name = DEVNAME,
        .owner = THIS_MODULE,
        .of_match_table = of_match_ptr (__test_int_driver_id),
    },
    .probe = __test_int_driver_probe,
    .remove = __test_int_driver_remove
};

module_platform_driver (__test_int_driver);

MODULE_LICENSE("GPL");

Program:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>

void sig_handler(int signo)
{
  if (signo == SIGUSR1)
    printf("Senal SIGUSR1 recibida\n");
}

int main(void){ 
    int pid=getpid();
    FILE *f = fopen("miPID", "w");
    if (f == NULL){
        printf("Error opening file!\n");
        exit(1);
    }
    fprintf(f, "%d", pid);
    fclose(f);

    printf("My process ID : %d\n", pid);
    if (signal(SIGUSR1, sig_handler) == SIG_ERR)
        printf("\nNo se ha podido capturar SIGINT\n");
    // A long long wait so that we can easily issue a signal to this process
    while(1) 
        sleep(1);
    return 0;
}

Compiles well under ARM arch. Errors when instantiating de module:

root@socfpga:~/modInt# insmod sigGen.ko
[   63.121696] sigGen: loading out-of-tree module taints kernel.
[   63.129185] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[   63.138088] pgd = ee7b0000
[   63.140801] [00000000] *pgd=3fcb2831
[   63.144381] Internal error: Oops: 80000007 [#1] PREEMPT SMP ARM
[   63.144385] Modules linked in: sigGen(O+)
[   63.144399] CPU: 1 PID: 1350 Comm: insmod Tainted: G           O    4.14.73-rt45-ltsi #2
[   63.144401] Hardware name: Altera SOCFPGA
[   63.144406] task: ee9c3f00 task.stack: ee618000
[   63.144411] PC is at 0x0
[   63.144423] LR is at __test_int_driver_probe+0x80/0x108 [sigGen]
[   63.144427] pc : [<00000000>]    lr : [<bf0000ec>]    psr: a0070013
[   63.144430] sp : ee619c20  ip : c0814080  fp : ee619ccc
[   63.144433] r10: 00000000  r9 : 00000003  r8 : bf000000
[   63.144437] r7 : ef279600  r6 : ee4c6000  r5 : ffffe000  r4 : 00000000
[   63.144441] r3 : ee4c6058  r2 : 00000080  r1 : ee619c28  r0 : ee4c6000
[   63.144446] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   63.144450] Control: 10c5387d  Table: 2e7b004a  DAC: 00000051
[   63.144454] Process insmod (pid: 1350, stack limit = 0xee618218)
[   63.144457] Stack: (0xee619c20 to 0xee61a000)
[   63.144465] 9c20: 00000000 c04c3280 00000000 00000000 00000000 00000000 00000000 00000000
[   63.144472] 9c40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   63.144478] 9c60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   63.144484] 9c80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   63.144491] 9ca0: 00000000 00000000 ef279610 ef279610 ef279610 bf002014 fffffdfb bf002014
[   63.144499] 9cc0: ee619cec ee619cd0 c050ffb8 bf000078 ef279610 c0cabf84 c0cabf9c 00000000
[   63.144506] 9ce0: ee619d1c ee619cf0 c050def8 c050ff68 00000000 ef279610 bf002014 ef279644
[   63.144512] 9d00: 00000000 bf0020c8 11b4365c bf002080 ee619d3c ee619d20 c050e084 c050dcf4
[   63.144519] 9d20: 00000000 bf002014 c050dfc8 00000000 ee619d64 ee619d40 c050bf34 c050dfd4
[   63.144526] 9d40: ef02b06c ef28f248 c07afb2c bf002014 ef26a380 c0c56658 ee619d74 ee619d68
[   63.144533] 9d60: c050d86c c050bec4 ee619d9c ee619d78 c050d338 c050d84c bf0012c8 ee619d88
[   63.144540] 9d80: bf002014 bf005000 00000000 00000001 ee619db4 ee619da0 c050edb0 c050d198
[   63.144547] 9da0: bf002080 bf005000 ee619dc4 ee619db8 c050ff08 c050ed34 ee619dd4 ee619dc8
[   63.144554] 9dc0: bf005020 c050fec4 ee619e44 ee619dd8 c0101870 bf00500c ee618000 ef001e40
[   63.144561] 9de0: ee619df8 ee618038 ee619e34 ee619df8 c025d0cc c025bb1c ee619e44 ee619e08
[   63.144569] 9e00: c025bb1c c0257780 00000001 0000001f ee4037c0 ee618008 00000001 bf002080
[   63.144575] 9e20: 00000001 bf002080 00000001 ee72fbc0 bf0020c8 11b4365c ee619e6c ee619e48
[   63.144582] 9e40: c01accac c010182c ee619e6c ee619e58 c024c6a8 ee619f40 00000001 ee4bc9c0
[   63.144590] 9e60: ee619f1c ee619e70 c01aba50 c01acc44 bf00208c 00007fff bf002080 c01a8a04
[   63.144596] 9e80: bf002264 00000000 c0947650 bf0021b0 bf002180 00000000 c0803938 ee619f40
[   63.144603] 9ea0: ee619eec ee619eb0 c026b078 c0264e58 00000001 00000000 00000000 00000000
[   63.144609] 9ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   63.144615] 9ee0: 00000000 00000000 00000000 00000000 7fffffff 00000000 00000003 000188e1
[   63.144622] 9f00: 0000017b c01080c4 ee618000 00000000 ee619fa4 ee619f20 c01ac274 c01a9c24
[   63.144629] 9f20: 7fffffff 00000000 00000003 00000000 00000000 f0b1e000 0001ef00 00000000
[   63.144636] 9f40: f0b1e412 f0b1e000 0001ef00 f0b3c7a8 f0b3c5d4 f0b35a50 00003000 00003080
[   63.144643] 9f60: 00000000 00000000 00000000 000016fc 0000002c 0000002d 00000018 00000000
[   63.144649] 9f80: 00000012 00000000 00000000 00000000 00000000 beb4cd88 00000000 ee619fa8
[   63.144656] 9fa0: c0107ee0 c01ac1e4 00000000 00000000 00000003 000188e1 00000000 00000002
[   63.144662] 9fc0: 00000000 00000000 beb4cd88 0000017b 00000000 00000000 b6f67000 00000000
[   63.144669] 9fe0: beb4cbc0 beb4cbb0 00013fef b6eb7990 60070010 00000003 00000000 00000000
[   63.144695] [<bf0000ec>] (__test_int_driver_probe [sigGen]) from [<c050ffb8>] (platform_drv_probe+0x5c/0xc0)
[   63.144708] [<c050ffb8>] (platform_drv_probe) from [<c050def8>] (driver_probe_device+0x210/0x2e0)
[   63.144718] [<c050def8>] (driver_probe_device) from [<c050e084>] (__driver_attach+0xbc/0xc0)
[   63.144731] [<c050e084>] (__driver_attach) from [<c050bf34>] (bus_for_each_dev+0x7c/0xb0)
[   63.144741] [<c050bf34>] (bus_for_each_dev) from [<c050d86c>] (driver_attach+0x2c/0x30)
[   63.144749] [<c050d86c>] (driver_attach) from [<c050d338>] (bus_add_driver+0x1ac/0x224)
[   63.144757] [<c050d338>] (bus_add_driver) from [<c050edb0>] (driver_register+0x88/0x108)
[   63.144766] [<c050edb0>] (driver_register) from [<c050ff08>] (__platform_driver_register+0x50/0x58)
[   63.144778] [<c050ff08>] (__platform_driver_register) from [<bf005020>] (__test_int_driver_init+0x20/0x1000 [sigGen])
[   63.144792] [<bf005020>] (__test_int_driver_init [sigGen]) from [<c0101870>] (do_one_initcall+0x50/0x178)
[   63.144805] [<c0101870>] (do_one_initcall) from [<c01accac>] (do_init_module+0x74/0x20c)
[   63.144815] [<c01accac>] (do_init_module) from [<c01aba50>] (load_module+0x1e38/0x2468)
[   63.144824] [<c01aba50>] (load_module) from [<c01ac274>] (SyS_finit_module+0x9c/0xac)
[   63.144834] [<c01ac274>] (SyS_finit_module) from [<c0107ee0>] (ret_fast_syscall+0x0/0x5c)
[   63.144843] Code: bad PC value
[   63.487534] dw_mmc ff704000.dwmmc0: Unexpected interrupt latency
[   63.613936] ---[ end trace 0000000000000002 ]---
Segmentation fault
root@socfpga:~/modInt#
Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144381] Internal error: Oops: 80000007 [#1] PREEMPT SMP ARM


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144454] Process insmod (pid: 1350, stack limit = 0xee618218)


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144457] Stack: (0xee619c20 to 0xee61a000)


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144465] 9c20: 00000000 c04c3280 00000000 00000000 00000000 00000000 00000000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144472] 9c40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144478] 9c60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144484] 9c80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144491] 9ca0: 00000000 00000000 ef279610 ef279610 ef279610 bf002014 fffffdfb bf002014


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144499] 9cc0: ee619cec ee619cd0 c050ffb8 bf000078 ef279610 c0cabf84 c0cabf9c 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144506] 9ce0: ee619d1c ee619cf0 c050def8 c050ff68 00000000 ef279610 bf002014 ef279644


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144512] 9d00: 00000000 bf0020c8 11b4365c bf002080 ee619d3c ee619d20 c050e084 c050dcf4


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144519] 9d20: 00000000 bf002014 c050dfc8 00000000 ee619d64 ee619d40 c050bf34 c050dfd4


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144526] 9d40: ef02b06c ef28f248 c07afb2c bf002014 ef26a380 c0c56658 ee619d74 ee619d68


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144533] 9d60: c050d86c c050bec4 ee619d9c ee619d78 c050d338 c050d84c bf0012c8 ee619d88


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144540] 9d80: bf002014 bf005000 00000000 00000001 ee619db4 ee619da0 c050edb0 c050d198


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144547] 9da0: bf002080 bf005000 ee619dc4 ee619db8 c050ff08 c050ed34 ee619dd4 ee619dc8


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144554] 9dc0: bf005020 c050fec4 ee619e44 ee619dd8 c0101870 bf00500c ee618000 ef001e40


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144561] 9de0: ee619df8 ee618038 ee619e34 ee619df8 c025d0cc c025bb1c ee619e44 ee619e08


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144569] 9e00: c025bb1c c0257780 00000001 0000001f ee4037c0 ee618008 00000001 bf002080


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144575] 9e20: 00000001 bf002080 00000001 ee72fbc0 bf0020c8 11b4365c ee619e6c ee619e48


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144582] 9e40: c01accac c010182c ee619e6c ee619e58 c024c6a8 ee619f40 00000001 ee4bc9c0


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144590] 9e60: ee619f1c ee619e70 c01aba50 c01acc44 bf00208c 00007fff bf002080 c01a8a04


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144596] 9e80: bf002264 00000000 c0947650 bf0021b0 bf002180 00000000 c0803938 ee619f40


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144603] 9ea0: ee619eec ee619eb0 c026b078 c0264e58 00000001 00000000 00000000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144609] 9ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144615] 9ee0: 00000000 00000000 00000000 00000000 7fffffff 00000000 00000003 000188e1


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144622] 9f00: 0000017b c01080c4 ee618000 00000000 ee619fa4 ee619f20 c01ac274 c01a9c24


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144629] 9f20: 7fffffff 00000000 00000003 00000000 00000000 f0b1e000 0001ef00 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144636] 9f40: f0b1e412 f0b1e000 0001ef00 f0b3c7a8 f0b3c5d4 f0b35a50 00003000 00003080


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144643] 9f60: 00000000 00000000 00000000 000016fc 0000002c 0000002d 00000018 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144649] 9f80: 00000012 00000000 00000000 00000000 00000000 beb4cd88 00000000 ee619fa8


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144656] 9fa0: c0107ee0 c01ac1e4 00000000 00000000 00000003 000188e1 00000000 00000002


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144662] 9fc0: 00000000 00000000 beb4cd88 0000017b 00000000 00000000 b6f67000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144669] 9fe0: beb4cbc0 beb4cbb0 00013fef b6eb7990 60070010 00000003 00000000 00000000


Broadcast message from systemd-journald@socfpga (Thu 2019-02-14 04:16:01 UTC):

kernel[1283]: [   63.144843] Code: bad PC value

I am sure there are better ways and I would like to hear them. For example, I also tried to implement the logic on the IRQ handler, but... failed.

EDIT:

I changed a little bit my code as @suren99 suggested, I also added some printk to debug, and now i get this:

root@socfpga:~/leer# insmod leer.ko
[  527.785020] Opened the file successfully
[  527.788953] Value of ret is: -22
[  527.792438] The PID is: ▒▒▒8A▒▒�@
[  527.792476] test_int: La IRQ 41 va a ser registrada!

I must add that...

ret = kernel_read(fp, offset, buf, 512);

Why this is "-22"?

printk("The PID is: %s", buf);

If I printk this, then the answer is this: ▒▒▒8A▒▒�@

printk("The PID is: %s", *buf);

And if put this, then the pointer returns "null".

What am I doing wrong?

jagumiel
  • 13
  • 4
  • Welcome to stackoverflow. Your question needs bit more clarification. Why are you using interrupts. Exactly what data you want to send to user space and on what events. Explain the methodology bit clearly. Well aside from that just considering the question in your post's title you can simply stick with a character driver to get this communication done. – Rajnesh Mar 01 '19 at 16:47
  • Using filp in the driver is begging for all kind of problems. The idea is very bad and needs some sort of rethink. – 0andriy Mar 03 '19 at 07:32
  • I am using interrupts because I am working with an Altera Cyclone V SoC and I want to learn it's different options. Also, the FPGA must have a fast response, and, as I want it to make some operations in the integrated ARM processor, I want to test both methodologies, polling and interrupts. I am also measuring the timing of polling and I want to do so with interrupts aswell. @0andriy, I am a begginer in kernel modules programming. I will read about the filp command you comment, but... What would you suggest to do? I mean, you ask me to rethink, but I don't see more options to communicate them – jagumiel Mar 04 '19 at 07:14
  • There are a lot of kernel<->user space mechanisms to communicate: firmware loader, sysfs, IOCTL, ... Your choice should be dependent to the case and best suitable format of data and communication you would like to have. `filp()` is simple no go. – 0andriy Mar 21 '19 at 13:48

1 Answers1

1

First of all, you shouldn't check the return value of filp_open with NULL. You should check if the call has succeeded by using IS_ERR()

if (IS_ERR(f)) {
    pr_err("Error opening file")
}

I believe the file_open has returned an error pointer and you are trying to dereference it

f->f_op->read(f, buf, 128, &f->f_pos);

Alternatively, you can use addr2line to find which line has caused the kernel panic

suren99
  • 86
  • 6