导 航┆主 站┆文 章┆资 料┆下 载┆美 食┆读 书┆笑 话┆博 客┆论 坛
>> Tony嵌入式开发论坛静态版首页
查看完全版本:Tony嵌入式开发论坛

 

    [原创]vxworks在2410上的串口驱动开发中的问题讨论
    作者:searcher827 时间:2006-5-29 16:16:10

    vxworks在2410上的串口驱动程序开发大讨论


    * ambaIoctl - special device control
    *
    * This routine handles the IOCTL messages from the user.
    *
    * RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed
    * request.
    */

    LOCAL STATUS ambaIoctl
        (
        SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
        int  request, /* request code */
        int  arg  /* some argument */
        )
        {
        int  oldlevel; /* current interrupt level mask */
        STATUS status;  /* status to return */
        UINT32 brd;  /* baud rate divisor */
        AMBA_CHAN * pChan = (AMBA_CHAN *)pSioChan;

        status = OK; /* preset to return OK */

        switch (request)
    {
    case SIO_BAUD_SET
            

         brd = (pChan->xtal/(16*arg)) - 1; /* calculate baudrate divisor */

         if ((brd < 1) || (brd > 0xFFF))
      {
      status = EIO;  /* baud rate out of range */
      break;
      }

         oldlevel = intLock ();


         /* Set baud rate divisor in UART */

         AMBA_UART_REG_WRITE(pChan, L_UBRLCR, brd & 0xFF);
         AMBA_UART_REG_WRITE(pChan, M_UBRLCR, (brd >> 8) & 0xF);

     

         AMBA_UART_REG_WRITE(pChan, H_UBRLCR,
      (UINT8)(WORD_LEN_8 | ONE_STOP | PARITY_NONE | FIFO_ENABLE));

         pChan->baudRate = arg;

         intUnlock (oldlevel);

         break;


    case SIO_BAUD_GET:

         /* Get the baud rate and return OK */

         *(int *)arg = pChan->baudRate;
         break;


    case SIO_MODE_SET

         if ((arg != SIO_MODE_POLL) && (arg != SIO_MODE_INT))
      {
      status = EIO;
      break;
      }
        
         oldlevel = intLock ();

         if (arg == SIO_MODE_INT)
      {
      /* Ensure that only Receive ints are generated. */
      AMBA_UART_REG_BIT_CLR(pChan,
              UARTCON,
                                          UART_RTIE | UART_TIE |
              UART_RIE | UART_MSIE );
      AMBA_UART_REG_BIT_SET(pChan, UARTCON, UART_RIE | UART_RTIE);

      /* Enable appropriate interrupts. */
      intEnable (pChan->lelelRX)
      }
         else
      {
      /* Disable all interrupts for this UART. */

      intDisable (pChan->levelRx);
      if (pChan->levelTx != pChan->levelRx)
          {
          intDisable (pChan->levelTx);
          }

      AMBA_UART_REG_BIT_CLR(pChan,
              UARTCON,
                                          UART_RTIE | UART_TIE |
              UART_RIE | UART_MSIE );
      }

         pChan->channelMode = arg;

         intUnlock (oldlevel);
         break;    


    case SIO_MODE_GET:

         /* Get the current mode and return OK */

         *(int *)arg = pChan->channelMode;
         break;


    case SIO_AVAIL_MODES_GET:

         /* Get the available modes and return OK */

         *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
         break;


    case SIO_HW_OPTS_SET:

      

    case SIO_HW_OPTS_GET:

     

    default:
         status = ENOSYS;
    }

        return status;

        }

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------


    作者:searcher827 时间:2006-5-29 16:16:32

    上是vxworks bsp包中intergrator920t primeCellSio.c对中关于实现串口

    驱动的一个关键函数XXIoctl()的定义.但在/h/sioLib.h中对该函数原型的定义如下:
    typedef struct sio_drv_funcs SIO_DRV_FUNCS;

    typedef struct sio_chan    /* a serial channel */
        {
        SIO_DRV_FUNCS * pDrvFuncs;
        /* device data */
        } SIO_CHAN;

    struct sio_drv_funcs    /* driver functions */
        {
        int  (*ioctl)
       (
       SIO_CHAN * pSioChan,
       int  cmd,
       void *  arg    /* .............注意这里*/
       );
            ..............
       }
    注意第三个参数这里的类型是void *,而在顶楼ambaIoctl()中的类型是int.
    这样问题就出来了,再往下看:在顶楼ambaIoctl()函数中有如下几行语句:

    pChan->baudRate = arg;             ....................A
    *(int *)arg = pChan->baudRate;     ....................B  
    pChan->channelMode = arg;          ....................C
    *(int *)arg = pChan->channelMode;  ....................D
    *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;  ..........E
    显然A,C两处是把arg当成整型来对待,而B,D,E处是把arg 当成void*来处理.
    一个变量怎能同时出现两种类型呢,对此深表怀疑.
        对于这中二意性的处理,个人觉得只要在ambaIoctl()函数中将arg的类型
    由int改为void *然后把A,C两处的arg改为*(int*) arg就可以把问题解决了.
        但实事情况是网上流传的4510bsp包包括其他一些bsp包中也大都是这样处理的.
    另外vxworks提供的bsp包应该是已经经过测试的.毕竟是一个商业软件.
        但从学习的角度出发,这的确是个问题.不知大家对此有何看法.

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------



查看完全版本:Tony嵌入式开发论坛
Copyright 2006-2008 Cevx.Com Cevx.Net 制作 版权所有
网友发帖仅代表个人观点,与本论坛立场无关