免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3742 | 回复: 4
打印 上一主题 下一主题

atmel_interrupt中断 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-12 12:27 |只看该作者 |倒序浏览
20可用积分
EBD9260的板子我们想要在中断函数中做些修改,先遇到了问题,想请教.

/*

* Interrupt handler

*/

static irqreturn_t atmel_interrupt(int irq, void *dev_id)

{

        struct uart_port *port = dev_id;

        struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;

        unsigned int status, pending, imr,pass_counter = 0;



        status = UART_GET_CSR(port);

        imr = UART_GET_IMR(port);

        pending = status & imr;

        //pending = status & UART_GET_IMR(port);

        while (pending) {



printk(KERN_INFO "atmel_interrupt:534,irq=[%d],imr=[0x%08x],csr=[0x%08x]\n",irq,imr,status);


              /* PDC receive */

              if (pending & ATMEL_US_ENDRX)

                    at91_pdc_endrx(port);

              if (pending & ATMEL_US_TIMEOUT)

                    at91_pdc_timeout(port);

              if (atmel_port->use_dma_rx && pending & (ATMEL_US_RXBRK | ATMEL_US_OVRE | ATMEL_US_FRAME | ATMEL_US_PARE))

                    at91_pdc_rxerr(port, pending);



              /* Interrupt receive */

              if (pending & ATMEL_US_RXRDY)

                    atmel_rx_chars(port);



              // TODO: All reads to CSR will clear these interrupts!

              if (pending & ATMEL_US_RIIC) port->icount.rng++;

              if (pending & ATMEL_US_DSRIC) port->icount.dsr++;

              if (pending & ATMEL_US_DCDIC)

                    uart_handle_dcd_change(port, !(status & ATMEL_US_DCD));

              if (pending & ATMEL_US_CTSIC)

                    uart_handle_cts_change(port, !(status & ATMEL_US_CTS));

              if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | ATMEL_US_CTSIC))

                    wake_up_interruptible(&port->info->delta_msr_wait);



              /* PDC transmit */

              if (pending & ATMEL_US_ENDTX)

                    at91_pdc_endtx(port);

              if (pending & ATMEL_US_TXBUFE)

                    at91_pdc_txbufe(port);



              /* Interrupt transmit */

              if (pending & ATMEL_US_TXRDY)

                    atmel_tx_chars(port);



              if (pass_counter++ > ATMEL_ISR_PASS_LIMIT)

                    break;



              status = UART_GET_CSR(port);

              pending = status & UART_GET_IMR(port);

      }

      return IRQ_HANDLED;

}

测试:板子上运行./uart_test,从DNW发送一个字符,

printk(KERN_INFO "atmel_interrupt:534,irq=[%d],imr=[0x%08x],csr=[0x%08x]\n",irq,imr,status);


上面的打印信息出现了3次.如下:
atmel_interrupt:534,irq=[8],imr=[0x000001e8],csr=[0x00800b12]
atmel_interrupt:534,irq=[8],imr=[0x000009f8],csr=[0x00800a12]
atmel_interrupt:534,irq=[8],imr=[0x000009f8],csr=[0x00800810]
1.我理解应该2次就可以,实在不知道多的一次是从哪里来的?
2.还有中断屏蔽寄存器是只读的,上面的信息是2次值是一样的,不知道中断屏蔽寄存器的值是怎么变化的?

Tks!

最佳答案

查看完整内容

发送的次数我们可以控制,但是接收的不一定的,是2次也很正常。检查你的调试环境,确保其不要被干扰。IMR的肯定不是readonly的,你哪里设置错了。原因是:IMR在变化,所以肯定不是readonly,readonly是你认为的,但不是事实。检查你的代码吧,如果是用系统的框架,肯定是你用错了,或者理解错了,如果没用框架,那肯定还是你错了

论坛徽章:
0
2 [报告]
发表于 2008-11-12 12:27 |只看该作者

回复 #3 againyuan 的帖子

发送的次数我们可以控制,但是接收的不一定的,是2次也很正常。检查你的调试环境,确保其不要被干扰。

IMR的肯定不是readonly的,你哪里设置错了。原因是:

IMR在变化,所以肯定不是readonly,readonly是你认为的,但不是事实。检查你的代码吧,如果是用系统的框架,肯定是你用错了,或者理解错了,如果没用框架,那肯定还是你错了

论坛徽章:
0
3 [报告]
发表于 2008-11-12 13:50 |只看该作者
不懂,UP

论坛徽章:
0
4 [报告]
发表于 2008-11-12 15:08 |只看该作者
多谢楼上的
1 接收和发送都要经过这个atmel_interrupt函数,那么就应该有2行打印信息,可是我却得到了3行,所以不知道多出的是什么?
  从打印信息来看,都是中断号8,也就是说都是串口的中断位引起的,csr就是状态寄存器.csr最低2位:bit 1:TXRDY,bit0:RXRDY.

2 IMR确实read_only,但是一直在变化

论坛徽章:
0
5 [报告]
发表于 2008-11-20 21:11 |只看该作者

回复 #4 samon_fu 的帖子

OK
IMR是readonly,但是可以通过IER,IDR来修改.这是atmel的arm的特性,这样可以防止不同进程对32bit中的一位进行修改产生的相互干扰.
因为程序很负责,还有DMA的设置,所以dma和普通接收都有了.
谢谢大家
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP