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

📄 pbm.c

📁 本软件是TI公司免费提供的网络开发包 现在好象很难找到,有黑心的公司把它改一改,就卖价5000元,对网络开发和网络驱动开发有参考价值
💻 C
字号:
/*
 *  Copyright 2006 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *
 *  @(#) TCP/IP_Network_Developers_Kit 1.91.00.08 08-22-2006 (ndk-a08)
 */
//--------------------------------------------------------------------------
// IP Stack
//--------------------------------------------------------------------------
// pbm.c
//
// Packet Buffer Manager
//
// Author: Michael A. Denio
// Copyright 2003, 2004 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>

//
// Local Packet Buffer Pool Definitions
//

// Number of buffers in PBM packet buffer free pool
//
// The number of buffers in the free pool can have a significant effect
// on performance, especially in UDP packet loss. Increasing this number
// will increase the size of the static packet pool use for both sending
// and receiving packets.
//
// DM642 Users Note: The DM642 Ethernet driver assumes that its local
// buffer allocation (EMAC_MAX_RX in dm642.c) plus PKT_NUM_FRAMEBUF
// defined below is less than or equal to 256. The default value for
// EMAC_MAX_RX in the DM642 Ethernet driver is 16.
//
#define PKT_NUM_FRAMEBUF    192

// Max size buffer
//
// On L2 cached CPUs, this size must be cache-line multiple
// The LogicIO Etherent (Macronix MAC) requires a larger buffer because
// it transfers data in 16 byte chunks, and with its pre-pad and data
// alignment, it will overflow a 1536 byte buffer.
//
// If the LogicIO/Maxcronix support is not required, this value can
// be reduced to 1536.
//
#define PKT_SIZE_FRAMEBUF   1664

//
// Data space for packet buffers
//
#pragma DATA_ALIGN(pBufMem, 128);
#pragma DATA_SECTION(pBufMem, ".far:NDK_PACKETMEM");
static UINT8 pBufMem[PKT_NUM_FRAMEBUF*PKT_SIZE_FRAMEBUF];

#pragma DATA_ALIGN(pHdrMem, 128);
#pragma DATA_SECTION(pHdrMem, ".far:NDK_PACKETMEM");
static UINT8 pHdrMem[PKT_NUM_FRAMEBUF*sizeof(PBM_Pkt)];

// Limitation of using mmAlloc
#define MMALLOC_MAXSIZE 3068

// Our PBM types
#define PBM_MAGIC_POOL      0x0F1E2D3C
#define PBM_MAGIC_ALLOC     0x4B5A6978

// Flag to make sure we've been opened
static uint     IsOpen = 0;

// Queue for Pooled Packets
PBMQ     PBMQ_free;

//--------------------------------------------------------------------
// PBM_open()
//
// Open the buffer manager and initialize the free pool
//--------------------------------------------------------------------
uint PBM_open()
{
    UINT8   *pBufTmp;
    UINT8   *pHdrTmp;
    PBM_Pkt *pPkt;
    uint    i;

    //
    // Initialize global data
    //

    // Initialize Free Queue
    PBMQ_init(&PBMQ_free);

    // Get temp pointers
    pBufTmp = pBufMem;
    pHdrTmp = pHdrMem;

    // Break memory array into packet buffers and push onto free queue
    for( i=0; i<PKT_NUM_FRAMEBUF; i++ )
    {
        pPkt = (PBM_Pkt *)pHdrTmp;
        pHdrTmp += sizeof(PBM_Pkt);

        pPkt->Type        = PBM_MAGIC_POOL;
        pPkt->BufferLen   = PKT_SIZE_FRAMEBUF;
        pPkt->pDataBuffer = pBufTmp;
        pBufTmp += PKT_SIZE_FRAMEBUF;

        PBMQ_enq( &PBMQ_free, pPkt );
    }

    IsOpen = 1;

    return(1);
}


//--------------------------------------------------------------------
// PBM_close()
//
// Close the buffer manager and free all allocated memory
//--------------------------------------------------------------------
void PBM_close()
{
    IsOpen = 0;
}


//--------------------------------------------------------------------
// PBM_alloc()
//
// Allocate a Packet Buffer Object
//
// (Can be called at ISR time by HAL)
// (Can be called in kernel mode by STACK)
//--------------------------------------------------------------------
PBM_Handle PBM_alloc( uint MaxSize )
{
    PBM_Pkt     *pPkt = 0;

    // Verify we're open
    if( !IsOpen )
        return(0);

    // Allocate Buffer off the Free Pool is size is OK
    if( MaxSize <= PKT_SIZE_FRAMEBUF )
        pPkt = (PBM_Pkt *)PBMQ_deq( &PBMQ_free );
    else
    {
        // Allocate header from memory
        pPkt = (PBM_Pkt *)mmAlloc( sizeof(PBM_Pkt) );
        if( pPkt )
        {
            pPkt->Type        = PBM_MAGIC_ALLOC;
            pPkt->BufferLen   = MaxSize;

            // Allocate Buffer from Memory
            // mmAlloc() is safe at interrupt time
            if( MaxSize <= MMALLOC_MAXSIZE )
                pPkt->pDataBuffer = mmAlloc( MaxSize );
            else
            {
                // Note: If the system needs to support packet buffers
                //       greater than MMALLOC_MAXSIZE, then there needs
                //       to be large buffer pool or an allocation scheme
                //       that can be called at ISR time, since this
                //       buffer allocation function can be called from
                //       device drivers at interrupt time.
                //
                //       The mmAlloc() function can be called from an
                //       ISR, but its buffer limited at around 3K. Since
                //       the DSP/BIOS memory function can't be called at
                //       ISR time, we can't use them here.
                //
                //       The addition of large buffer support can be
                //       added here if needed.
                pPkt->pDataBuffer = 0;
            }

            // If no buffer, free header
            if( !pPkt->pDataBuffer )
            {
                mmFree( pPkt );
                pPkt = 0;
            }
        }
    }

    // If we have a packet, clear all "zero-init" fields. These are
    // all the fields starting with "Flags" down.
    if( pPkt )
        mmZeroInit( &pPkt->Flags,
                    sizeof(PBM_Pkt)-((uint)&(pPkt->Flags)-(uint)pPkt));

    return( (PBM_Handle)pPkt );
}


//--------------------------------------------------------------------
// PBM_free()
//
// Free a Packet Buffer Object
//
// (Can be called at ISR time by HAL)
// (Can be called in kernel mode by STACK)
//--------------------------------------------------------------------
void PBM_free( PBM_Handle hPkt )
{
    PBM_Pkt *pPkt = (PBM_Pkt *)hPkt;

    // Validate the type
    if(!pPkt || (pPkt->Type!=PBM_MAGIC_POOL && pPkt->Type!=PBM_MAGIC_ALLOC))
        DbgPrintf(DBG_ERROR,"PBM_free: Invalid Packet");

    // Free any held route
    //
    // Note: We do not call RtDeRef() from outside of kernel mode. However,
    //       it is impossible for a device driver to be passed a packet that
    //       contains a route reference. Thus, if there is a route on this
    //       packet, we must have been called from the stack and thus are in
    //       kernel mode already.
    //
    if( pPkt->hRoute )
    {
        RtDeRef( pPkt->hRoute );
        pPkt->hRoute = 0;
    }

    // If a pool packet, return to free pool
    if( pPkt->Type == PBM_MAGIC_POOL )
        PBMQ_enq( &PBMQ_free, pPkt );
    // Else it is an allocated packet, free it
    else
    {
        if( pPkt->BufferLen <= MMALLOC_MAXSIZE )
            mmFree( pPkt->pDataBuffer );
        // else
        // {
        //     // When supporting buffers larger than MMALLOC_MAXSIZE,
        //     // they can be freed here.
        // }

        mmFree( pPkt );
    }
}

//--------------------------------------------------------------------
// PBM_copy()
//
// Copy a Packet Buffer Object
//
// (Can be called at ISR time by HAL)
// (Can be called in kernel mode by STACK)
//--------------------------------------------------------------------
PBM_Handle PBM_copy( PBM_Handle hPkt )
{
    PBM_Pkt *pPkt = (PBM_Pkt *)hPkt;
    PBM_Pkt *pPktNew;

    pPktNew = (PBM_Pkt *)PBM_alloc( pPkt->ValidLen + pPkt->DataOffset );

    if( pPktNew )
    {
        // Copy all structure field from "Flags" down
        mmCopy( &pPktNew->Flags, &pPkt->Flags,
                sizeof(PBM_Pkt)-((uint)&pPkt->Flags-(uint)pPkt));

        // Copy the data in the data buffer
        mmCopy( pPktNew->pDataBuffer + pPktNew->DataOffset,
                pPkt->pDataBuffer + pPkt->DataOffset, pPkt->ValidLen );

        // Add a reference to a route if we copied it
        //
        // Note: We do not call RtRef() from outsise of kernel mode. However,
        //       it is impossible for a device driver to be passed a packet that
        //       contains a route reference. Thus, if there is a route on this
        //       packet, we must have been called from the stack and thus are in
        //       kernel mode already.
        //
        if( pPktNew->hRoute )
            RtRef( pPktNew->hRoute );
    }

    return( (PBM_Handle)pPktNew );
}


//--------------------------------------------------------------------
// PBMQ_enq()
//
// Enqueue a packet onto the supplied queue
//--------------------------------------------------------------------
void PBMQ_enq( PBMQ *pQ, PBM_Handle hPkt )
{
    PBM_Pkt *pPkt = (PBM_Pkt *)hPkt;
    uint    mask;

    if( pPkt->Type != PBM_MAGIC_POOL &&
        pPkt->Type != PBM_MAGIC_ALLOC )
    {
        DbgPrintf(DBG_ERROR,"PBM_enq: Invalid Packet");
        return;
    }

    mask = OEMSysCritOn();

    pPkt->pNext = 0;

    if( !pQ->Count )
    {
        // Queue is empty - Initialize it with this one packet
        pQ->pHead = pPkt;
        pQ->pTail = pPkt;
        pQ->Count = 1;
    }
    else
    {
        // Queue is not empty - Push onto END
        pQ->pTail->pNext = pPkt;
        pQ->pTail        = pPkt;
        pQ->Count++;
    }

    OEMSysCritOff(mask);
}


//--------------------------------------------------------------------
// PBMQ_deq()
//
// Dequeue a packet from the supplied queue
//--------------------------------------------------------------------
PBM_Handle PBMQ_deq( PBMQ *pQ )
{
    PBM_Pkt *pPkt;
    uint     mask;

    mask = OEMSysCritOn();

    pPkt = pQ->pHead;

    if( pPkt )
    {
        pQ->pHead = pPkt->pNext;
        if( !pQ->pHead )
            pQ->pTail = 0;
        pQ->Count--;
        pPkt->pPrev = pPkt->pNext = 0;
    }

    OEMSysCritOff(mask);

    return( (PBM_Handle)pPkt );
}


⌨️ 快捷键说明

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