2011. 10. 13. 17:53
실제 인터럽트 핸들러 OS이야기2011. 10. 13. 17:53
RTC 드라이버인 drivers/char/rtc.c 에 있는 인터럽트 핸들러이다.
RTC드라이버가 로드되면 우선 드라이버를 초기화하기 위해 rtc_init()가 호출된다.
이 함수의 역할 중하나는 인터럽트 핸들러를 등록하는 것
if(request_irq(RTC_IRQ,trc_interrupt, SA_INTERRUPT,"rtc",NULL)
{
RTC드라이버가 로드되면 우선 드라이버를 초기화하기 위해 rtc_init()가 호출된다.
이 함수의 역할 중하나는 인터럽트 핸들러를 등록하는 것
if(request_irq(RTC_IRQ,trc_interrupt, SA_INTERRUPT,"rtc",NULL)
{
printk(KERN_ERR"rtc : cannot register IRQ %d\n", RTC_IRQ);
return -EIO;
return -EIO;
}
static irqreturn_t rtc_interrupt(int irq, void *dev_id)
240{ 241 /* 242 * Can be an alarm interrupt, update complete interrupt, 243 * or a periodic interrupt. We store the status in the 244 * low byte and the number of interrupts received since 245 * the last read in the remainder of rtc_irq_data. 246 */ 247 248 spin_lock(&rtc_lock); 249 rtc_irq_data += 0x100; 250 rtc_irq_data &= ~0xff; 251 if (is_hpet_enabled()) { 252 /* 253 * In this case it is HPET RTC interrupt handler 254 * calling us, with the interrupt information 255 * passed as arg1, instead of irq. 256 */ 257 rtc_irq_data |= (unsigned long)irq & 0xF0; 258 } else { 259 rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); 260 } 261 262 if (rtc_status & RTC_TIMER_ON) 263 mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); 264 265 spin_unlock(&rtc_lock); 266 267 /* Now do the rest of the actions */ 268 spin_lock(&rtc_task_lock); 269 if (rtc_callback) 270 rtc_callback->func(rtc_callback->private_data); 271 spin_unlock(&rtc_task_lock); 272 wake_up_interruptible(&rtc_wait); 273 274 kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); 275 276 return IRQ_HANDLED; 277}
rtc_irq_data와 rtc_callback 변수를 serializable해준다.
rtc_irq_data는 RTC에 대한 정보를 저장하는 unsigned long 타입의 변수이며, 인터럽트의 현재 상태를 반영하기 위해 인터럽트가 발생할 때마다 갱신된다.
'OS이야기' 카테고리의 다른 글
인터럽트 핸들링구현 (0) | 2011.10.13 |
---|---|
인터럽트 컨텍스트 (0) | 2011.10.13 |
load_balance() (0) | 2011.10.13 |
Sleep And Block (0) | 2011.10.13 |
우선순위와 타임슬라이스계산 (0) | 2011.10.13 |