인터럽트 후반부를 처리하는 soft irq를 배웠다. 자 이제 사용해 보자. 불행히도 요즘은 일반화된 tasklet을 사용하고 low level인 soft irq를 사용하지 않는다고 한다. 그래도 아래 사이트에서 강제로?? 사용할 수 있는 방법을 찾았다. 실습하고 쓰지 말아야 한다. 드라이버를 로딩 후 언로딩하면 시스템이 죽어버린다.
https://embetronicx.com/tutorials/linux/device-drivers/softirq-in-linux-kernel/
요점은 kernel에서 export_symbol로 raise_softirq, open_softiq 등 3개 함수를 내보내 사용할 수 있게한다. interrrupt.h에 사용자 정의 softirq를 설정해야 한다. 기존 등록된 이벤를 사용하면 시스템이 죽는다.
https://stackoverflow.com/questions/39691131/undefined-functions-while-compiling-linux-kernel-module
튜토리얼이 시스템에 장치를 설치하여 인터럽트를 하는 방법으로 했다. 딱히 장치를 추가할 이유가 없는데 왜 했는지 모르겠으나, 아래 사이트에서 간략한 규칙을 찾았다.
https://temp123.tistory.com/16?category=877924
https://hyeyoo.com/85
인터럽트를 만들어야 확인할 수 있다. 리눅스가 제공하는 명령어로 gpio를 쉽게 컨트롤 할 수 있다. 당연하게도 출력으로 설정하고 값을 써야한다.
https://infoarts.tistory.com/21
돌고 돌아 장치를 추가하고, 인터럽트를 만들어 softirq를 실행했다. tutorial site에 잘 설명되어 있다. 나중에 디바이스 read, write를 인터럽트로 설정할 수도 있을 듯 하다.
i@raspberrypi:~/RaspberryDebug/my_driver $ cat Makefile
#obj-m := sample_driver.o
make -C /lib/modules/`uname -r`/build M=`pwd` modules
rm *.o *.ko *.mod *.mod.c *.mod.o
i@raspberrypi:~/RaspberryDebug/my_driver $ cat Makefile
obj-m := my_driver.o
#obj-m := sample_driver.o
all:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
rm *.o *.ko *.mod *.mod.c *.mod.o
i@raspberrypi:~/RaspberryDebug/my_driver $ cat Makefile
obj-m := my_driver.o
#obj-m := sample_driver.o
all:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
rm *.o *.ko *.mod *.mod.c *.mod.o
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/gpio.h> //GPIO
#include <linux/device.h>
unsigned int GPIO_irqNumber;
static void pesudo_interrupt_softirq_handler(struct softirq_action *action)
pr_info("pesudo interreupt occured\n");
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
raise_softirq(TEST_SOFT_IRQ);
//device driver \uc791\uc131 \ubd80\ubd84.
/*************\ub4dc\ub77c\uc774\ubc84 \ud568\uc218 ******************/
static int mydriver_open(struct inode *inode, struct file *file);
static int mydriver_release(struct inode *inode, struct file *file);
static ssize_t mydriver_read(struct file *flip,
char *buf, size_t len, loff_t *off);
static ssize_t mydriver_write(struct file *flip,
const char *buf, size_t len, loff_t *off);
/********************************************/
//file operation structure
static struct file_operations fops =
.release = mydriver_release,
static int mydriver_open(struct inode *inode, struct file *file)
pr_info("Deviced file was opend.\n");
static int mydriver_release(struct inode *inode, struct file *file)
static int mydriver_read(struct file *flip,
char *buf, size_t len, loff_t *off)
static int mydriver_write(struct file *flip,
const char *buf, size_t len, loff_t *off)
static struct cdev my_cdev;
static struct class *dev_class;
static int __init init_hw(void)
//\ub514\ubc14\uc774\uc2a4 \ub4f1\ub85d
if(( alloc_chrdev_region(&dev, 0, 1, "test_device") < 0))
pr_err("[!]character device was not allocated\n");
pr_info("[=]%d-%d, was allocated\n", MAJOR(dev), MINOR(dev));
cdev_init(&my_cdev, &fops);
pr_info("[=]driver was initialized\n");
//\uc2dc\uc2a4\ud15c\uc5d0 \ucd94\uac00
if((cdev_add(&my_cdev, dev, 1)) < 0)
pr_err("[!]cannot add device to kernel\n");
if((dev_class=class_create(THIS_MODULE, "my_class")) == NULL)
pr_err("[!]cannot add class\n");
if((device_create(dev_class, NULL, dev, NULL, "my_device")) == NULL)
pr_err("[!]cannot create device\n");
//gpio 10\ubc88\uc744 \uc0ac\uc6a9.
//export\ud558\uc5ec \uac04\ub2e8\ud788 \uc0ac\uc6a9.
//\uc785\ub825\uc740 \uac12\uc744 \uc368 \ub123\uc744 \uc218 \uc5c6\uc74c. \ucd9c\ub825\uc73c\ub85c \uc124\uc815.
GPIO_irqNumber = gpio_to_irq(GPIO_10_OUT);
pr_info("[=]irq %d was assinged\n",GPIO_irqNumber);
//interrupt \ub4f1\ub85d \ud544\uc694
if (request_irq(GPIO_irqNumber,
pr_err("[!]my_device: cannot register IRQ\n");
open_softirq(TEST_SOFT_IRQ, pesudo_interrupt_softirq_handler);
pr_info("[=]module was installed\n");
device_destroy(dev_class,dev);
class_destroy(dev_class);
unregister_chrdev_region(dev,1);
static void __exit exit_hw(void) {
device_destroy(dev_class,dev);
class_destroy(dev_class);
unregister_chrdev_region(dev,1);
printk(KERN_INFO "module was removed\n");
MODULE_AUTHOR("Eunseong Park (esp-ark.com)");
MODULE_DESCRIPTION("Hello, world!");
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/gpio.h> //GPIO
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#define GPIO_10_OUT (10)
unsigned int GPIO_irqNumber;
//softirq handler
static void pesudo_interrupt_softirq_handler(struct softirq_action *action)
{
pr_info("pesudo interreupt occured\n");
}
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
/* Raise the softirq */
raise_softirq(TEST_SOFT_IRQ);
return IRQ_HANDLED;
}
//device driver \uc791\uc131 \ubd80\ubd84.
/*************\ub4dc\ub77c\uc774\ubc84 \ud568\uc218 ******************/
static int mydriver_open(struct inode *inode, struct file *file);
static int mydriver_release(struct inode *inode, struct file *file);
static ssize_t mydriver_read(struct file *flip,
char *buf, size_t len, loff_t *off);
static ssize_t mydriver_write(struct file *flip,
const char *buf, size_t len, loff_t *off);
/********************************************/
//file operation structure
static struct file_operations fops =
{
.owner = THIS_MODULE,
.read = mydriver_read,
.write = mydriver_write,
.open = mydriver_open,
.release = mydriver_release,
};
static int mydriver_open(struct inode *inode, struct file *file)
{
pr_info("Deviced file was opend.\n");
return 0;
}
static int mydriver_release(struct inode *inode, struct file *file)
{
return 0;
}
static int mydriver_read(struct file *flip,
char *buf, size_t len, loff_t *off)
{
return 0;
}
static int mydriver_write(struct file *flip,
const char *buf, size_t len, loff_t *off)
{
return 0;
}
dev_t dev = 0;
static struct cdev my_cdev;
static struct class *dev_class;
static int __init init_hw(void)
{
//\ub514\ubc14\uc774\uc2a4 \ub4f1\ub85d
if(( alloc_chrdev_region(&dev, 0, 1, "test_device") < 0))
{
pr_err("[!]character device was not allocated\n");
goto r_unreg;
}
pr_info("[=]%d-%d, was allocated\n", MAJOR(dev), MINOR(dev));
//\ucd08\uae30\ud654
cdev_init(&my_cdev, &fops);
pr_info("[=]driver was initialized\n");
//\uc2dc\uc2a4\ud15c\uc5d0 \ucd94\uac00
if((cdev_add(&my_cdev, dev, 1)) < 0)
{
pr_err("[!]cannot add device to kernel\n");
goto r_del;
}
//class \ub9cc\ub4e6.
if((dev_class=class_create(THIS_MODULE, "my_class")) == NULL)
{
pr_err("[!]cannot add class\n");
goto r_class;
}
if((device_create(dev_class, NULL, dev, NULL, "my_device")) == NULL)
{
pr_err("[!]cannot create device\n");
goto r_device;
}
//gpio 10\ubc88\uc744 \uc0ac\uc6a9.
//export\ud558\uc5ec \uac04\ub2e8\ud788 \uc0ac\uc6a9.
//\uc785\ub825\uc740 \uac12\uc744 \uc368 \ub123\uc744 \uc218 \uc5c6\uc74c. \ucd9c\ub825\uc73c\ub85c \uc124\uc815.
GPIO_irqNumber = gpio_to_irq(GPIO_10_OUT);
pr_info("[=]irq %d was assinged\n",GPIO_irqNumber);
//interrupt \ub4f1\ub85d \ud544\uc694
if (request_irq(GPIO_irqNumber,
(void*)gpio_irq_handler,
IRQF_TRIGGER_RISING,
"my_device",
NULL))
{
pr_err("[!]my_device: cannot register IRQ\n");
goto r_gpio;
}
open_softirq(TEST_SOFT_IRQ, pesudo_interrupt_softirq_handler);
pr_info("[=]module was installed\n");
return 0;
r_gpio:
gpio_free(GPIO_10_OUT);
r_device:
device_destroy(dev_class,dev);
r_class:
class_destroy(dev_class);
r_del:
cdev_del(&my_cdev);
r_unreg:
unregister_chrdev_region(dev,1);
return -1;
}
static void __exit exit_hw(void) {
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&my_cdev);
unregister_chrdev_region(dev,1);
printk(KERN_INFO "module was removed\n");
}
module_init(init_hw);
module_exit(exit_hw);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Eunseong Park (esp-ark.com)");
MODULE_DESCRIPTION("Hello, world!");
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/gpio.h> //GPIO
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#define GPIO_10_OUT (10)
unsigned int GPIO_irqNumber;
//softirq handler
static void pesudo_interrupt_softirq_handler(struct softirq_action *action)
{
pr_info("pesudo interreupt occured\n");
}
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
/* Raise the softirq */
raise_softirq(TEST_SOFT_IRQ);
return IRQ_HANDLED;
}
//device driver \uc791\uc131 \ubd80\ubd84.
/*************\ub4dc\ub77c\uc774\ubc84 \ud568\uc218 ******************/
static int mydriver_open(struct inode *inode, struct file *file);
static int mydriver_release(struct inode *inode, struct file *file);
static ssize_t mydriver_read(struct file *flip,
char *buf, size_t len, loff_t *off);
static ssize_t mydriver_write(struct file *flip,
const char *buf, size_t len, loff_t *off);
/********************************************/
//file operation structure
static struct file_operations fops =
{
.owner = THIS_MODULE,
.read = mydriver_read,
.write = mydriver_write,
.open = mydriver_open,
.release = mydriver_release,
};
static int mydriver_open(struct inode *inode, struct file *file)
{
pr_info("Deviced file was opend.\n");
return 0;
}
static int mydriver_release(struct inode *inode, struct file *file)
{
return 0;
}
static int mydriver_read(struct file *flip,
char *buf, size_t len, loff_t *off)
{
return 0;
}
static int mydriver_write(struct file *flip,
const char *buf, size_t len, loff_t *off)
{
return 0;
}
dev_t dev = 0;
static struct cdev my_cdev;
static struct class *dev_class;
static int __init init_hw(void)
{
//\ub514\ubc14\uc774\uc2a4 \ub4f1\ub85d
if(( alloc_chrdev_region(&dev, 0, 1, "test_device") < 0))
{
pr_err("[!]character device was not allocated\n");
goto r_unreg;
}
pr_info("[=]%d-%d, was allocated\n", MAJOR(dev), MINOR(dev));
//\ucd08\uae30\ud654
cdev_init(&my_cdev, &fops);
pr_info("[=]driver was initialized\n");
//\uc2dc\uc2a4\ud15c\uc5d0 \ucd94\uac00
if((cdev_add(&my_cdev, dev, 1)) < 0)
{
pr_err("[!]cannot add device to kernel\n");
goto r_del;
}
//class \ub9cc\ub4e6.
if((dev_class=class_create(THIS_MODULE, "my_class")) == NULL)
{
pr_err("[!]cannot add class\n");
goto r_class;
}
if((device_create(dev_class, NULL, dev, NULL, "my_device")) == NULL)
{
pr_err("[!]cannot create device\n");
goto r_device;
}
//gpio 10\ubc88\uc744 \uc0ac\uc6a9.
//export\ud558\uc5ec \uac04\ub2e8\ud788 \uc0ac\uc6a9.
//\uc785\ub825\uc740 \uac12\uc744 \uc368 \ub123\uc744 \uc218 \uc5c6\uc74c. \ucd9c\ub825\uc73c\ub85c \uc124\uc815.
GPIO_irqNumber = gpio_to_irq(GPIO_10_OUT);
pr_info("[=]irq %d was assinged\n",GPIO_irqNumber);
//interrupt \ub4f1\ub85d \ud544\uc694
if (request_irq(GPIO_irqNumber,
(void*)gpio_irq_handler,
IRQF_TRIGGER_RISING,
"my_device",
NULL))
{
pr_err("[!]my_device: cannot register IRQ\n");
goto r_gpio;
}
open_softirq(TEST_SOFT_IRQ, pesudo_interrupt_softirq_handler);
pr_info("[=]module was installed\n");
return 0;
r_gpio:
gpio_free(GPIO_10_OUT);
r_device:
device_destroy(dev_class,dev);
r_class:
class_destroy(dev_class);
r_del:
cdev_del(&my_cdev);
r_unreg:
unregister_chrdev_region(dev,1);
return -1;
}
static void __exit exit_hw(void) {
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&my_cdev);
unregister_chrdev_region(dev,1);
printk(KERN_INFO "module was removed\n");
}
module_init(init_hw);
module_exit(exit_hw);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Eunseong Park (esp-ark.com)");
MODULE_DESCRIPTION("Hello, world!");
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo "10" > /sys/class/gpio/export
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo "out" > /sys/class/gpio/gpio10/direction
pi@raspberrypi:~/RaspberryDebug/my_driver $ gpio read 10
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo "10" > /sys/class/gpio/export
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo "out" > /sys/class/gpio/gpio10/direction
pi@raspberrypi:~/RaspberryDebug/my_driver $ gpio read 10
1
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo "10" > /sys/class/gpio/export
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo "out" > /sys/class/gpio/gpio10/direction
pi@raspberrypi:~/RaspberryDebug/my_driver $ gpio read 10
1
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
pi@raspberrypi:~/RaspberryDebug/my_driver $ echo 0 > /sys/class/gpio/gpio10/value ; echo 1 > /sys/class/gpio/gpio10/value;
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.513881] input: Keyboard K480 Consumer Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input5
[ 21.514017] input: Keyboard K480 System Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input6
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
TIMER: 18713 21705 20854 19911
NET_RX: 1125 324 1051 398
TASKLET: 44263 453 587 288
SCHED: 17064 20646 19843 18418
RCU: 19242 23191 20816 20212
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.514017] input: Keyboard K480 System Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input6
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
TIMER: 18828 21849 21047 20104
NET_RX: 1125 324 1063 398
TASKLET: 44459 453 609 288
SCHED: 17173 20815 20069 18623
RCU: 19350 23343 20917 20386
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
[ 477.954727] pesudo interreupt occured
TIMER: 18963 22041 21297 20379
NET_RX: 1128 326 1068 409
TASKLET: 44749 453 647 288
SCHED: 17324 21034 20344 18910
RCU: 19496 23548 21158 20547
pi@raspberrypi:/sys/class/gpio $ sudo rmmod my_driver
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
[ 477.954727] pesudo interreupt occured
[ 497.174610] module was removed
TIMER: 19416 22394 21661 20809
NET_RX: 1141 331 1087 409
TASKLET: 45416 479 678 288
SCHED: 17800 21462 20753 19347
RCU: 19908 23925 21541 20832
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.513881] input: Keyboard K480 Consumer Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input5
[ 21.514017] input: Keyboard K480 System Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input6
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 18713 21705 20854 19911
NET_TX: 95 49 315 19
NET_RX: 1125 324 1051 398
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 44263 453 587 288
SCHED: 17064 20646 19843 18418
HRTIMER: 0 0 0 0
RCU: 19242 23191 20816 20212
(null): 1 0 0 0
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.514017] input: Keyboard K480 System Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input6
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 18828 21849 21047 20104
NET_TX: 95 49 321 19
NET_RX: 1125 324 1063 398
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 44459 453 609 288
SCHED: 17173 20815 20069 18623
HRTIMER: 0 0 0 0
RCU: 19350 23343 20917 20386
(null): 2 0 0 0
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
[ 477.954727] pesudo interreupt occured
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 18963 22041 21297 20379
NET_TX: 95 50 325 19
NET_RX: 1128 326 1068 409
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 44749 453 647 288
SCHED: 17324 21034 20344 18910
HRTIMER: 0 0 0 0
RCU: 19496 23548 21158 20547
(null): 3 0 0 0
pi@raspberrypi:/sys/class/gpio $ sudo rmmod my_driver
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
[ 477.954727] pesudo interreupt occured
[ 497.174610] module was removed
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 19416 22394 21661 20809
NET_TX: 95 50 335 19
NET_RX: 1141 331 1087 409
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 45416 479 678 288
SCHED: 17800 21462 20753 19347
HRTIMER: 0 0 0 0
RCU: 19908 23925 21541 20832
(null): 3 0 0 0
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.513881] input: Keyboard K480 Consumer Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input5
[ 21.514017] input: Keyboard K480 System Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input6
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 18713 21705 20854 19911
NET_TX: 95 49 315 19
NET_RX: 1125 324 1051 398
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 44263 453 587 288
SCHED: 17064 20646 19843 18418
HRTIMER: 0 0 0 0
RCU: 19242 23191 20816 20212
(null): 1 0 0 0
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.514017] input: Keyboard K480 System Control as /devices/platform/soc/fe201000.serial/tty/ttyAMA0/hci0/hci0:11/0005:046D:B33C.0003/input/input6
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 18828 21849 21047 20104
NET_TX: 95 49 321 19
NET_RX: 1125 324 1063 398
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 44459 453 609 288
SCHED: 17173 20815 20069 18623
HRTIMER: 0 0 0 0
RCU: 19350 23343 20917 20386
(null): 2 0 0 0
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 21.514160] hid-generic 0005:046D:B33C.0003: input,hidraw2: BLUETOOTH HID v28.02 Keyboard [Keyboard K480] on e4:5f:01:06:e9:01
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
[ 477.954727] pesudo interreupt occured
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 18963 22041 21297 20379
NET_TX: 95 50 325 19
NET_RX: 1128 326 1068 409
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 44749 453 647 288
SCHED: 17324 21034 20344 18910
HRTIMER: 0 0 0 0
RCU: 19496 23548 21158 20547
(null): 3 0 0 0
pi@raspberrypi:/sys/class/gpio $ sudo rmmod my_driver
pi@raspberrypi:/sys/class/gpio $ dmesg | tail -10;cat /proc/softirqs
[ 281.496011] my_driver: loading out-of-tree module taints kernel.
[ 281.496218] my_driver: no symbol version for raise_softirq
[ 281.496487] [=]236-0, was allocated
[ 281.496492] [=]driver was initialized
[ 281.496679] [=]irq 54 was assinged
[ 281.496713] [=]module was installed
[ 439.643072] pesudo interreupt occured
[ 471.316929] pesudo interreupt occured
[ 477.954727] pesudo interreupt occured
[ 497.174610] module was removed
CPU0 CPU1 CPU2 CPU3
HI: 1 0 0 0
TIMER: 19416 22394 21661 20809
NET_TX: 95 50 335 19
NET_RX: 1141 331 1087 409
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 45416 479 678 288
SCHED: 17800 21462 20753 19347
HRTIMER: 0 0 0 0
RCU: 19908 23925 21541 20832
(null): 3 0 0 0
pi@raspberrypi:/sys/class/gpio $ cat /proc/interrupts
17: 0 0 0 0 GICv2 29 Level arch_timer
18: 13237 9026 7126 13623 GICv2 30 Level arch_timer
23: 352 0 0 0 GICv2 114 Level DMA IRQ
31: 3111 0 0 0 GICv2 65 Level fe00b880.mailbox
34: 8655 0 0 0 GICv2 153 Level uart-pl011
35: 0 0 0 0 GICv2 169 Level brcmstb_thermal
36: 33671 0 0 0 GICv2 158 Level mmc1, mmc0
37: 17923 0 0 0 GICv2 144 Level vc4 firmware kms
38: 0 0 0 0 GICv2 48 Level arm-pmu
39: 0 0 0 0 GICv2 49 Level arm-pmu
40: 0 0 0 0 GICv2 50 Level arm-pmu
41: 0 0 0 0 GICv2 51 Level arm-pmu
42: 8559 0 0 0 GICv2 106 Level v3d
44: 1557 0 0 0 GICv2 189 Level eth0
45: 52 0 0 0 GICv2 190 Level eth0
51: 707 0 0 0 GICv2 66 Level VCHIQ doorbell
52: 0 0 0 0 GICv2 175 Level PCIe PME, aerdrv
53: 1053 0 0 0 Brcm_MSI 524288 Edge xhci_hcd
54: 2 0 0 0 pinctrl-bcm2835 10 Edge my_device
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 12130 21051 27290 15651 Rescheduling interrupts
IPI3: 785 1597 1554 1937 Function call interrupts
IPI4: 0 0 0 0 CPU stop interrupts
IPI5: 793 414 433 246 IRQ work interrupts
IPI6: 0 0 0 0 completion interrupts
pi@raspberrypi:/sys/class/gpio $ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
17: 0 0 0 0 GICv2 29 Level arch_timer
18: 13237 9026 7126 13623 GICv2 30 Level arch_timer
23: 352 0 0 0 GICv2 114 Level DMA IRQ
31: 3111 0 0 0 GICv2 65 Level fe00b880.mailbox
34: 8655 0 0 0 GICv2 153 Level uart-pl011
35: 0 0 0 0 GICv2 169 Level brcmstb_thermal
36: 33671 0 0 0 GICv2 158 Level mmc1, mmc0
37: 17923 0 0 0 GICv2 144 Level vc4 firmware kms
38: 0 0 0 0 GICv2 48 Level arm-pmu
39: 0 0 0 0 GICv2 49 Level arm-pmu
40: 0 0 0 0 GICv2 50 Level arm-pmu
41: 0 0 0 0 GICv2 51 Level arm-pmu
42: 8559 0 0 0 GICv2 106 Level v3d
44: 1557 0 0 0 GICv2 189 Level eth0
45: 52 0 0 0 GICv2 190 Level eth0
51: 707 0 0 0 GICv2 66 Level VCHIQ doorbell
52: 0 0 0 0 GICv2 175 Level PCIe PME, aerdrv
53: 1053 0 0 0 Brcm_MSI 524288 Edge xhci_hcd
54: 2 0 0 0 pinctrl-bcm2835 10 Edge my_device
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 12130 21051 27290 15651 Rescheduling interrupts
IPI3: 785 1597 1554 1937 Function call interrupts
IPI4: 0 0 0 0 CPU stop interrupts
IPI5: 793 414 433 246 IRQ work interrupts
IPI6: 0 0 0 0 completion interrupts
Err: 0
pi@raspberrypi:/sys/class/gpio $ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
17: 0 0 0 0 GICv2 29 Level arch_timer
18: 13237 9026 7126 13623 GICv2 30 Level arch_timer
23: 352 0 0 0 GICv2 114 Level DMA IRQ
31: 3111 0 0 0 GICv2 65 Level fe00b880.mailbox
34: 8655 0 0 0 GICv2 153 Level uart-pl011
35: 0 0 0 0 GICv2 169 Level brcmstb_thermal
36: 33671 0 0 0 GICv2 158 Level mmc1, mmc0
37: 17923 0 0 0 GICv2 144 Level vc4 firmware kms
38: 0 0 0 0 GICv2 48 Level arm-pmu
39: 0 0 0 0 GICv2 49 Level arm-pmu
40: 0 0 0 0 GICv2 50 Level arm-pmu
41: 0 0 0 0 GICv2 51 Level arm-pmu
42: 8559 0 0 0 GICv2 106 Level v3d
44: 1557 0 0 0 GICv2 189 Level eth0
45: 52 0 0 0 GICv2 190 Level eth0
51: 707 0 0 0 GICv2 66 Level VCHIQ doorbell
52: 0 0 0 0 GICv2 175 Level PCIe PME, aerdrv
53: 1053 0 0 0 Brcm_MSI 524288 Edge xhci_hcd
54: 2 0 0 0 pinctrl-bcm2835 10 Edge my_device
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 12130 21051 27290 15651 Rescheduling interrupts
IPI3: 785 1597 1554 1937 Function call interrupts
IPI4: 0 0 0 0 CPU stop interrupts
IPI5: 793 414 433 246 IRQ work interrupts
IPI6: 0 0 0 0 completion interrupts
Err: 0
자 이제 커널을 다시 돌리고 tasklet으로 가자. 드라이버를 언로딩하고 cat /proc/interrupt를 하면 시스템이 어쩃든 죽는다. softirq 문제가 아니라, 인터럽트 핸들러를 해제하지 않아서 죽었다.
pi@raspberrypi:~/RaspberryDebug/my_driver $ diff my_driver.c my_driver.c.bak
< free_irq(GPIO_irqNumber, NULL);
pi@raspberrypi:~/RaspberryDebug/my_driver $ diff my_driver.c my_driver.c.bak
164d163
< free_irq(GPIO_irqNumber, NULL);
pi@raspberrypi:~/RaspberryDebug/my_driver $ diff my_driver.c my_driver.c.bak
164d163
< free_irq(GPIO_irqNumber, NULL);