[질문] 리눅스 디바이스 드라이버 (유영창 저), 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:
댓글 달기