Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 9. Interrupt Handling

Similar presentations


Presentation on theme: "Chapter 9. Interrupt Handling"— Presentation transcript:

1 Chapter 9. Interrupt Handling
인터럽트 허용 및 금지 인터럽트 핸들러 등록 short-int 예 순천향대학교 정보기술공학부 이 상 정

2 단원 소개 인터럽트는 외부 하드웨어가 프로세서에 보내는 시그널 인터럽트의 예를 보이기 위해서는 실제 하드웨어가 필요
리눅스에서 인터럽트는 사용자 영역에서 시그널과 유사하게 동작 드라이버는 디바이스의 인터럽트를 위해 핸들러를 등록하고 인터럽트 시그널의 도착 시 핸들러를 실행 인터럽트의 예를 보이기 위해서는 실제 하드웨어가 필요 앞 장의 short 모듈을 사용하여 병렬포트로 인터럽트를 생성 예 소개 순천향대학교 정보기술공학부 이 상 정

3 인터럽트 허용 및 금지 순천향대학교 정보기술공학부 이 상 정

4 cli(), sti() 함수 (1) 인터럽트를 금지시키고 허용하는 함수로 유닉스에서 사용했던 cli()와 sti() 함수가 사용 인터럽트 금지 예 unsigned long flags; save_flags(flags); cli(); /* This code runs with interrupts disabled */ restore_flags(flags); 여기서 save_flags은 매크로 save_flags와 restore_flags는 같은 함수에서 호출되어야 함 순천향대학교 정보기술공학부 이 상 정

5 cli(), sti() 함수 (2) 최신 리눅스에서는 cli(), sti() 함수의 직접 사용 바람직하지 않음
특정 루틴이 호출될 때 인터럽트가 허용되었는지 여부를 아는 것이 점점 더 어려워 짐 멀티프로세서 시스템에서 critical code가 단순히 인터럽트를 금지하여 보호받을 수 없고 locking mechanism과 함께 사용되어야 함 이장의 “Using Spinlocks”에서 소개될 spin_lock_irqsave 함수 등이 사용 cli는 시스템 상의 모든 프로세서들의 인터럽트를 금지하여 시스템의 성능에 영향을 미침 순천향대학교 정보기술공학부 이 상 정

6 병렬포트 인터럽트 병렬포트는 인터럽트를 트리거 인터럽트 인가
병렬인터페이스에서 제어포트(0x37a, 0x27a, 0x3be)의 비트 4를 세팅하면 인터럽트가 허용 short 모듈 초기화에서 간단히 이 비트의 세팅하는 outb의 호출하여 허용 인터럽트 인가 인터럽트 허용되면 병렬 인터페이스의 핀 10(ACK 비트)에 0->1의 신호가 입력하여 인터럽트 인가 병렬 인터페이스에서 핀 9와 10을 연결하여 간단하게 강제적인 인터럽트를 인가 핀 9는 병렬 데이터 바이트의 MSB /dev/short0에 이진 데이터 쓰기를 하면 인터럽트를 생성 ASCII 텍스트인 경우 MSB가 0이기 때문에 인터럽트를 발생시키지 않음 순천향대학교 정보기술공학부 이 상 정

7 인터럽트 핸들러 등록 순천향대학교 정보기술공학부 이 상 정

8 IRQ 등록 모듈은 사용 전에 인터럽트 요청 채널(IRQ)을 요청하고 종료 시 이를 해제
인터럽트 처리하는 소프트웨어 핸들러도 등록 I/O 포트 등록과 유사하게 인터럽트 라인을 등록하고 관리 IRQ는 인터럽트 라인은 부족하고 값비싼 자원(15-16개)으로 대개 다른 드라이버와 공유 <linux/sched.h>에 정의된 인터럽트 요청 함수 int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id); 성공인 경우 0을 리턴하고 실패인 경우 음수의 에러 코드를 리턴 void free_irq(unsigned int irq, void *dev_id) 순천향대학교 정보기술공학부 이 상 정

9 인터럽트 요청함수 인수 인수의 의미 unsigned int irq 요청된 인터럽트 번호
void (*handler)(int, void *, struct pt_regs *) 설정되는 인터럽트 핸들러 함수 unsigned long flags 인터럽트 관리와 관련된 옵션들의 비트 마스크 SA_INTERRUPT: 빠른 인터럽트 핸들러를 표시 SA_SHIRQ: 디바이스들 간에 인터럽트 공유 SA_SAMPLE_RANDOM: 난수 생성 엔트로피 풀 구성 const char *dev_name 인터럽트의 소유자를 표시하는 문자열 void *dev_id 인터럽트 라인의 공유를 위해 사용된다. 인터럽트 라인이 해제될 때 사용되는 고유의 식별자 순천향대학교 정보기술공학부 이 상 정

10 short 예 short 예제에서는 short_init()에서 인터럽트 등록
다음은 short_irq의 인터럽트를 요청하는 코드 if (short_irq >= 0) { result = request_irq(short_irq, short_interrupt, SA_INTERRUPT, "short", NULL); if (result) { printk(KERN_INFO "short: can’t get assigned irq %i\n", short_irq); short_irq = -1; } else { /* actually enable it -- assume this *is* a parallel port */ outb(0x10,short_base+2); } } 순천향대학교 정보기술공학부 이 상 정

11 /proc/interrupts 등록된 IRQ에 대한 인터럽트 요청 카운트 표시 CPU0 CPU1
0: IO-APIC-edge timer 1: IO-APIC-edge keyboard 2: XT-PIC cascade 5: IO-APIC-level eth0 9: IO-APIC-level acpi 10: IO-APIC-level aic7xxx 12: IO-APIC-edge PS/2 Mouse 13: XT-PIC fpu 15: IO-APIC-edge ide1 NMI: LOC: ERR: 첫번째 열은 IRQ 번호, 두번째와 세번째 열은 각 CPU에 요청된 인터럽트 카운트를 표시하고, 네번째 열은 PIC(programmable interrupt controller)에 대한 정보이고, 마지막 열은 등록된 인터럽트 핸들러를 사용하는 디바이스의 이름 순천향대학교 정보기술공학부 이 상 정

12 IRQ 번호의 자동검출(autodetecting)
다음은 디폴트로 병렬포트를 사용하는 short의 코드 예 if (short_irq < 0) /* not yet specified: force the default on */ switch(short_base) { case 0x378: short_irq = 7; break; case 0x278: short_irq = 2; break; case 0x3bc: short_irq = 5; break; } 위 코드는 선택된 기본 I/O 주소에 따라 IRQ 번호를 지정 사용자는 로드 시 다음과 같이 디폴트 값을 변경 insmod ./short.o short_irq=x 순천향대학교 정보기술공학부 이 상 정

13 IRQ 가용 커널 조사 가용한 IRQ 조사 <linux/interrupt.h>에서 선언된 인터럽트 조사 함수
unsigned long probe_irq_on(void); 할당되지 않은 가용한 인터럽트 IRQ들의 비트 마스크를 리턴 드라이버는 디바이스가 최소한 하나의 인터럽트를 발생시키고, 리턴된 비트 마스크를 다음의 probe_irq_off 에 전달 int probe_irq_off(unsigned long); 디바이스가 인터럽트를 요청한 후 드라이버는 probe_irq_on의 리턴 값을 갖고 이 함수를 호출 “probe_on” 후 이슈되었던 인터럽트의 번호를 리턴 어떤 인터럽트도 일어나지 않았으면 0을 리턴 순천향대학교 정보기술공학부 이 상 정

14 short 예 int count = 0; do { unsigned long mask; mask = probe_irq_on(); outb_p(0x10,short_base+2); /* enable reporting */ outb_p(0x00,short_base); /* clear the bit */ outb_p(0xFF,short_base); /* set the bit: interrupt! */ outb_p(0x00,short_base+2); /* disable reporting */ udelay(5); /* give it some time */ short_irq = probe_irq_off(mask); if (short_irq == 0) { /* none of them? */ printk(KERN_INFO "short: no irq reported by probe\n"); short_irq = -1; } /* * If more than one line has been activated, the result is * negative. We should service the interrupt (no need for lpt port) * and loop over again. Loop at most five times, then give up */ } while (short_irq < 0 && count++ < 5); if (short_irq < 0) printk("short: probe failed %i times, giving up\n", count); 순천향대학교 정보기술공학부 이 상 정

15 자율조사(do-it-yourself probing)
자율조사는 기본적으로 앞의 방식과 유사 모든 사용하지 않은 인터럽트들을 인에이블 시키고 기다린 후 무엇 발생한지를 조사 short 모듈 로딩 시 probe=2로 지정하면 자율검사로 동작 short 구현에서는 3,5,7,9 가 가능한 IRQ라고 가정 병렬포트에서 사용되는 번호 인터럽트를 조사하는 코드에서 배열 trial은 가능한 IRQ들의 리스트이고 배열 tried는 실제 이 드라이버에 의해 등록된 IRQ를 추적하는데 사용 IRQ 가용 시 인터럽트 핸들러 short_probing() 호출 순천향대학교 정보기술공학부 이 상 정

16 short 예 (1) void short_selfprobe(void) {
int trials[] = {3, 5, 7, 9, 0}; int tried[] = {0, 0, 0, 0, 0}; int i, count = 0; /* * install the probing handler for all possible lines. Remember * the result (0 for success, or -EBUSY) in order to only free * what has been acquired */ for (i=0; trials[i]; i++) tried[i] = request_irq(trials[i], short_probing, SA_INTERRUPT, "short probe", NULL); do { short_irq = 0; /* none got, yet */ outb_p(0x10,short_base+2); /* enable */ outb_p(0x00,short_base); outb_p(0xFF,short_base); /* toggle the bit */ outb_p(0x00,short_base+2); /* disable */ udelay(5); /* give it some time */ /* the value has been set by the handler short_probing */ 순천향대학교 정보기술공학부 이 상 정

17 short 예 (2) if (short_irq == 0) { /* none of them? */
printk(KERN_INFO "short: no irq reported by probe\n"); } /* * If more than one line has been activated, the result is * negative. We should service the interrupt (but the lpt port * doesn't need it) and loop over again. Do it at most 5 times */ } while (short_irq <=0 && count++ < 5); /* end of loop, uninstall the handler */ for (i=0; trials[i]; i++) if (tried[i] == 0) free_irq(trials[i], NULL); if (short_irq < 0) printk("short: probe failed %i times, giving up\n", count); void short_probing(int irq, void *dev_id, struct pt_regs *regs) { if (short_irq == 0) short_irq = irq; /* found */ if (short_irq != irq) short_irq = -irq; /* ambiguous */ 순천향대학교 정보기술공학부 이 상 정

18 short-probe, 커널 조사 # sh short_load probe=1 => 커널조사
# cat /proc/interrupts CPU0 0: XT-PIC timer 1: XT-PIC keyboard 2: XT-PIC cascade 7: XT-PIC short 8: XT-PIC rtc 11: XT-PIC eth0 12: XT-PIC usb-uhci, PS/2 Mouse 14: XT-PIC ide0 15: XT-PIC ide1 NMI: ERR: 순천향대학교 정보기술공학부 이 상 정

19 short-probe,자율 조사 # sh short_load probe=2 => 자율조사
# cat /proc/interrupts CPU0 0: XT-PIC timer 1: XT-PIC keyboard 2: XT-PIC cascade 7: XT-PIC short 8: XT-PIC rtc 11: XT-PIC eth0 12: XT-PIC usb-uhci, PS/2 Mouse 14: XT-PIC ide0 15: XT-PIC ide1 NMI: ERR: 순천향대학교 정보기술공학부 이 상 정

20 short-int 예 순천향대학교 정보기술공학부 이 상 정

21 인터럽트 핸들러 역할 인터럽트 핸들러의 역할 인터럽트 핸들러의 대표적인 작업은 새로운 데이터의 도착 등과 같이 기다리던 이벤트가 발생되어 인터럽트 신호가 오면 해당 디바이스 상에서 수면 중인 프로세스들을 깨움 인터럽트 발생 시 디바이스에 피드백을 제공하고 서비스되는 인터럽트에 따라 데이터 읽기나 쓰기를 수행 핸들러는 먼저 인터페이스 보드의 비트를 클리어 대부분의 하드웨어 디바이스들은 인터럽트-보류(interrupt-pending) 비트가 클리어될 때까지 다른 인터럽트를 금지 일부 디바이스들은 인터럽트-보류 비트들을 가지고 있지 않아서 이 과정이 생략 병렬포트는 이 부류에 속하기 때문에 short 모듈에서는 이 비트를 클리어하는 과정이 생략 순천향대학교 정보기술공학부 이 상 정

22 인터럽트 핸들러 코드 제한 인터럽트 핸들러 코드 작성 제한 인터럽트 모드에서 동작은 태스크 큐의 제약과 동일
인터럽트 핸들러 코드 작성 제한 인터럽트 모드에서 동작은 태스크 큐의 제약과 동일 핸들러는 프로세스의 컨텍스트 상에서 실행되지 않기 때문에 사용자 영역과 데이터 전송을 할 수 없음 핸들러는 sleep_on 등을 호출하여 수면에 들어갈 수도 없음 메모리 할당은 GFP_ATOMIC으로 해야 함 핸들러는 schedule() 함수를 호출할 수 없음 순천향대학교 정보기술공학부 이 상 정

23 short-int 예 인터럽트 발생 시 마다 현재시간을 버퍼에 쓰기 수행 디바이스 읽기로 버퍼의 시간 출력
인터럽트는 병렬포트 디바이스에 쓰기를 수행하면 두 문자마다 한 번씩 인터럽트 발생 병렬 커넥터의 핀 9와 10을 연결되어 병렬 데이터 바이트의 MSB를 0->1로 하면 인터럽트를 생성 /dev/short0에 이진 데이터 쓰기를 하거나 /dev/shortint에 임의의 문자를 쓰기하여 수행 /dev/shortint는 병렬포트에 0x00과 0xff를 번갈아 가며 쓰기를 하여 인터럽트 생성 순천향대학교 정보기술공학부 이 상 정

24 short-int 인터럽트 핸들러 void short_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct timeval tv; int written; do_gettimeofday(&tv); /* Write a 16-byte record. Assume PAGE_SIZE is a multiple of 16 */ written = sprintf((char *)short_head,"%08u.%06u\n", (int)(tv.tv_sec % ), (int)(tv.tv_usec)); short_incr_bp(&short_head, written); wake_up_interruptible(&short_queue); /* wake any reading process */ } static inline void short_incr_bp(volatile unsigned long *index,int delta) unsigned long new = *index + delta; barrier (); /* Don’t optimize these two together */ *index = (new >= (short_buffer + PAGE_SIZE)) ? short_buffer : new; 순천향대학교 정보기술공학부 이 상 정

25 short-int 읽기 ssize_t short_i_read (struct file *filp, char *buf, size_t count, loff_t *f_pos) { int count0; while (short_head == short_tail) { interruptible_sleep_on(&short_queue); if (signal_pending (current)) /* a signal arrived */ return -ERESTARTSYS; /* tell the fs layer to handle it */ /* else, loop */ } /* count0 is the number of readable data bytes */ count0 = short_head - short_tail; if (count0 < 0) /* wrapped */ count0 = short_buffer + PAGE_SIZE - short_tail; if (count0 < count) count = count0; if (copy_to_user(buf, (char *)short_tail, count)) return -EFAULT; short_incr_bp (&short_tail, count); return count; 순천향대학교 정보기술공학부 이 상 정

26 short-int 쓰기 ssize_t short_i_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos) { int written = 0, odd = *f_pos & 1; unsigned long address = short_base; /* output to the parallel data latch */ if (use_mem) { while (written < count) writeb(0xff * ((++written + odd) & 1), address); } else { outb(0xff * ((++written + odd) & 1), address); } *f_pos += count; return written; 순천향대학교 정보기술공학부 이 상 정

27 short-int 실행 예 (1) # cat /proc/modules short 10944 0 (unused)
lp (autoclean) …… # cat /proc/interrupts CPU0 0: XT-PIC timer 1: XT-PIC keyboard 2: XT-PIC cascade 7: XT-PIC short 8: XT-PIC rtc 11: XT-PIC eth0 # echo -n "123456" > /dev/shortint => 인터럽트 3번 인가, 인가 시 마다 인터럽트 핸들러가 버퍼에 발생시점 저장 # cat /dev/shortint => 버퍼에 저장된 내용 읽기 ctrl+c => 읽기 메쏘드에서 버퍼가 빈 경우 sleep 순천향대학교 정보기술공학부 이 상 정

28 short-int 실행 예 # cat /proc/interrupts CPU0 …… 7: 37 XT-PIC short
8: XT-PIC rtc …… # cat /dev/shortint& [2] 3766 # echo -n "xyz" > /dev/shortint 순천향대학교 정보기술공학부 이 상 정

29 과제 실행, 결과 및 코드 분석 short-int 소스 예 분석 실행 및 테스트 병렬포트 핀 9와 10을 연결
순천향대학교 정보기술공학부 이 상 정


Download ppt "Chapter 9. Interrupt Handling"

Similar presentations


Ads by Google