728x90
반응형
Interrupt Handling in Embedded Linux
Embedded Linux에서 인터럽트는 하드웨어 이벤트를 처리하는 중요한 메커니즘입니다. 이번 포스팅에서는 Linux에서 인터럽트 처리에 대한 개념을 이해하고, Rockchip RK3399를 기준으로 인터럽트 기반 드라이버를 작성하는 방법을 단계별로 살펴보겠습니다.
1. Linux에서 인터럽트 처리 이해
1.1 인터럽트의 개념
인터럽트는 하드웨어 또는 소프트웨어에서 발생하는 이벤트를 커널이 처리하도록 알리는 메커니즘입니다. 하드웨어 인터럽트는 CPU에 신호를 보내 특정 이벤트를 처리하도록 요청합니다.
인터럽트의 주요 용어
- IRQ (Interrupt Request): 하드웨어 디바이스가 CPU에 이벤트를 알리는 신호.
- ISR (Interrupt Service Routine): 인터럽트를 처리하기 위한 커널의 함수.
- SoftIRQ: ISR에서 처리하지 못한 작업을 연기하여 처리하는 메커니즘.
1.2 Linux 인터럽트 처리 흐름
- 하드웨어에서 인터럽트 신호 발생.
- 커널이 적절한 ISR을 호출.
- ISR에서 필요한 작업 수행 후 반환.
- 추가 작업이 필요하면 SoftIRQ로 연기하여 처리.
2. 인터럽트 기반 드라이버 작성
Rockchip RK3399를 기준으로 GPIO 핀에 연결된 버튼의 인터럽트를 처리하는 드라이버를 작성해보겠습니다.
2.1 드라이버 구조
드라이버는 아래와 같은 주요 단계를 포함합니다:
- IRQ 번호 요청 및 매핑.
- ISR 등록.
- ISR에서 이벤트 처리.
2.2 예제 코드
아래는 Rockchip RK3399의 GPIO 인터럽트를 처리하는 간단한 드라이버 예제입니다.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#define DRIVER_NAME "rk3399_gpio_irq"
static int gpio_num;
static int irq_num;
// ISR 정의
static irqreturn_t gpio_irq_handler(int irq, void *dev_id) {
printk(KERN_INFO "GPIO Interrupt occurred!\n");
return IRQ_HANDLED;
}
static int __init gpio_irq_init(void) {
struct device_node *node;
// 디바이스 트리에서 GPIO 정보 가져오기
node = of_find_node_by_name(NULL, "gpio-keys");
if (!node) {
printk(KERN_ERR "Failed to find device tree node\n");
return -ENODEV;
}
gpio_num = of_get_named_gpio(node, "gpios", 0);
if (!gpio_is_valid(gpio_num)) {
printk(KERN_ERR "Invalid GPIO number\n");
return -EINVAL;
}
if (gpio_request(gpio_num, DRIVER_NAME)) {
printk(KERN_ERR "Failed to request GPIO\n");
return -EBUSY;
}
// IRQ 번호 요청
irq_num = gpio_to_irq(gpio_num);
if (irq_num < 0) {
printk(KERN_ERR "Failed to get IRQ number\n");
gpio_free(gpio_num);
return irq_num;
}
// ISR 등록
if (request_irq(irq_num, gpio_irq_handler, IRQF_TRIGGER_RISING, DRIVER_NAME, NULL)) {
printk(KERN_ERR "Failed to request IRQ\n");
gpio_free(gpio_num);
return -EBUSY;
}
printk(KERN_INFO "GPIO IRQ driver initialized\n");
return 0;
}
static void __exit gpio_irq_exit(void) {
free_irq(irq_num, NULL);
gpio_free(gpio_num);
printk(KERN_INFO "GPIO IRQ driver exited\n");
}
module_init(gpio_irq_init);
module_exit(gpio_irq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("GPIO IRQ Example for RK3399");
2.3 디바이스 트리 설정
드라이버에서 사용할 GPIO 핀과 IRQ는 디바이스 트리에서 정의해야 합니다. 아래는 rk3399-gpio.dtsi
에 추가할 디바이스 트리 예제입니다:
gpio-keys {
compatible = "gpio-keys";
gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
};
2.4 컴파일 및 테스트
- 위 코드를 저장하고 Makefile을 작성하여 모듈을 컴파일합니다.
- 모듈을 RK3399 보드에 로드합니다:
insmod rk3399_gpio_irq.ko
- 버튼을 눌러 인터럽트 발생 여부를 확인합니다.
3. 결론
이번 포스팅에서는 Linux에서 인터럽트 처리의 기본 개념과 Rockchip RK3399 보드를 기준으로 인터럽트 기반 드라이버를 작성하는 방법을 살펴보았습니다. 인터럽트는 실시간 이벤트 처리가 중요한 임베디드 시스템에서 필수적인 기술입니다. 다양한 인터럽트 처리 사례를 실습하며 이해를 심화해보세요.
728x90
반응형
'Linux > Kernel Driver' 카테고리의 다른 글
Embedded Linux Kernel 디버깅 가이드 (0) | 2025.03.26 |
---|---|
DMA(Direct Memory Access) 처리: 개념과 사용법, 그리고 RK3399 예제 (0) | 2025.03.25 |
USB Device Driver 작성 및 Linux Kernel에서 USB 인터페이스 사용 방법 (0) | 2025.03.23 |
USART Driver 작성 및 Linux Kernel에서의 USART 인터페이스 사용 방법 (0) | 2025.03.22 |
Embedded Linux에서 SPI Driver 작성하기 (Rockchip RK3399 기준) (0) | 2025.03.21 |