[질문] 리눅스 디바이스 드라이버 (유영창 저), 12장 인터럽트 예제
글쓴이: kko2913 / 작성시간: 수, 2010/10/27 - 9:04오후
책보고 공부하다 해결이 안되서 올립니다.
인터럽트 등록은 되는데 인터럽트가 호출이 안됩니다.
처음에는 등록이 안되었는데
rmmod parport_pc
rmmod ppdev
rmmod parport 를 해주고 나서 하니 등록은 돼더라구요...(request_irq()의 리턴값 0확인)
커널 버전은 2.6.25.15이고
Onboard Parallel Port - 378/IRQ7
Parallel Port Mode - SPP
프린터 포트의 사용선택은 바이오스 셋업 모드에서 나오지 않아서 선택 못했읍니다.
그리고 SA_INTERRUPT를 IRQF_DISABLED로 수정
코드는 아래에
좀 부탁드립니다...
// int_dev.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#define INT_DEV_NAME "intdev"
#define INT_DEV_MAJOR 240
#define INT_WRITE_ADDR 0x0378
#define INT_READ_ADDR 0x0379
#define INT_CTRL_ADDR 0x037A
#define PRINT_IRQ 7
#define PRINT_IRQ_ENABLE_MASK 0x10
#define INT_BUFF_MAX 64
typedef struct
{
unsigned long time;
} __attribute__ ((packed)) R_INT_INFO;
R_INT_INFO intbuffer[INT_BUFF_MAX];
int intcount = 0;
void int_clear( void )
{
int lp;
for(lp = 0; lp < INT_BUFF_MAX; lp++)
{
intbuffer[lp].time = 0;
}
intcount = 0;
}
irqreturn_t int_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//printk();
printk(KERN_EMERG "int_interrupt\n");
if( intcount < INT_BUFF_MAX )
{
intbuffer[intcount].time = get_jiffies_64();
intcount++;
}
return IRQ_HANDLED;
}
int int_open (struct inode *inode, struct file *filp)
{
printk(KERN_EMERG "int_open\n");
int a = request_irq( PRINT_IRQ , int_interrupt, IRQF_DISABLED, INT_DEV_NAME, NULL);
printk(KERN_EMERG "request_irq() : %d\n", a);
if(!a)
{
//printk(KERN_EMERG "111\n");
outb( PRINT_IRQ_ENABLE_MASK, INT_CTRL_ADDR );
}
int_clear();
return 0;
}
ssize_t int_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
int readcount;
char *ptrdata;
int loop;
//printk(KERN_EMERG "int_read - %d\n", intcount);
readcount = count / sizeof( R_INT_INFO );
if( readcount > intcount ) readcount = intcount;
ptrdata = (char * ) &intbuffer[0];
for( loop = 0; loop < readcount * sizeof(R_INT_INFO); loop++ )
{
put_user( ptrdata[loop], (char *) &buf[loop] );
}
return readcount * sizeof( R_INT_INFO );
}
ssize_t int_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
unsigned char status;
int loop;
int_clear();
for( loop = 0; loop < count; loop++ )
{
get_user( status, (char *) buf );
outb( status , INT_WRITE_ADDR );
}
return count;
}
int int_release (struct inode *inode, struct file *filp)
{
outb( 0x00, INT_CTRL_ADDR );
free_irq( PRINT_IRQ , NULL );
return 0;
}
struct file_operations int_fops =
{
.owner = THIS_MODULE,
.read = int_read,
.write = int_write,
.open = int_open,
.release = int_release,
};
int int_init(void)
{
int result;
result = register_chrdev( INT_DEV_MAJOR, INT_DEV_NAME, &int_fops);
if (result < 0) return result;
return 0;
}
void int_exit(void)
{
unregister_chrdev( INT_DEV_MAJOR, INT_DEV_NAME );
}
module_init(int_init);
module_exit(int_exit);
MODULE_LICENSE("Dual BSD/GPL"); // int_app.c
#include stdio.h>
#include sys/types.h>
#include sys/stat.h>
#include sys/ioctl.h>
#include fcntl.h>
#include unistd.h>
#define DEVICE_FILENAME "/dev/intdev"
typedef struct
{
unsigned long time;
} __attribute__ ((packed)) R_INT_INFO;
#define INT_BUFF_MAX 64
int main()
{
int dev;
R_INT_INFO intbuffer[INT_BUFF_MAX];
int intcount;
char buff[128];
int loop;
dev = open( DEVICE_FILENAME, O_RDWR|O_NDELAY );
if( dev >= 0 )
{
printf( "start...\n" );
buff[0] = 0xFF;
write(dev,buff,1 );
printf( "wait... input\n" );
while(1)
{
memset( intbuffer, 0, sizeof( intbuffer ) );
intcount = read(dev,(char *) &intbuffer[0],sizeof(R_INT_INFO) ) / sizeof(R_INT_INFO) ;
if( intcount ) break;
//sleep(1);
}
printf( "input ok...\n");
sleep(1);
memset( intbuffer, 0, sizeof( intbuffer ) );
printf( "read interrupt times\n" );
intcount = read(dev,(char *) intbuffer,sizeof(intbuffer) ) / sizeof(R_INT_INFO) ;
for( loop =0; loop < intcount; loop++ )
{
printf( "index = %d time = %ld\n", loop, intbuffer[loop].time );
}
printf( "led flashing...\n");
for( loop=0; loop<5; loop++ )
{
buff[0] = 0xFF;
write(dev,buff,1 );
sleep(1);
buff[0] = 0x00;
write(dev,buff,1 );
sleep(1);
}
close(dev);
}
return 0;
}Forums:


댓글 달기