전역 변수를 이용해서 인터럽트를 할 경우 동기를 맞추기 위해 인터럽트의 금지와 해제를 이용한다.
이를 처리하는 루틴을 수행 할 때 특정 데이터가 인터럽트 서비스 함수에서 변경되어 이후 처리 루틴
에 영향을 미칠수 있기 때문에 예기치 못한 결과를 발생하게 된다. 이를 방지하기 위해서
// -----------------------------------------------------------------
kernel 2.6 에서 seqlock_t 구조체를 제공한다.
#include <linux/seqlock.h>
// 제어용 변수
seqlock_t the_lock = SEQLOCK_UNLOCKED;
unsigned int seq;
// 데이터 변경 루틴
write_seqlock(&the_lock);
// data change routine
write_sequnlock(&the_lock);
// 데이터 취득 루틴
do
{
seq = read_seqbegin(&the_lock);
// data value process routine
}
while read_seqretry(&the_lock, seq);
// example --------------------------------------------------------
seqlock_t the_lock = SEQLOCK_UNLOCKED;
unsigned int seq;
unsigned char ReadData = 0;
irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
write_seqlock(&the_lock);
ReadData = inb(IN_ADDR);
write_sequnlock(&the_lock);
return IRQ_HANDLED;
}
ssize_t xxx_read(struct fiel *filp, char *buf, size_t count, loff_t *f_pos)
{
do
{
seq = read_seqbegin(&the_lock);
if(ReadData)
{
// process routine
}
outb(ReadData | 0x80);
}
while read_seqretry(&the_lock, seq);
return 1;
}
이를 처리하는 루틴을 수행 할 때 특정 데이터가 인터럽트 서비스 함수에서 변경되어 이후 처리 루틴
에 영향을 미칠수 있기 때문에 예기치 못한 결과를 발생하게 된다. 이를 방지하기 위해서
// -----------------------------------------------------------------
kernel 2.6 에서 seqlock_t 구조체를 제공한다.
#include <linux/seqlock.h>
// 제어용 변수
seqlock_t the_lock = SEQLOCK_UNLOCKED;
unsigned int seq;
// 데이터 변경 루틴
write_seqlock(&the_lock);
// data change routine
write_sequnlock(&the_lock);
// 데이터 취득 루틴
do
{
seq = read_seqbegin(&the_lock);
// data value process routine
}
while read_seqretry(&the_lock, seq);
// example --------------------------------------------------------
seqlock_t the_lock = SEQLOCK_UNLOCKED;
unsigned int seq;
unsigned char ReadData = 0;
irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
write_seqlock(&the_lock);
ReadData = inb(IN_ADDR);
write_sequnlock(&the_lock);
return IRQ_HANDLED;
}
ssize_t xxx_read(struct fiel *filp, char *buf, size_t count, loff_t *f_pos)
{
do
{
seq = read_seqbegin(&the_lock);
if(ReadData)
{
// process routine
}
outb(ReadData | 0x80);
}
while read_seqretry(&the_lock, seq);
return 1;
}
'Linux > Device Driver' 카테고리의 다른 글
인터럽트 발생 횟수 확인 (0) | 2013.09.26 |
---|---|
인터럽트와 난수 발생 처리 (0) | 2013.09.26 |
인터럽트 발생금지 (0) | 2013.09.26 |
인터럽트 공유 (0) | 2013.09.26 |
인터럽트함수와 디바이스 드라이버간 데이터 공유 (0) | 2013.09.26 |