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

📄 diti.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    cleanup(chancfg);
    return;
    }

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

chancfg->dflags |= OPENED;

/*---------------------------------------------------------------------*/
/* Get a mblock to use for echo and delete.                            */
/*---------------------------------------------------------------------*/
if(!(chancfg->echo_mblk = gs_allocb(3, 0)))
    {
    parms->err = TERM_NBUFF;
    cleanup(chancfg);
    return;
    }
chancfg->echo_rwprt = chancfg->echo_mblk->b_rptr;

/*---------------------------------------------------------------------*/
/* Set channel active RTS CTS                                          */
/*---------------------------------------------------------------------*/
p = doctl((Lid )chancfg->lid, SIOCSACTIVATE, (void *)0, parms);
if((p != SIOCOK) && (parms->err == SIOCCFGNOTSUPPORTED))
    parms->err = SIOCOK;
else
    {

/*---------------------------------------------------------------------*/
/* Wait for cd                                                         */
/*---------------------------------------------------------------------*/
    if(sm_p(chancfg->ctl_id, SM_WAIT, FOREVER))
        {
        parms->err = TERM_SEM;
        cleanup(chancfg);
        gs_freemsg(chancfg->echo_mblk);
        chancfg->dflags &= ~OPENED;
        return;
        }
    }
chancfg->dflags |= CONNECTED;
}

/***********************************************************************/
/* TermRead: Read from a channel                                       */
/*                                                                     */
/*      INPUTS: struct ioparms                                         */
/*              ioparms->in_iopb    points to a TermIO type            */
/*              ioparms->in_dev     device number                      */
/*              TermIO->buffp        points to buffer to read into     */
/*              TermIO->length       length of buffer                  */
/*                                                                     */
/*     OUTPUTS: ioparms->out_retval number of characters read          */
/*              ioparms->err        error code or 0 if OK              */
/*              ioparms->used       1                                  */
/*                                                                     */
/*     RETURNS:                                                        */
/*              TERM_NINIT driver not initialized                      */
/*              TERM_NOPEN minor device has not been opened            */
/*              TERM_MINOR Invalid minor device                        */
/*              TERM_BRKINT Terminated by a break character            */
/*              TERM_DCDINT Terminated by loss of DCD                  */
/*              TERM_RXERR data receive error                          */
/*              TERM_SEM Semaphore error                               */
/*              TERM_QUE que error                                     */
/*              TERM_ROPER redirect operation error                    */
/*                                                                     */
/***********************************************************************/
void TermRead (struct ioparms *parms)
{
ChanCfg *chancfg;
TermIO *conio = (TermIO *) parms->in_iopb;
mblk_t *mblk, *echo_mblk, *can_mblk=NULL;
                       /* =NULL, -- chg by szg for restraining warning*/
unsigned short minor;
unsigned long b_flags, wait, length, msg[4], error, timeout_ticks;
unsigned char *buffp, character;
unsigned short    c_iflag, c_oflag;
static unsigned long read_access_tid;
unsigned long ret;
unsigned long oldprio, imask;
unsigned long date, time, ticks, start_ticks, vtime;
int characters_received;

/*---------------------------------------------------------------------*/
/* 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 initiatized.                    */
/*---------------------------------------------------------------------*/
if (!Term_Init_Done)
    {
    parms->err = TERM_NINIT;
    return;
    }

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

/*---------------------------------------------------------------------*/
/* Check to see if the minor device is 0 (default console). If so      */
/* set the minor device to the actual channel being used as the        */
/* system console.                                                     */
/*---------------------------------------------------------------------*/
if(minor == 0)
    minor = SysConsole;

chancfg = &DChanCfg[minor];

/*---------------------------------------------------------------------*/
/* Check to see if minor device has been opened.                       */
/*---------------------------------------------------------------------*/
if(!(chancfg->dflags & OPENED))
    {
    parms->err = TERM_NOPEN;
    return;
    }

/*---------------------------------------------------------------------*/
/* If count is zero return now on error                                */
/*---------------------------------------------------------------------*/
if (!(length = conio->length))
    return;

/*---------------------------------------------------------------------*/
/* Get the semaphore which controls access to the device.              */
/* To avoid the problem of a task being deleted while in this section  */
/* of code and no other task being able to get in after that the       */
/* semaphore is programmed to time out. At each time out a check       */
/* will be made to see if the task that currently has this section     */
/* of code is still alive. If it is not, sm_v will be called to clean  */
/* up the semphore.                                                    */
/*---------------------------------------------------------------------*/
while (ret = sm_p(chancfg->rda_id, SM_WAIT,
                  (anchor->psosct->kc_ticks2sec/2)))
    {
    if (ret == ERR_TIMEOUT)
        {
        /*-------------------------------------------------------------*/
        /* Check to see if the task that is currently blocking access  */
        /* is still running.                                           */
        /*-------------------------------------------------------------*/
        if(ret = t_setpri(read_access_tid, 0, &oldprio))
            {
            if(ret == ERR_OBJDEL)
                {
                /*-----------------------------------------------------*/
                /* Task that is blocking access has been deleted.      */
                /* Clean up access semaphore.                          */
                /*-----------------------------------------------------*/
                sm_v(chancfg->rda_id);

                /*-----------------------------------------------------*/
                /* Go back and try again.                              */
                /*-----------------------------------------------------*/
                continue;
                }
            else
                {
                /*-----------------------------------------------------*/
                /* Some other error has happened just return.          */
                /*-----------------------------------------------------*/
                parms->err = TERM_SEM;
                return;
                }
            }
        else
            /*---------------------------------------------------------*/
            /* Valid task still waiting in this section go back and    */
            /* wait some more.                                         */
            /*---------------------------------------------------------*/
            continue;

        }
    else
        {
        parms->err = TERM_SEM;
        return;
        }
    }

/*---------------------------------------------------------------------*/
/* Save off the tasks ID to be used if task is deleted                 */
/*---------------------------------------------------------------------*/
t_ident((char *)0, 0, &read_access_tid);

/*---------------------------------------------------------------------*/
/* Check to see if any current mblk from canonical queue available. If */
/* not, check to see if any mblks available in the canonical queue. If */
/* available, copy the characters from the mblk to user buffer until   */
/* there are any characters in the canonical queue or until the read   */
/* count is satisfied. If no mblk available in the canonical queue,    */
/* proceed on to read mblks from the receive queue, process character  */
/* if needed and then copy to user buffer (if in non canonical mode) or*/
/* to canonical queue (if in canonical mode).                          */
/*---------------------------------------------------------------------*/
mblk = 0;
if (chancfg->cnmblk)
    mblk = chancfg->cnmblk;
else
    if (q_receive(chancfg->can_id, Q_NOWAIT, 0, msg) == 0)
        mblk = (mblk_t *)msg[0];
if (mblk)
    {
    buffp = conio->buffp;
    while (length)
        {
        *buffp++ = *mblk->b_rptr++;
        length--;
        if (mblk->b_rptr >= mblk->b_wptr)
           {
           gs_freemsg(mblk);
           if (length)
              {
              if (q_receive(chancfg->can_id, Q_NOWAIT, 0, msg) == 0)
                 mblk = (mblk_t *)msg[0];
              else
                 break;
              }
           }
        } /* while */
    if ((mblk->b_rptr < mblk->b_wptr) && 
        ((*mblk->b_rptr == chancfg->termio.c_cc[VEOL]) ||
        (*mblk->b_rptr == chancfg->termio.c_cc[VEOF])))
           mblk->b_rptr++;
    
    if (mblk->b_rptr < mblk->b_wptr)
        chancfg->cnmblk = mblk;
    else
        chancfg->cnmblk = 0;            
 
    parms->out_retval = conio->length - length;
    sm_v(chancfg->rda_id);
    return;
    }

/*---------------------------------------------------------------------*/
/* Set the characters_received for VMIN VTIME processing               */
/*---------------------------------------------------------------------*/
characters_received = 0;
if (chancfg->termio.c_lflag & ICANON)
   {
   can_mblk = gs_allocb((int)128, 0);
   if (can_mblk == NULL)
      {
      parms->err = TERM_NBUFF;
      sm_v(chancfg->rda_id);
      return;
      }
   buffp = can_mblk->b_wptr;
   }
else
   buffp = conio->buffp;

/*---------------------------------------------------------------------*/
/* The following variables are set to make lint not complain.          */
/*---------------------------------------------------------------------*/
timeout_ticks = 0;
start_ticks = 0;
vtime = 0;

/*---------------------------------------------------------------------*/
/* Fill the callers buffer until length is reached or a error is found */
/* or a control character is found.                                    */
/*---------------------------------------------------------------------*/
while(1)
    {
    if (!(chancfg->termio.c_lflag & ICANON) && (length == 0))
       break;
    
    /*-----------------------------------------------------------------*/

⌨️ 快捷键说明

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