24.01.04 최초 작성
24.01.08 예제 추가
Interrupt
발생 시 Interrupt Vector Table
로 분기할 때 참조되는 번호IRQ
가짐BCM2711 기준
IRQ routing
기능을 지원해 프로세서에 어떤 디바이스에서 인터럽트가 발생했는지(IRQ
) 알림
devm_request_irq()
: 인터럽트를 등록하는 API
devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
unsigned long irq_flags, const char *devname, void *dev_id);
///
dev : 등록하려는 디바이스의 struct device
irq : irq 번호
handler : 인터럽트 핸들러
irq_flags : 플래그 설정
devname : 디바이스 이름
dev_id : 디바이스 ID
rising edge
감지 이후 일정시간 이후에 서비스 처리)kdt_module_init()
: GPIO 16번 핀을 input으로 세팅하고 16번으로 신호가 들어오면 kdt_gpio_irq_signal_handler()
가 실행되도록 설정static int __init kdt_module_init(void)
{
...
if(gpio_request(KDT_GPIO_INPUT, "kdt-gpio-16")) {
pr_info("Can not allocate GPIO 16\n");
goto gpio_17_error;
}
if(gpio_direction_input(KDT_GPIO_INPUT)) {
pr_info("Can not set GPIO 16 to input!\n");
goto gpio_16_error;
}
button_irq = gpio_to_irq(16);
gpio_set_debounce(16, 300);
if (request_irq(button_irq, (irq_handler_t) kdt_gpio_irq_signal_handler, IRQF_TRIGGER_RISING, "kdt_gpio_irq_signal", NULL) != 0) {
pr_err("Error!\n Can not request interrupt nr: %d\n", button_irq);
gpio_free(17);
return -1;
}
...
}
kdt_gpio_irq_signal_handler()
: 호출되면 유저 공간의 태스크에 시그널(SIGNR
)을 전송함static irq_handler_t kdt_gpio_irq_signal_handler(unsigned int irq, void *dev_id, struct pt_regs *regs)
{
struct siginfo info;
pr_info("kdt_gpio_irq_signal_handler: interrupt triggered!!!\n");
if (user_space_task != NULL) {
memset(&info, 0, sizeof(info));
info.si_signo = SIGNR;
info.si_code = SI_QUEUE;
if (send_sig_info(SIGNR, (struct kernel_siginfo *) &info, user_space_task) < 0)
printk("gpio_irq_signal: Error sending signal\n");
}
wait_queue_flag = 1;
wake_up_interruptible(&wait_queue);
return (irq_handler_t) IRQ_HANDLED;
}