- 论坛徽章:
- 0
|
大家好,我最近在编写tl16c554串口扩展的驱动,其中在读串口时候调用wait_event_interruptible ()函数等待串口接收数据的到来,以便唤醒read函数,而在串口接收中断处理中调用wake_up_interruptible()以唤醒读进程。现在问题是当用户按下CTRL+C时要中断读函数,而wait_event_interruptible怎么判断是CTRL+C信号中断,还是wake_up_interruptible()唤醒的呢。附上目前的我的问题代码请大家帮帮看看
中断处理函数
- static irqreturn_t uart0_irq_handle(int irq, void *dev_id, struct pt_regs *regs){
- volatile unsigned char lsr,isr;
- struct Queue *qCOM_rx_buf;
- int inc = 0;
- // printk(KERN_INFO" uart0 irq handled\n");
- unsigned long flag;
- local_irq_save(flag);
- if (!EXT_COM_USE[0])
- {
- //clear int
- readb(vEXT_COM_BASE_ADDR[0] + ISR);
- readb(vEXT_COM_BASE_ADDR[0] + RBR);
- readb(vEXT_COM_BASE_ADDR[0] + LSR);
- readb(vEXT_COM_BASE_ADDR[0] + MSR);
- printk(KERN_INFO"COM0 is not used\n");
- return IRQ_RETVAL(IRQ_HANDLED);
- }
- if ((qCOM_rx_buf = COM_rx_buf[0])){
- isr = readb(vEXT_COM_BASE_ADDR[0] + ISR);
- while(!(isr&0x01)) {
- isr=(isr&0x0E)>>1;
- switch(isr) {
- case 3:
- readb(vEXT_COM_BASE_ADDR[0] + LSR);
- break;
- case 2:
- case 4:
- case 6:
- while ((!qCOM_rx_buf->full) && ((lsr = readb(vEXT_COM_BASE_ADDR[0] + LSR))& 0x01)) {
- //recive data ready, read later is clear
- if(!(lsr & 0x8a))
- {
- if(++(qCOM_rx_buf->rear) == (qCOM_rx_buf->buf+qCOM_rx_buf->num)){
- qCOM_rx_buf->rear = qCOM_rx_buf->buf;
- }
- if (qCOM_rx_buf->rear == qCOM_rx_buf->front){
- qCOM_rx_buf->full = 1;
- }
- *(qCOM_rx_buf->rear) = readb(vEXT_COM_BASE_ADDR[0] + RBR);
- //printk("recv data is : %x \n",*(qCOM_rx_buf->rear));
-
- rmb();
- inc++;
- }
- else//data error
- {
- //printk("recv data error,lsr is %d\n",lsr);
- readb(vEXT_COM_BASE_ADDR[0] + RBR);
- }
- }
- if (inc){
- qCOM_rx_buf->emp = 0;
- wake_up_interruptible(rx_queue[0]);
- }
- break;
-
-
- // printk("Character time-out indicator\n");
- //break;
- case 0:
- readb(vEXT_COM_BASE_ADDR[0] + MSR);
- //printk("Modem status int \n");
- break;
- default:
-
- printk("Unknow interrupt type : 0x%x!\n",isr);
- break;
- }
- isr = readb(vEXT_COM_BASE_ADDR[0] + ISR);
- }//end while
- local_irq_restore(flag);
- }
- return IRQ_RETVAL(IRQ_HANDLED);[code]
复制代码
}
[/code]
读函数
- static ssize_t uart_read(struct file *filp, char *buf, size_t count, loff_t *f_pos){
- unsigned long flag;
- char rx_buf[BUFSIZE];
- size_t rx_buf_count = 0;
- //unsigned int i;
- struct inode *inode = filp->private_data;
- struct Queue *qCOM_rx_buf = COM_rx_buf[MINOR(inode->i_rdev)];
- printk("uart_read MINOR is %d, filp->f_count is %d\n", MINOR(inode->i_rdev),
- (filp->f_count));
- //local_irq_save(flag);
- while (rx_buf_count < count){
- if (!qCOM_rx_buf->emp){
- if (++qCOM_rx_buf->front == (qCOM_rx_buf->buf + qCOM_rx_buf->num)) {
- qCOM_rx_buf->front = qCOM_rx_buf->buf;
- }
- if (qCOM_rx_buf->front == qCOM_rx_buf->rear){
- qCOM_rx_buf->emp = 1;//is empty
- }
- rx_buf[rx_buf_count++] = *qCOM_rx_buf->front;
- qCOM_rx_buf->full = 0;
- }
- else{
- if(wait_event_interruptible(*(rx_queue[MINOR(inode->i_rdev)]),!qCOM_rx_buf->emp) == -ERESTARTSYS);
- return -ERESTARTSYS;
- //printk(KERN_INFO"out sleep\n");
- }
- }
- copy_to_user(buf, rx_buf, rx_buf_count);
- //local_irq_restore(flag);
- return rx_buf_count;
- }
复制代码
目前如果有串口数据达到或按下CTRL+C,read函数都会返回,而注释掉return -ERESTARTSYS;
时驱动又无法响应CTRL+C,请问大侠们应该如何改动 |
|