⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diti.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    if(DChanCfg[i].dflags & OPENED && DChanCfg[i].lid)
        while (DChanCfg[i].rqhead)
            {
            tmblk = DChanCfg[i].rqhead;
            imask = splx(MAX_ILEV);
            DChanCfg[i].rqhead = tmblk->b_next;
            splx(imask);
            gs_freemsg(tmblk);
            }

    /*-----------------------------------------------------------------*/
    /* If this is a re-init free any echo mblk's that were allocated.  */
    /*-----------------------------------------------------------------*/
    if (DChanCfg[i].echo_mblk)
        gs_freemsg(DChanCfg[i].echo_mblk);
    }

/*---------------------------------------------------------------------*/
/* Clear DChanCfg structures                                           */
/*---------------------------------------------------------------------*/
bzero(DChanCfg, (sizeof(ChanCfg) * (BSP_SERIAL + 1)));

Term_Init_Done = 1;
}

/***********************************************************************/
/* TermOpen: open a serial port.                                       */
/*                                                                     */
/*      INPUTS: struct ioparms *parms used to return errors            */
/*                                                                     */
/*     RETURNS: void                                                   */
/*                                                                     */
/*     The following error codes are returned in ioparms->err:         */
/*                                                                     */
/*      TERM_MINOR                     Invalid minor device            */
/*      TERM_NINIT                     Driver no initialized           */
/*      TERM_AOPEN                     Channel already open            */
/*                                                                     */
/*     In the case of TERM_SEM ioparms->out_retval will contain the    */
/*     semaphore error code.                                           */
/*                                                                     */
/***********************************************************************/
void TermOpen(struct ioparms *parms)
{
ChannelCfg channelcfg;
unsigned short minor;
char sema4_name[6];
unsigned long error;
ChanCfg *chancfg;
int p, i;

/*---------------------------------------------------------------------*/
/* SysBaud is the default baudrate set in sysinit.c                    */
/*---------------------------------------------------------------------*/
extern int SysBaud;

UCHAR defaultbaud;

/*---------------------------------------------------------------------*/
/* Set elements of the ioparms structure to their default values.      */
/* used - will tell pSOS we're using stack interface                   */
/* out_retval - is used to pass additional error information to the    */
/*              user.                                                  */
/* err - will contain an error code (0 for success)                    */
/*---------------------------------------------------------------------*/
parms->used = 1;
parms->out_retval = 0;
parms->err = 0;

/*---------------------------------------------------------------------*/
/* Check to see if the driver has been initialized.                    */
/*---------------------------------------------------------------------*/
if (!Term_Init_Done)
    {
    parms->err = TERM_NINIT;
    return;
    }

/*---------------------------------------------------------------------*/
/* Check to see if the minor device is in a valid range.               */
/* When using SC_AUTOINIT this will be zero, so skip the whole thing.  */
/*---------------------------------------------------------------------*/
if((minor = MINOR(parms->in_dev)) < 1)
    return;

/*---------------------------------------------------------------------*/
/* Check to see if the minor device is in range.                       */
/*---------------------------------------------------------------------*/
if(minor > BSP_SERIAL)
    {
    parms->err = TERM_MINOR;
    return;
    }

/*---------------------------------------------------------------------*/
/* Keep track of opens so close will know when to actually close       */
/* channel.                                                            */
/*---------------------------------------------------------------------*/
DChanCfg[minor].num_open++;

/*---------------------------------------------------------------------*/
/* Check to see if minor device is already opened.                     */
/*---------------------------------------------------------------------*/
if(DChanCfg[minor].dflags & OPENED)
    {
    /*-----------------------------------------------------------------*/
    /* Minor device already open.                                      */
    /*-----------------------------------------------------------------*/
    return;
    }

/*---------------------------------------------------------------------*/
/* Set up configuration structure that will be passed to DISI          */
/* interface.                                                          */
/* NOTE: ECHO is removed from Flags before it is copied to the lower   */
/* level code because it has a different meaning to the lower level    */
/* code. This driver will do its own echo.                             */
/*---------------------------------------------------------------------*/
bzero(&channelcfg, sizeof(ChannelCfg));
channelcfg.Mode = SIOCASYNC;
channelcfg.Cfg.Uart.CharSize = SCS8;
channelcfg.Cfg.Uart.Flags = SBRKINT | SWFC | CANON;
channelcfg.Cfg.Uart.LineD[0].LChar = EOT;
channelcfg.Cfg.Uart.LineD[0].LFlags = 0;
channelcfg.Cfg.Uart.LineD[1].LChar = NL;
channelcfg.Cfg.Uart.LineD[1].LFlags = 0;
channelcfg.Cfg.Uart.LineD[2].LChar = CR;
channelcfg.Cfg.Uart.LineD[2].LFlags = ENDOFTABLE;
channelcfg.Cfg.Uart.XOnCharacter = XON;
channelcfg.Cfg.Uart.XOffCharacter = XOFF;
channelcfg.Cfg.Uart.MinChar = 1;
channelcfg.Cfg.Uart.MaxTime = 3;
channelcfg.RBuffSize = RBUFFSIZE;
channelcfg.NRBuffs = 1;
channelcfg.OutQLen = 4;
channelcfg.Baud = SysBaud;
channelcfg.LineMode = FULLD;
channelcfg.dataind = term_dataind;
channelcfg.expind = term_expind;
channelcfg.datacnf = term_datacnf;
channelcfg.ctlcnf = term_ctlcnf;
channelcfg.allocb = gs_allocb;
channelcfg.freemsg = gs_freemsg;
channelcfg.esballoc = gs_esballoc;
channelcfg.uid = (void *)&DChanCfg[minor];

/*---------------------------------------------------------------------*/
/* Call the DISI interface open                                        */
/*---------------------------------------------------------------------*/
if(error = SerialOpen((ULONG)(minor - 1), (ChannelCfg *)&channelcfg,
           (Lid )&DChanCfg[minor].lid,
           (unsigned long *)&DChanCfg[minor].hdwflags))
    {
    /*-----------------------------------------------------------------*/
    /* Return error code.                                              */
    /*-----------------------------------------------------------------*/
    switch (error)
        {
        case SIOCAOPEN:
            /*---------------------------------------------------------*/
            /* The Channel has already been opened by another driver!  */
            /*---------------------------------------------------------*/
            parms->err = TERM_ADOPEN;
            return;

        case SIOCBADCHANNELNUM:
            /*---------------------------------------------------------*/
            /* Even though the minor number is in range it is not a    */
            /* valid channel for this hardware.                        */
            /*---------------------------------------------------------*/
            parms->err = TERM_MINOR;
            return;

        case SIOCCFGNOTSUPPORTED:
            /*---------------------------------------------------------*/
            /* Hardware cannot be configured by the DISI as given.     */
            /*---------------------------------------------------------*/
            parms->err = TERM_CFGHSUP;
            return;

        case SIOCBADBAUD:
            /*---------------------------------------------------------*/
            /* Baud rate not supported by hardware.                    */
            /*---------------------------------------------------------*/
            parms->err = TERM_BAUD;
            return;

        case SIOCBADMINCHAR:
            /*---------------------------------------------------------*/
            /* This error should have been caught above so something   */
            /* is corrupted in the lower driver.                       */
            /*---------------------------------------------------------*/
            parms->err = TERM_LDERR;
            return;

        case SIOCNOTINIT:
            /*---------------------------------------------------------*/
            /* This error shows that the lower driver thinks it is     */
            /* has not been initialized. Since tests made above        */
            /* show otherwise the driver is out of sync.               */
            /*---------------------------------------------------------*/
            parms->err = TERM_OUTSYNC;
            return;
        }
    }

/*---------------------------------------------------------------------*/
/* Get the address of the drivers ChanCfg for this minor device        */
/*---------------------------------------------------------------------*/
chancfg = &DChanCfg[minor];

/*---------------------------------------------------------------------*/
/* Save the minor device configuration                                 */
/*---------------------------------------------------------------------*/
chancfg->termio.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
chancfg->termio.c_oflag = OPOST | ONLCR;

for (i = 1; i < BAUD_TABLE_SIZE; i++)
    if(baud_table[i] == SysBaud)
        break;

if(i != BAUD_TABLE_SIZE)
    defaultbaud = (i & CBAUD);
else
    defaultbaud = B9600;

chancfg->termio.c_cflag = defaultbaud | CS8 | CREAD;
chancfg->termio.c_lflag = ICANON | ECHO;
chancfg->termio.c_cc[VERASE] = BS;
chancfg->termio.c_cc[VEOF] = EOT;
chancfg->termio.c_cc[VEOL] = NL;
chancfg->termio.c_cc[VSTART] = XON;
chancfg->termio.c_cc[VSTOP] = XOFF;

/*---------------------------------------------------------------------*/
/* NOTE: error returns after this could leave driver in HALF OPENED    */
/* state. cleanup must be called to clear all references to channel    */
/*---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/
/* Create semaphores to control task access to the read and write      */
/* drivers and for signaling the end of rcv and xmit operations.       */
/*---------------------------------------------------------------------*/
StringCopy(sema4_name, READ_NAME);
sema4_name[3] = minor + '0';
if (error = sm_create(sema4_name, 1, SM_FIFO,
    &chancfg->rda_id))
    {
    parms->err = TERM_SEM;
    parms->out_retval = error;
    cleanup(chancfg);
    return;
    }

StringCopy(sema4_name, WRITE_NAME);
sema4_name[3] = minor + '0';
if (error = sm_create(sema4_name, 1, SM_FIFO,
    &chancfg->wra_id))
    {
    parms->err = TERM_SEM;
    parms->out_retval = error;
    cleanup(chancfg);
    return;
    }

StringCopy(sema4_name, RXQUE_NAME);
sema4_name[3] = minor + '0';
if (error = q_create(sema4_name, 0, Q_FIFO | Q_SYSBUF | Q_NOLIMIT,
    &chancfg->rxq_id))
    {
    parms->err = TERM_QUE;
    parms->out_retval = error;
    cleanup(chancfg);
    return;
    }

StringCopy(sema4_name, CANQUE_NAME);
sema4_name[3] = minor + '0';
if (error = q_create(sema4_name, 0, Q_FIFO | Q_SYSBUF | Q_NOLIMIT,
    &chancfg->can_id))
    {
    parms->err = TERM_QUE;
    parms->out_retval = error;
    cleanup(chancfg);
    return;
    }

StringCopy(sema4_name, TXCOMP_NAME);
sema4_name[3] = minor + '0';
if (error = sm_create(sema4_name, 0, SM_FIFO,
    &chancfg->txc_id))
    {
    parms->err = TERM_SEM;
    parms->out_retval = error;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -