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

📄 nbuf.c

📁 freemodbus-v019.zip 是v0.19版本的代码
💻 C
字号:
/* * Copyright (c) 2006 Christian Walter * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Note: Most of the network buffer code is based on the MCF5235 examples from *   Freescale. * * File: $Id: nbuf.c,v 1.1 2006/08/30 23:18:07 wolti Exp $ *//* ------------------------ Platform includes ----------------------------- */#include "mcf5xxx.h"#include "mcf523x.h"#include "nbuf.h"/* ------------------------ Static variables ------------------------------ *//* Buffer descriptor indexes */static uint8    tx_bd_idx;static uint8    rx_bd_idx;/* Buffer Descriptors -- must be aligned on a 4-byte boundary but a * 16-byte boundary is recommended. */static nbuf_t   tx_nbuf[sizeof( nbuf_t ) * NUM_TXBDS] ATTR_FECMEM;static nbuf_t   rx_nbuf[sizeof( nbuf_t ) * NUM_RXBDS] ATTR_FECMEM;/* Data Buffers -- must be aligned on a 16-byte boundary. */static uint8    tx_buf[TX_BUFFER_SIZE * NUM_TXBDS] ATTR_FECMEM;static uint8    rx_buf[RX_BUFFER_SIZE * NUM_RXBDS] ATTR_FECMEM;/* ------------------------ Start implementation -------------------------- */voidnbuf_init(  ){    uint8           i;    /* Initialize receive descriptor ring */    for( i = 0; i < NUM_RXBDS; i++ )    {        rx_nbuf[i].status = RX_BD_E;        rx_nbuf[i].length = 0;        rx_nbuf[i].data = &rx_buf[i * RX_BUFFER_SIZE];    }    /* Set the Wrap bit on the last one in the ring */    rx_nbuf[NUM_RXBDS - 1].status |= RX_BD_W;    /* Initialize transmit descriptor ring */    for( i = 0; i < NUM_TXBDS; i++ )    {        tx_nbuf[i].status = TX_BD_L | TX_BD_TC;        tx_nbuf[i].length = 0;        tx_nbuf[i].data = &tx_buf[i * TX_BUFFER_SIZE];    }    /* Set the Wrap bit on the last one in the ring */    tx_nbuf[NUM_TXBDS - 1].status |= TX_BD_W;    /* Initialize the buffer descriptor indexes */    tx_bd_idx = rx_bd_idx = 0;    return;}/********************************************************************/uint32nbuf_get_start( uint8 direction ){    /*     * Return the address of the first buffer descriptor in the ring.     * This routine is needed by the FEC of the MPC860T , MCF5282, and MCF523x     * in order to write the Rx/Tx descriptor ring start registers     */    switch ( direction )    {    case NBUF_RX:        return ( uint32 ) rx_nbuf;    case NBUF_TX:    default:        return ( uint32 ) tx_nbuf;    }}/********************************************************************/nbuf_t         *nbuf_rx_allocate(  ){    /* This routine alters shared data. Disable interrupts! */    int             old_ipl = asm_set_ipl( 6 );    /* Return a pointer to the next empty Rx Buffer Descriptor */    int             i = rx_bd_idx;    /* Check to see if the ring of BDs is full */    if( rx_nbuf[i].status & RX_BD_INUSE )        return NULL;    /* Mark the buffer as in use */    rx_nbuf[i].status |= RX_BD_INUSE;    /* increment the circular index */    rx_bd_idx = ( uint8 ) ( ( rx_bd_idx + 1 ) % NUM_RXBDS );    /* Restore previous IPL */    asm_set_ipl( old_ipl );    return &rx_nbuf[i];}/********************************************************************/nbuf_t         *nbuf_tx_allocate(  ){    /* This routine alters shared data. Disable interrupts! */    int             old_ipl = asm_set_ipl( 6 );    /* Return a pointer to the next empty Tx Buffer Descriptor */    int             i = tx_bd_idx;    /* Check to see if ring of BDs is full */    if( ( tx_nbuf[i].status & TX_BD_INUSE ) || ( tx_nbuf[i].status & TX_BD_R ) )        return NULL;    /* Mark the buffer as Ready (in use) */    /* FEC must set R bit in transmit routine */    tx_nbuf[i].status |= TX_BD_INUSE;    /* increment the circular index */    tx_bd_idx = ( uint8 ) ( ( tx_bd_idx + 1 ) % NUM_TXBDS );    /* Restore previous IPL */    asm_set_ipl( old_ipl );    return &tx_nbuf[i];}/********************************************************************/voidnbuf_rx_release( nbuf_t * pNbuf ){    /* This routine alters shared data. Disable interrupts! */    int             old_ipl = asm_set_ipl( 6 );    /* Mark the buffer as empty and not in use */    pNbuf->status |= RX_BD_E;    pNbuf->status &= ~RX_BD_INUSE;    /* Restore previous IPL */    asm_set_ipl( old_ipl );}/********************************************************************/voidnbuf_tx_release( nbuf_t * pNbuf ){    /* This routine alters shared data. Disable interrupts! */    int             old_ipl = asm_set_ipl( 6 );    /* Mark the buffer as not in use */    pNbuf->status &= ~TX_BD_INUSE;    /* Restore previous IPL */    asm_set_ipl( old_ipl );}/********************************************************************/intnbuf_rx_next_ready(  ){    /**************************************************************** This function checks the EMPTY bit of the next Rx buffer to be allocated. If the EMPTY bit is cleared, then the next buffer in the ring has been filled by the FEC and has not already been allocated and passed up the stack. In this case, the next buffer in the ring is ready to be allocated. Otherwise, the  buffer is either empty or not empty but still in use by a higher level protocol. The FEC receive routine uses this function to determine if multiple buffers where filled by the FEC during a single interrupt event. ****************************************************************/    return ( !( rx_nbuf[rx_bd_idx].status & RX_BD_E ) );}

⌨️ 快捷键说明

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