Problem in interrupt handler for uart 16550
Hi,
i am writing a serial driver for UART 16550 .For that i have recompiled the kernel and inserted generic driver as a module.in OPEN i have initialized all the registers and at the end i have enabled the interrupts .Handler is registered succesfully .interrupt is generated but sequence is not going into handler. PLEASE HELP ME |
Kinda hard to do that, friend. We don't have your code, and what is more, probably couldn't do too much to help. Try looking for other examples of serial-device-driver code. Compare their code to yours...
|
this is my code in kernel space
#define MODULE #define __KERNEL__ #include<linux/module.h> #include<linux/kernel.h> #include<linux/sched.h> #include<linux/interrupt.h> #include<linux/fs.h> #include<asm/current.h> #include<linux/ioport.h> #include<asm/io.h> #include<errno.h> #include<asm/uaccess.h> #include<linux/init.h> #include<linux/delay.h> #include "defs.h" #include "serialcmd.h" #define MAX 20 #define NAME lifo MODULE_LICENSE("GPL"); static INT32S divisor; static INT8U setparity; static INT8U kbuff[MAX]; static INT32U i,result,STAT,time_out=0; static BOOLEAN FLAG=0; DECLARE_WAIT_QUEUE_HEAD(my_q); static INT32S lifo_open(struct inode *, struct file *); ssize_t lifo_read(struct file *,char *,size_t , loff_t *); ssize_t lifo_write(struct file *,const char *,size_t , loff_t *); static int lifo_close(struct inode *,struct file *); static int lifo_ioctl(struct inode *inode,struct file *filep,unsigned int cmd,unsigned long arg); static int lifo_ioctl(struct inode *inode,struct file *filep,unsigned int cmd,unsigned long arg) { time_out=arg; } void serial_handler(INT32S irq_num,void *dev_id,struct pt_regs *regs) { printk("\n Irq number is %d ", irq_num); static INT8U ch; static INT32U len; STAT = inb_p(IIR); printk("\n status is %x",STAT); STAT &=0x06; printk("\n Change due to ANDing with 0x06 in status is %x",STAT); switch(STAT) { /*writing the characters to transmit register */ case 2: len = strlen(kbuff); if(FLAG == 1) { for(i=0; i<len; i++) outb_p(kbuff[i],BASE+0); i=0; FLAG = 0; } break; /* reading the characters from the receive register */ case 4: i = 0; while((ch = inb_p(BASE+0)) !='\0') kbuff[i++] = ch; break; default: break; } } static INT32S lifo_open(struct inode *inode, struct file *filep) { static int result; printk("\n In open , Initialising all needed registers\n"); outb(0x07, IER); outb(0x87, FCR); outb(0x03, LCR); result = request_irq(4,serial_handler,0,"my_origin",(void*)1234); if(result < 0) { printk("\n Error in requesting Irq\n"); return result; } printk("\n Handler is requested\n"); return 0; } /*Here we will get the irq line no. and the control will be transferred to serial_handler which is interrupt handler*/ ssize_t lifo_read(struct file *filep,char *ubuff,size_t len, loff_t *offset) { time_out=time_out*101; printk("\n In read \n"); if (i==0) { copy_to_user(ubuff,"\n No data available\n",20); /* if(time_out==0) { sleep_on(&my_q); copy_to_user((void *)ubuff,(void *)kbuff,i); } else { sleep_on_timeout(&my_q,time_out); copy_to_user((void *)ubuff,(void *)kbuff,i); time_out=0; }*/ } else { printk("i=%d",i); printk("time out=%d",time_out); copy_to_user((void *)ubuff,(void *)kbuff,i); } return i; } ssize_t lifo_write(struct file *filep,const char *ubuff,size_t len, loff_t *offset) { STAT = inb_p(LCR); STAT &= 0x7f; outb(STAT,LCR); result=copy_from_user((void *)kbuff,(void *)ubuff,20); FLAG = 1; printk("\n Write succeed %c \n",ubuff[0]); wake_up(&my_q); return 0; } static int lifo_close(struct inode *inode,struct file *filep) { free_irq(4,(void *)1234); printk("\nWe've closed the device"); return 0; } struct file_operations fops= { open: lifo_open, read: lifo_read, release: lifo_close, write: lifo_write, ioctl: lifo_ioctl }; int register_dd(void) { int result; printk("\nThe device is registerered"); result=register_chrdev(254,"lifo",&fops); if(result<0) { printk("error"); return(result); } return 0; } void unregister_dd(void) { printk("\nThe device is unregistered"); unregister_chrdev(254,"lifo"); } module_init(register_dd); module_exit(unregister_dd); I have recompiled the kernel 2.4.21-ELsmp and inserted Generic driver as module also and i have removed serial moule also and inserted my own module but unable to go into interrupt handler.my user space code is #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include"serialcmd.h" #define MAX 20 main() { int fd,ch,choice,result,time_out,cont; char ubuff[MAX]; do { system("clear"); printf("\nEnter 1 to open the serial device"); printf("\nEnter 2 to close the serial device"); printf("\nEnter 3 to read from the serial device"); printf("\nEnter 4 to write to the serial device"); printf("\nEnter your choice:"); scanf("%d",&choice); switch(choice) { case 1: fd=open("/dev/lifo",O_RDWR); if(fd==-1) { perror("\nError in opening the device"); return -1; } break; case 2: result=close(fd); if(result=-1) { perror("\nError in closing the device"); return -1; } break; case 3: system("clear"); printf("\nPress '1' to read characters\n"); printf("\nPress '2' to read timed out charaters\n"); fflush(stdout); printf("\nEnter your choice:\n"); fflush(stdin); scanf("%d",&ch); switch(ch) { case 1: result=read(fd,ubuff,strlen(ubuff)); printf("%s",ubuff); break; case 2: printf("\nEnter the time out value in seconds:"); scanf("%d",&time_out); result=ioctl(fd,TIME_OUT,time_out); /* if(result=-1) { perror("\nError in closing the device"); return -1; }*/ result=read(fd,ubuff,strlen(ubuff)); /*if(result=-1) { perror("\nError in closing the device"); return -1; }*/ printf("%s",ubuff); break; default: printf("\nEnter a valid choice"); } break; case 4: printf("\nEnter the string to write:"); scanf("%s",ubuff); result=write(fd,ubuff,strlen(ubuff)); /*if(result=-1) { perror("\nError in closing the device"); return -1; }*/ break; default: printf("\nEnter a valid choice"); } system("clear"); printf("\nEnter 1 to continue, any other key to exit:"); fflush(stdin); scanf("%d",&cont); }while(cont==1); } ANY device driver specialist help me please. |
hi all ,
control is not gonig in Interrupt handler ,i have checked IIR register it is showing that interrupt has occured .i have already given my code i have also checked /proc/interrupt it is not showing any entry for IRQ 4 please anyone help me to sort out this problem. thanks®ards Mrinal |
All times are GMT -5. The time now is 07:17 PM. |