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?
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