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

📄 buffer.h

📁 这项工程将让您把自己的MP3播放器平台
💻 H
字号:
//++
//buffer.h - buffer management declarations
//
// Copyright (C) 2005 by Spare Time Gizmos.  All rights reserved.
//
// This file is part of the Spare Time Gizmos' MP3 Player firmware.
//
// This firmware is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 59 Temple
// Place, Suite 330, Boston, MA  02111-1307  USA
//
//REVISION HISTORY:
// dd-mmm-yy    who     description
// 28-May-05	RLA	New file.
// 19-Oct-05	RLA	Add STACKSLOCS hack to InitializeBuffers() for SDCC.
//--
#ifndef _buffer_h_
#define _buffer_h_
#include "slocs.h"	// STACKSLOCS hack for SDCC

//   Our queues are single linked structures described by a head pointer
// (points to the first item in the queue) and a tail pointer (points to
// the last item in the queue).  Generally, the head pointer is used for
// removing items from the front of the queue and the tail pointer is used
// to add items to the end of the queue.  A queue with only one item has
// pHead == pTail, and an empty queue has pHead == NULL.  In the case of an
// empty queue the pTail is undefined and could be anything.
//
//   IMPORTANT!!  None (NONE!) of these macros are interrupt safe.  Any time
// you use one on a queue that's shared by both the background and interrupt
// level it needs to be bracketed with INT_OFF and INT_ON macros. That goes
// for the free buffer list (RELEASE_BUFFER and ALLOCATE_BUFFER macros) too!!


// If you change this data structure, you'll have to change MP3DRQ!!!
typedef struct _BUFFER_CONTROL_BLOCK BUFFER_CONTROL_BLOCK;
typedef BUFFER_CONTROL_BLOCK BCB;
typedef BUFFER_CONTROL_BLOCK IDATA *PIBCB;
//   WARNING - the code in the MP3DRQ ISR (MP3DRQ.A51) makes some assumptions
// about the order and size of the fields in this structure.  If you do anything
// other than add new fields to the end, you'll have to change that module!
struct _BUFFER_CONTROL_BLOCK {
  BCB IDATA *pNext;
  BYTE XDATA *pbBuffer;
  WORD cbBuffer;
};


//   This macro will add a buffer to the specified queue.  Buffers are always
// added to the end of the queue in FIFO fashion and only pTail is changed.
// Unless, of course, the queue is empty in which case both pHead and pTail
// must be updated...
#define ADD_TO_QUEUE(pBCB,pHead,pTail) {		\
    pBCB->pNext = NULL;					\
    if (pHead == NULL)					\
      pHead = pTail = pBCB;				\
    else						\
      pTail->pNext = pBCB, pTail = pBCB;		\
  }

//   And this macro will remove the first item from the head of the queue and
// return its BCB pointer.  If the queue is empty, then NULL results.  Note
// that the pTail pointer is unused - it's included as a parameter only for
// symmetry with ADD_TO_QUEUE()...
#define REMOVE_FROM_QUEUE(pBCB,pHead,pTail) {  		\
    pBCB = pHead;					\
    if (pHead != NULL) pHead = pHead->pNext;		\
  }

//   This macro will allocate a free buffer by removing it from the free
// buffer queue.  If there are no free buffers left, then the resulting
// pointer will be NULL...
#define ALLOCATE_BUFFER(pBCB) {  			\
    pBCB = g_pFreeBufferList;				\
    if (g_pFreeBufferList != NULL) 			\
      g_pFreeBufferList = g_pFreeBufferList->pNext;	\
  }


//   This macro will return a buffer to the free buffer pool.  It's basically
// a special case of ADD_TO_QUEUE that adds the free buffer to the free buffer
// queue, but in this case we add it to the head of the queue.  For free
// buffers the order is arbitrary and we save a byte or two of RAM by not
// keeping track of a pTail.
#define RELEASE_BUFFER(pBCB) {				\
     pBCB->pNext = g_pFreeBufferList;                  \
     g_pFreeBufferList = pBCB;				\
   }


//   Although the buffers are allocated dynamically in XDATA at startup, the
// buffer control blocks themselves must be stored in IDATA and are allocated
// statically.  Since IDATA is a limited resource, there's a very finite limit
// on the number of BCBs, and therefore the number of buffers, we can have.
// For example, on the P89C668 MCU there's enough XDATA RAM for 14 or 15 buffers,
// but since we have IDATA space for only 4 or 5 BCBs, the remaining RAM goes
// unused.  However on the P89C664, there's only enough XDATA RAM for two or
// three buffers, and the remaining BCBs are unused.  Can't win :-)
#define MAX_NUMBER_OF_BUFFERS	4

//   Note that the actual buffer control block array, m_aBufferControlBlocks,
// is not global.  It doesn't need to be - all BCBs are accessed thru the free
// list, which contains their address.
//extern BUFFER_CONTROL_BLOCK idata m_aBufferControlBlocks[NUMBER_OF_BUFFERS];

// The list of free BCBs, however, is global!
extern PIBCB g_pFreeBufferList;

// Methods...
extern void InitializeBuffers (WORD cbReserved) STACKSLOCS;
#ifdef DEBUG
extern BYTE ShowBufferPool (void);
#endif


#endif	// _buffer_h_

⌨️ 快捷键说明

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