Chinaunix首页 | 论坛 | 博客
  • 博客访问: 493302
  • 博文数量: 118
  • 博客积分: 5003
  • 博客等级: 大校
  • 技术积分: 1213
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-07 20:29
文章存档

2011年(8)

2010年(4)

2009年(12)

2008年(85)

2007年(9)

我的朋友

分类: LINUX

2008-06-04 15:28:32

    一个疑问:9260串口驱动是如何工作的?很奇怪,这两天我一直在考虑串口数据的中断接收数据,但是我在网上搜索基本上所有的帖子,采用的都是查询接收数据。逼得我今天不得不自己去看驱动。
    看完之后我就发现一个很奇怪的现象:
    我明明申请了7个uart口,但是为什么在/proc/interrupt中只看到一个中断?
    dmesg:
    <6>atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
<6>atmel_usart.1: ttyS1 at MMIO 0xfffb0000 (irq = 6) is a ATMEL_SERIAL
<6>atmel_usart.2: ttyS2 at MMIO 0xfffb4000 (irq = 7) is a ATMEL_SERIAL
<6>atmel_usart.3: ttyS3 at MMIO 0xfffb8000 (irq = 8) is a ATMEL_SERIAL
<6>atmel_usart.4: ttyS4 at MMIO 0xfffd0000 (irq = 23) is a ATMEL_SERIAL
<6>atmel_usart.5: ttyS5 at MMIO 0xfffd4000 (irq = 24) is a ATMEL_SERIAL
<6>atmel_usart.6: ttyS6 at MMIO 0xfffd8000 (irq = 25) is a ATMEL_SERIAL
    cat /proc/interrupt
/mnt/flash2/home/yongtao $ cat /proc/interrupts
           CPU0
  1:     187090         AIC  at91_tick, atmel_serial
 12:          2         AIC  atmel_spi.0
 13:         11         AIC  atmel_spi.1
 20:          0         AIC  ohci_hcd:usb1
 21:       8621         AIC  eth0
102:          1        GPIO  mcp2515
Err:          0


为什么,后来我看了内核中的串口驱动代码之后,我才发现:
中断的请求:
static int atmel_startup(struct uart_port *port)
{
    struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
    int retval;

    /*
     * Ensure that no interrupts are enabled otherwise when
     * request_irq() is called we could get stuck trying to
     * handle an unexpected interrupt
     */
    UART_PUT_IDR(port, -1);

    /*
     * Allocate the IRQ
     */
    printk("request uart irq %d\n",port->irq);
    retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, "atmel_serial", port);
    if (retval) {
        printk("atmel_serial: atmel_startup - Can't get irq\n");
        return retval;
    }




中断的释放:
static void atmel_shutdown(struct uart_port *port)
{
    struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;

    /*
     * Ensure everything is stopped.
     */
    atmel_stop_rx(port);
    atmel_stop_tx(port);

    /*
     * Shut-down the DMA.
     */
    if (atmel_port->use_dma_rx) {
        int i;

        for (i = 0; i < 2; i++) {
            struct atmel_dma_buffer *pdc = &atmel_port->pdc_rx[i];

            dma_unmap_single(port->dev, pdc->dma_addr, pdc->dma_size, DMA_FROM_DEVICE);
            kfree(pdc->buf);
        }
    }
    if (atmel_port->use_dma_tx) {
        struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;

        dma_unmap_single(port->dev, pdc->dma_addr, pdc->dma_size, DMA_TO_DEVICE);
    }

    /*
     * Disable all interrupts, port and break condition.
     */
    UART_PUT_CR(port, ATMEL_US_RSTSTA);
    UART_PUT_IDR(port, -1);

    /*
     * Free the interrupt
     */
    printk("release uart irq %d\n",port->irq);
    free_irq(port->irq, port);



我们在dmesg中我们看到,不断的有:
<4>request uart irq 1
<4>release uart irq 1
也就是说,一旦没有数据进入的时候,内核马上就调用关闭函数关掉该串口。

后来我使用了一个非常简单的例子来测试一下:
int main(int argc, char *argv[])
{
    int fd;
    if((fd=open("/dev/ttyS1",O_RDWR))==-1)
    {
        printf("can't get device\n");
    }
    printf("just test\n");
while(1)
{
}


}

我奇怪的发现:
dmesg打出了如下的信息:
<4>request uart irq 6
<4>release uart irq 6


也就是说,你调用open打开该设备之后,如果你没有继续的动作,内核会马上该端口关上!!这也就是我们在/proc/interrupt中看不到其他中断的原因!!因为没有程序使用了这其他的几个串口。。或者即使你使用了,也没有长期的占用这个串口!!

 

明天一定要将串口设置为阻塞型,也就是如果应用程序不主动释放的话,就一直占用它!!




阅读(1895) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~