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

📄 diti.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
            /*---------------------------------------------------------*/
            if (sm_p(chancfg->wra_id, SM_WAIT, FOREVER))
                {
                parms->err = TERM_SEM;
                return;
                }

            chancfg->dflags |= WAITING;
            SerialSend((Lid)chancfg->lid, echo_mblk);
            if(sm_p(chancfg->txc_id, SM_WAIT, FOREVER))
                {

                /*-----------------------------------------------------*/
                /* semaphore failed clean up and return.               */
                /*-----------------------------------------------------*/
                chancfg->dflags &= ~WAITING;
                parms->err = TERM_SEM;
                parms->out_retval = conio->length - length;

                /*-----------------------------------------------------*/
                /* Restore echo mblock pointer so it can be reused.    */
                /*-----------------------------------------------------*/
                echo_mblk->b_rptr = chancfg->echo_rwprt;
                echo_mblk->b_wptr = chancfg->echo_rwprt;

                /*-----------------------------------------------------*/
                /* Free the message block if it is empty.              */
                /*-----------------------------------------------------*/
                if(mblk->b_rptr >= mblk->b_wptr)
                    {
                    gs_freemsg(mblk);
                    chancfg->rdmblk = 0;
                    SerialIoctl((Lid)chancfg->lid, SIOCREPLENISH, (void *)0);
                    }

                /*-----------------------------------------------------*/
                /* Free the semaphores which control the device.       */
                /*-----------------------------------------------------*/
                sm_v(chancfg->rda_id);
                sm_v(chancfg->wra_id);
                return;
                }

            chancfg->dflags &= ~WAITING;

            /*---------------------------------------------------------*/
            /* Free write semphore so others can write.                */
            /*---------------------------------------------------------*/
            sm_v(chancfg->wra_id);

            /*---------------------------------------------------------*/
            /* Restore echo mblock pointer so it can be reused.        */
            /*---------------------------------------------------------*/
            echo_mblk->b_rptr = chancfg->echo_rwprt;
            echo_mblk->b_wptr = chancfg->echo_rwprt;
            }

        /*-------------------------------------------------------------*/
        /* Update the user buffer/canonical queue with character       */
	/* received.                                                   */
	/*-------------------------------------------------------------*/
	*buffp++ = character;
        characters_received++;
        if ((chancfg->termio.c_lflag & ICANON) &&
            (characters_received >= 128))
            {
            can_mblk->b_wptr = buffp;
            msg[0] = (unsigned long)can_mblk;
            msg[1] = 0;
            error = q_send(chancfg->can_id, msg);
            if (error != 0)
               {
               parms->err = error;
               sm_v(chancfg->rda_id);
               return;
               }
            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;
            characters_received = 0;
            }

       if (!(chancfg->termio.c_lflag & ICANON))
          length--;

        /*-------------------------------------------------------------*/
        /* Check for end of record if in canonical mode.               */
        /* If end of record is reached, copy the characters from       */
        /* canonical queue to user buffer and return.                  */
        /*-------------------------------------------------------------*/
        if ((chancfg->termio.c_lflag & ICANON) &&
            ((character == chancfg->termio.c_cc[VEOL]) ||
             (character == chancfg->termio.c_cc[VEOF])))
            {
            if(mblk->b_rptr >= mblk->b_wptr)
                {
                gs_freemsg(mblk);
                chancfg->rdmblk = 0;
                SerialIoctl((Lid)chancfg->lid, SIOCREPLENISH, (void *)0);
                }
            
            if (characters_received > 0)
                {
                can_mblk->b_wptr = buffp;
                msg[0] = (unsigned long)can_mblk;
                msg[1] = 0;
                error = q_send(chancfg->can_id, msg);
                if (error != 0)
                   {
                   parms->err = error;
                   sm_v(chancfg->rda_id);
                   return;
                   }
                }
 
            error = q_receive(chancfg->can_id, Q_NOWAIT, 0, msg);
            if (error != 0)
                {
                parms->err = error;
                parms->out_retval = conio->length - length;
                sm_v(chancfg->rda_id);
                return;
                }
            else
                {
                length = conio->length;
                buffp = conio->buffp;
                mblk = (mblk_t *)msg[0];
                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;
                }
             }
        } /* end while(mblk->b_rptr < mblk->b_wptr) */

    /*-----------------------------------------------------------------*/
    /* Free the message block if it is empty.                          */
    /*-----------------------------------------------------------------*/
    if(mblk->b_rptr >= mblk->b_wptr)
        {
        gs_freemsg(mblk);
        chancfg->rdmblk = 0;
        SerialIoctl((Lid)chancfg->lid, SIOCREPLENISH, (void *)0);

        /*-------------------------------------------------------------*/
        /* Since this is the end of the mblk buffer status should be   */
        /* check for terminating condition. If a break was received or */
        /* a delimiter was found or carrier was dropped then terminate */
        /* this read.                                                  */
        /*-------------------------------------------------------------*/
        if(b_flags & SIOCBREAKR)
            {
            parms->err = TERM_BRKINT;
            parms->out_retval = conio->length - length;

            /*---------------------------------------------------------*/
            /* Free the semaphore which controls access to the device. */
            /*---------------------------------------------------------*/
            sm_v(chancfg->rda_id);

            return;
            }
        else if(b_flags & SIOCCONTROL)
            {

            /*---------------------------------------------------------*/
            /* Free the semaphore which controls access to the device. */
            /*---------------------------------------------------------*/
            if (sm_v(chancfg->rda_id))
                {
                parms->err = TERM_SEM;
                }

            parms->out_retval = conio->length - length;
            return;
            }
        else if(b_flags & SIOCCDLOST)
            {
            parms->err = TERM_DCDINT;
            parms->out_retval = conio->length - length;

            /*---------------------------------------------------------*/
            /* Free the semaphore which controls access to the device. */
            /*---------------------------------------------------------*/
            sm_v(chancfg->rda_id);

            return;
            }
        }

    /*-----------------------------------------------------------------*/
    /* Now test for the non canonical mode case where VMIN and VTIME   */
    /* are set. For this mode VTIME is a inter character timer once    */
    /* the first character has been received.                          */
    /*-----------------------------------------------------------------*/
    if (!(chancfg->termio.c_lflag & ICANON) &&
        (chancfg->termio.c_cc[VMIN] &&
        chancfg->termio.c_cc[VTIME] &&
        start_ticks && characters_received > 1))
        {
        /*-------------------------------------------------------------*/
        /* Get current ticks for timed input.                          */
        /*-------------------------------------------------------------*/
        if(tm_get(&date, &time, &ticks))

            /*---------------------------------------------------------*/
            /* If call fails break out to return.                      */
            /*---------------------------------------------------------*/
            break;

        else if (ticks - start_ticks >= vtime)
            /*---------------------------------------------------------*/
            /* Time expired between characters.                        */
            /*---------------------------------------------------------*/
            break;

        else if (characters_received >= chancfg->termio.c_cc[VMIN])
            /*---------------------------------------------------------*/
            /* Got VMIN characters break to return.                    */
            /*---------------------------------------------------------*/
            break;
        }

    /*-----------------------------------------------------------------*/
    /* Now test for the non canonical mode case where VMIN only        */
    /* is set.  For this mode we will not return to the call until     */
    /* VMIN characters have been received.                             */
    /*-----------------------------------------------------------------*/
    else if (!(chancfg->termio.c_lflag & ICANON) &&
        (chancfg->termio.c_cc[VMIN] &&
        characters_received >= chancfg->termio.c_cc[VMIN]))
        break;
    } /* end of while(1) */

/*-----------------------------------------------------------------*/
/* Free the semaphore which controls access to the device.         */
/*-----------------------------------------------------------------*/
if (sm_v(chancfg->rda_id))
    {
    parms->err = TERM_SEM;
    }
parms->out_retval = conio->length - length;
}

/***********************************************************************/
/* TermWrite: write to the minor device.                               */
/*                                                                     */
/*      INPUTS: struct ioparms                                         */
/*              ioparms->in_iopb    points to a TermIO type            */
/*              ioparms->in_dev     device number                      */
/*              TermIO->buffp        points to buffer to write         */
/*              TermIO->length       length of buffer                  */
/*                                                                     */
/*     OUTPUTS: ioparms->out_retval number of characters written       */
/*              ioparms->err        error code or 0 if OK              */
/*              ioparms->used       1                                  */
/*                                                                     */
/*     RETURNS:                                                        */
/*              TERM_NINIT driver not initialized

⌨️ 快捷键说明

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