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

📄 mem.c

📁 基于56F8346的异步电机VVVF控制程序。
💻 C
📖 第 1 页 / 共 4 页
字号:
*              cannot allocate an aligned buffer from
*              either partition, it calls memMallocEM
*              to try to allocate a buffer of the correct
*              size without the proper alignment.
*
* Arguments:
*       size - the new size of the memory buffer to be
*              allocated in internal memory
*
* Return:      If memory is insufficient to satisfy the request
*              from either partition, memMallocAlignedIM returns NULL
*
*******************************************************/
void *  memMallocAlignedEM (size_t size)
{
  void * pMem;

  pMem = memMallocAligned (&ExternalMemoryPool, size);
  if (pMem == NULL) {
    pMem = memMallocAligned (&InternalMemoryPool, size);
    if (pMem == NULL) {
      pMem = memMallocEM (size);
    }
  }
  return pMem;
}


/*******************************************************
*
* Method: memFreeEM
*
* Description: This function deallocates a memory block
*              in external memory that previously had
*              been dynamically allocated with
*              the routine memMallocEM.
*
* Arguments:
*   memblock - pointer to previously allocated memory
*
* Return:      None
*
*******************************************************/
void    memFreeEM   (void * memblock)
{
  if (memIsEM(memblock)) {
    memFree (&ExternalMemoryPool, memblock);
  }
  else {
    memFree (&InternalMemoryPool, memblock);
  }
}


/*******************************************************
*
* Method: memIsAligned
*
* Description: This function checks the address of
*              a memory block to determine whether
*              it is properly aligned to use modulo
*              addressing.
*
* Arguments:
*   memblock - the address of the memory block
*              to check alignment for modulo addressing
*       size - the size to which the block should
*              be aligned for modulo addressing
*
* Return:      The function memIsAligned returns true
*              if the address is aligned so that modulo
*              addressing can be used; otherwise, it
*              returns false.
*
*******************************************************/
bool    memIsAligned (void * memblock, size_t size)
{
  UInt16 Modulo;                       /* Modulo of the defined memory size */
  UInt16 ModuloMask;                   /* Bits mask of the modulo size */

  Modulo = 1;                          /* Set minimal modulo */
  while(size > Modulo){
    Modulo=Modulo << 1;                /* Set modulo to a double modulo (2,4,8,16, ...) */
  }
  ModuloMask = Modulo - 1;             /* Set bits mask of the modulo */
  return (((UInt16)memblock & ModuloMask) == 0); /* TRUE  - memblock mod Modulo = 0 */
                                       /* FALSE - memblock mod Modulo > 0 */
}


/*******************************************************
* Mem
*
* Description:
*   General-purpose ANSI C-compliant memory pool manager.
*
* Author:
*   Mark Glenn
*
* Design:
*   These routines manage a memory buffer that you specify, internally
*   called the pool.  Blocks of memory are allocated from and returned
*   to this pool.
*
*   The first UInt32 of every block is the size of the block
*   in bytes, inclusive.  This value is positive if the block is free,
*   negative if the block is in use, and zero if this is the last block
*   of the pool.
*******************************************************/

/* The header for each memory block in a pool. */
#pragma warn_padding off
typedef struct {
  /* The size of the block. This includes the size of this sBlockHead. */
  Int32 Size;
} sBlockHead;

/* sPool -- Holds the state of a memory pool. */
typedef struct {
  /* Points to the first block of the pool. */
  sBlockHead * pFirst;
  /* Points to the last block of the pool. */
  sBlockHead * pLast;
  /* Points to a block within the pool.  It is used
  // to remain "close" to memory most likely to be free.  We could just
  // start from the beginning of the pool each time, but then we would
  // very likely have to skip over many in-use blocks, especially as
  // memory is allocated from a fresh pool.  We wrap to pFirst if
  // there isn't enough memory between pCurrent and the end of the pool,
  // to satisfy the request. */
  sBlockHead * pCurrent;
  /* If set, aborts the program when the memory pool is
  // exhausted.  Otherwise, behave as ANSI requires. */
  bool Assert;
  /* True if we are to mutex-protect the pool. */
  bool Protect;
} sPool;
#pragma warn_padding reset


/*******************************************************
*
* Method: memProtect
*
* Description: This function set memory protection.
*
* Arguments:
*   pMemPool - pointer to the memory pool
*
* Return:      None
*
*******************************************************/
extern void memProtect(mem_sPool * pMemPool)
{
  sPool * pPool=(sPool *)pMemPool;

  pPool -> Protect=true;
}


/*******************************************************
*
* Method: memCleanUp
*
* Description: This function cleans memory.
*              Starting from the beginning of the pool,
*              merge blocks that are not in use.
*              Stop at the first in-use block.
*
* Arguments:
*   pMemPool - pointer to the memory pool
*
* Return:      Size of the free memory
*
*******************************************************/
extern size_t memCleanUp(mem_sPool * pMemPool)
{
  bool            bSatMode;
  sPool         * pPool       = (sPool *) pMemPool;
  sBlockHead    * pBlock      = pPool -> pFirst;
  sBlockHead    * pFirstBlock = pBlock;
  Int32           TotalSize   = 0;
  Int32           Size;

  bSatMode = archGetSetSaturationMode(false);
  pPool -> pCurrent = pBlock;
  while (Size = pBlock -> Size, Size != 0) {
    if (Size < 0) break;
    TotalSize += Size;
    pBlock = (sBlockHead *) (((char *) pBlock) + Size);
  }
  pFirstBlock -> Size = TotalSize;
  archGetSetSaturationMode(bSatMode);
  return (size_t)TotalSize;
}


/*******************************************************
*
* Method: MergeFree
*
* Description: This function assumes that pBlock points to a block not in-use.
*              Checks the block following to determine its state.  If it is not in-use,
*              merge it to the current block.  pBlock will not change, but the
*              size of the block to which it points may increase.
*
* Arguments:
*      pPool - pointer to the memory pool
*     pBlock - pointer to the memory pool
* SizeNeeded - size of the memory block
*
* Return:      None
*
*******************************************************/
static Int32 MergeFree(sPool* pPool, sBlockHead * pBlock, Int32 SizeNeeded)
{
  bool  bSatMode;
  Int32 CurrentSize = pBlock -> Size;

  bSatMode = archGetSetSaturationMode(false);
  assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  while (true) {
    sBlockHead * pNext;
    Int32        NextSize;

    /* Get a pointer to the next block and retrieve it's size. */
    pNext = ((sBlockHead *)(((char *) pBlock) + CurrentSize));
    assert ((((UWord16)pNext) & 0x0001) == 0); /* Ensure that pNext is double-word aligned */
    NextSize  = pNext -> Size;
    assert ((NextSize & 0x0003) == 0); /* Ensure that NextSize is double-word aligned */
    /* If the next block is in use or is the last block (Size == 0), return. */
    if (NextSize <= 0) {
      assert ((CurrentSize & 0x0003) == 0); /* Ensure that NextSize is double-word aligned */
      pBlock -> Size = CurrentSize;
      archGetSetSaturationMode (bSatMode);
      return CurrentSize;
    }
    /* Increment the known size of the current block.  We won't store it
    // until we are about to leave the routine. */
    CurrentSize += NextSize;
    /* If pCurrent happens to point to the block that we are about
    // to combine, reset it to point to the beginning of the merged block. */
    if (pNext == pPool -> pCurrent)
      pPool -> pCurrent = pBlock;

    /* Optimized to get out as soon as we know we can satisfy the request. */
    if (CurrentSize >= SizeNeeded) {
      assert ((CurrentSize & 0x0003) == 0); /* Ensure that NextSize is double-word aligned */
      pBlock -> Size = CurrentSize;
      archGetSetSaturationMode (bSatMode);
      return CurrentSize;
    }
  }
}

/*******************************************************
*
* Method: SplitBlock
*
* Description: Assumes that pBlock points to a block larger than SizeNeeded.
*              If the block is large enough to contain SizeNeeded plus another block,
*              the block is split.  The area returned to the user is the user
*              portion of the first block.  The remainder in its entirety will
*              be set to describe a not-in-use block.
*
* Arguments:
*      pPool - pointer to the memory pool
*     pBlock - pointer to the memory pool
* SizeNeeded - size of the memory block
*
* Return:      None
*
*******************************************************/
#pragma warn_unusedarg off
static void * SplitBlock(sPool * pPool, sBlockHead * pBlock, Int32 SizeNeeded)
{
  bool           bSatMode;
  Int32          Remainder;
  sBlockHead   * pUser     = pBlock + 1;
  Int32          BlockSize = pBlock -> Size;

  bSatMode = archGetSetSaturationMode(false);
  assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  #ifdef ADDRESSING_8
  /* Allocate in 4 8-bit units only. */
  SizeNeeded = (SizeNeeded + 3) & ~3;
  #endif
  if ((Remainder = BlockSize - SizeNeeded) > sizeof(sBlockHead)) {
    assert ((Remainder & 0x0003) == 0); /* Ensure that Remainder is double-word aligned */
    assert ((SizeNeeded & 0x0003) == 0); /* Ensure that Remainder is double-word aligned */
    /* Set the size of the first part of the split. */
    pBlock -> Size = -SizeNeeded;
    /* Point to the next block of the split. */
    pBlock = (sBlockHead *) ((char *) pBlock + SizeNeeded);
    assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
    pBlock -> Size  = Remainder;
  }
  else {
    /* Don't split block. */
    pBlock -> Size = -BlockSize;
    pBlock         = (sBlockHead *) ((char *) pBlock + BlockSize);
    assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  }

  /* Store a pointer to a likely candidate block. */
  pPool -> pCurrent = pBlock;
  archGetSetSaturationMode(bSatMode);
  return pUser;
}
#pragma warn_unusedarg reset

/*******************************************************
*
* Method: SplitBlockRev
*
* Description: Assumes that pBlock points to a block larger than SizeNeeded.
*              If the block is large enough to contain SizeNeeded plus another block,
*              the block is split.  The area returned is the
*              portion of the end of the block.  The remainder in its entirety will
*              be set to describe a not-in-use block.
*
* Arguments:
*      pPool - pointer to the memory pool
*     pBlock - pointer to the memory pool
* SizeNeeded - size of the memory block
*
* Return:      None
*
*******************************************************/
#pragma warn_unusedarg off
static void * SplitBlockRev(sPool * pPool, sBlockHead * pBlock, UInt32 SizeNeeded)
{
  bool           bSatMode;
  sBlockHead   * pUser;
  Int32          BlockSize = pBlock -> Size;

  bSatMode  = archGetSetSaturationMode(false);
  assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  #ifdef ADDRESSING_8
  /* Allocate in 4 8-bit units only. */

⌨️ 快捷键说明

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