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

📄 buffer.c

📁 基于STR710和嵌入式操作系统的串口驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*                                     Embedded Systems Building Blocks
*                                  Complete and Ready-to-Use Modules in C
*
*                                    Asynchronous Serial Communications
*                                           Buffered Serial I/O 
*                                                 (RTOS)
*
*                            (c) Copyright 1999, Jean J. Labrosse, Weston, FL
*                                           All Rights Reserved
*
* Filename   : COMMRTOS.C
* Programmer : Jean J. Labrosse
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                               INCLUDES
*********************************************************************************************************
*/

#include "config.h"

/*$PAGE*/
/*
*********************************************************************************************************
*                                               CONSTANTS
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                               DATA TYPES
*********************************************************************************************************
*/

typedef struct {
    INT16U     RingBufRxCtr;                /* Number of characters in the Rx ring buffer              */
    OS_EVENT  *RingBufRxSem;                /* Pointer to Rx semaphore                                 */
    INT8U     *RingBufRxInPtr;              /* Pointer to where next character will be inserted        */
    INT8U     *RingBufRxOutPtr;             /* Pointer from where next character will be extracted     */
    INT8U      RingBufRx[COMM_RX_BUF_SIZE]; /* Ring buffer character storage (Rx)                      */
    INT16U     RingBufTxCtr;                /* Number of characters in the Tx ring buffer              */
    OS_EVENT  *RingBufTxSem;                /* Pointer to Tx semaphore                                 */
    INT8U     *RingBufTxInPtr;              /* Pointer to where next character will be inserted        */
    INT8U     *RingBufTxOutPtr;             /* Pointer from where next character will be extracted     */
    INT8U      RingBufTx[COMM_TX_BUF_SIZE]; /* Ring buffer character storage (Tx)                      */
} COMM_RING_BUF;

/*
*********************************************************************************************************
*                                            GLOBAL VARIABLES
*********************************************************************************************************
*/

COMM_RING_BUF  Comm3Buf;

/*$PAGE*/
/*
*********************************************************************************************************
*                                  INITIALIZE COMMUNICATIONS MODULE
*
*
* Description : This function is called by your application to initialize the communications module.  You
*               must call this function before calling any other functions.
* Arguments   : none
*********************************************************************************************************
*/

void  CommInit (void)
{
    COMM_RING_BUF *pbuf;
    
    pbuf                  = &Comm3Buf;                     /* Initialize the ring buffer for COMM4     */
    pbuf->RingBufRxCtr    = 0;
    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];
    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
    pbuf->RingBufRxSem    = OSSemCreate(0);
    pbuf->RingBufTxCtr    = 0;
    pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];
    pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
    pbuf->RingBufTxSem    = OSSemCreate(COMM_TX_BUF_SIZE);
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                    REMOVE CHARACTER FROM RING BUFFER
*
*
* Description : This function is called by your application to obtain a character from the communications
*               channel.  The function will wait for a character to be received on the serial channel or
*               until the function times out.
* Arguments   : 'ch'    is the COMM port channel number and can either be:
*                           COMM1
*                           COMM2
*               'to'    is the amount of time (in clock ticks) that the calling function is willing to
*                       wait for a character to arrive.  If you specify a timeout of 0, the function will
*                       wait forever for a character to arrive.
*               'err'   is a pointer to where an error code will be placed:
*                           *err is set to COMM_NO_ERR     if a character has been received
*                           *err is set to COMM_RX_TIMEOUT if a timeout occurred
*                           *err is set to COMM_BAD_CH     if you specify an invalid channel number
* Returns     : The character in the buffer (or NUL if a timeout occurred)
*********************************************************************************************************
*/

INT8U  CommGetChar (INT8U ch, INT16U to, INT8U *err)
{
    INT8U          c;
    INT8U          oserr;
    OS_CPU_SR  	   cpu_sr;
    COMM_RING_BUF *pbuf;


    switch (ch)											/* Obtain pointer to communications channel */ 
    {                                          
        /*case COMM0:
             pbuf = &Comm0Buf;
             break;
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;*/
        case COMM3:
             pbuf = &Comm3Buf;
             break;

        default:
             *err = COMM_BAD_CH;
             return (NUL);
    }
    OSSemPend(pbuf->RingBufRxSem, to, &oserr);             /* Wait for character to arrive             */
    if (oserr == OS_TIMEOUT) {                             /* See if characters received within timeout*/
        *err = COMM_RX_TIMEOUT;                            /* No, return error code                    */
        return (NUL);
    } else {
        OS_ENTER_CRITICAL();
        pbuf->RingBufRxCtr--;                              /* Yes, decrement character count           */
        c = *pbuf->RingBufRxOutPtr++;                      /* Get character from buffer                */
        if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) {     /* Wrap OUT pointer     */
            pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
        }
        OS_EXIT_CRITICAL();
        *err = COMM_NO_ERR;
        return (c);
    }
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                  GET TX CHARACTER FROM RING BUFFER
*
*
* Description : This function is called by the Tx ISR to extract the next character from the Tx buffer.
*               The function returns FALSE if the buffer is empty after the character is extracted from
*               the buffer.  This is done to signal the Tx ISR to disable interrupts because this is the
*               last character to send.
* Arguments   : 'ch'    is the COMM port channel number and can either be:
*                           COMM1
*                           COMM2
*               'err'   is a pointer to where an error code will be deposited:
*                           *err is set to COMM_NO_ERR         if at least one character was available
*                                                              from the buffer.
*                           *err is set to COMM_TX_EMPTY       if the Tx buffer is empty.
*                           *err is set to COMM_BAD_CH         if you have specified an incorrect channel
* Returns     : The next character in the Tx buffer or NUL if the buffer is empty.
*********************************************************************************************************
*/

INT8U  CommGetTxChar (INT8U ch, INT8U *err)
{
    INT8U          c;
    COMM_RING_BUF  *pbuf;

    switch (ch)											/* Obtain pointer to communications channel */ 
    {                                          
        /*case COMM0:
             pbuf = &Comm0Buf;
             break;
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;*/
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        default:
             *err = COMM_BAD_CH;
             return (NUL);
    }
    
    if (pbuf->RingBufTxCtr > 0) 						   /* See if buffer is empty                   */
    {                          		
        pbuf->RingBufTxCtr--;                              /* No, decrement character count            */
        c = *pbuf->RingBufTxOutPtr++;                      /* Get character from buffer                */
        if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COMM_TX_BUF_SIZE]) /* Wrap OUT pointer     */
        {     
            pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
        }
        OSSemPost(pbuf->RingBufTxSem);                     /* Indicate that character will be sent     */
        *err = COMM_NO_ERR;
        return (c);                                        /* Characters are still available           */
    } 
    else 
    {
        *err = COMM_TX_EMPTY;
        return (NUL);                                      /* Buffer is empty                          */
    }
}

/*$PAGE*/
/*********************************************************************************************************
** 函数名称: CommTxBufIsEmpty
** 功能描述: 允许应用程序确定发送缓冲区是否有字符发送。本函数允许在无数据是避免发送中断允许,可以在ISR中
**            调用该函数。
** 
** 参    数: ch指串行通信信道,可以是COMM1、COMM2、COMM3、COMM4
**  
** 返 回 值: 如果环状缓冲区无数据发送,则函数返回TRUE,如果环状缓冲区有数据发送,则函数返回FALSE,
**         
** 作   者: 罗辉联
** 日   期: 2006年11月1日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

BOOLEAN  CommTxBufIsEmpty (INT8U ch)
{
    BOOLEAN        empty;
    //OS_CPU_SR  	   cpu_sr;
    COMM_RING_BUF  *pbuf;


    switch (ch)											/* Obtain pointer to communications channel */ 
    {                                          
        /*case COMM0:
             pbuf = &Comm0Buf;
             break;
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;*/
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        default:
             return (TRUE);
    }
    
    //OS_ENTER_CRITICAL();
    if (pbuf->RingBufTxCtr > 0) 
    {                          							 /* See if buffer is empty                   */
        empty = FALSE;                                     /* Buffer is NOT empty                      */
    } 
    else 
    {
        empty = TRUE;                                      /* Buffer is empty                          */
    }
    
    //OS_EXIT_CRITICAL();
    return (empty);
}


/*$PAGE*/
/*
*********************************************************************************************************
*                                   SEE IF RX CHARACTER BUFFER IS EMPTY
*
*
* Description : This function is called by your application to see if any character is available from the
*               communications channel.  If at least one character is available, the function returns
*               FALSE otherwise, the function returns TRUE.

⌨️ 快捷键说明

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