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

📄 mem.c

📁 基于56F8346的异步电机VVVF控制程序。
💻 C
📖 第 1 页 / 共 4 页
字号:
  SizeNeeded &= ~3;
  #endif
  if (SizeNeeded >= sizeof(sBlockHead)) {
    /* Set the size of the user part of the split. */
    pUser = (sBlockHead *)(((char *)pBlock) + SizeNeeded);
    assert ((((UWord16)pUser) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
    assert (((BlockSize - SizeNeeded) & 0x0003) == 0); /* Ensure that Remainder is double-word aligned */
    pUser -> Size  = (Int32) (BlockSize - SizeNeeded);
    assert ((pUser -> Size & 0x0003) == 0); /* Ensure that pUser -> Size is double-word aligned */
    assert ((SizeNeeded & 0x0003) == 0); /* Ensure that Remainder is double-word aligned */
    pBlock -> Size = (Int32) SizeNeeded;
    assert ((pBlock -> Size & 0x0003) == 0); /* Ensure that pUser -> Size is double-word aligned */
  }
  else {
    pUser = pBlock;
  }
  /* Store a pointer to a likely candidate block. */
  archGetSetSaturationMode(bSatMode);
  return pUser;
}
#pragma warn_unusedarg reset


/*******************************************************
*
* Method: memInitializePool
*
* Description: This function Initializes the memory pool to all zeroes.
*              Brackets the pool with two blocks: The last sizeof(UInt32)
*              bytes will be set to 0 to indicate the last block of the pool.
*              The first sizeof(UInt32) bytes of the pool will be set
*              to the size of the remainder of the pool.
*
* Arguments:
*   pMemPool - pointer to the memory pool
*       pMem - pointer to the memory
*       Size - size of the memory block
*    Protect - TRUE = enable protect memory
*     Assert - TRUE = enable assert
*
* Return:      None
*
*******************************************************/
extern void memInitializePool(mem_sPool * pMemPool,
                    void      * pMem,
                    size_t      Size,
                    bool        Protect,
                    bool        Assert)
{
  bool         bSatMode;
  sBlockHead * pFirst = (sBlockHead *)pMem;
  sBlockHead * pLast;
  sPool      * pPool = (sPool *) pMemPool;

  bSatMode = archGetSetSaturationMode(false);
  /* Ensure that pFirst is double-word aligned */
  assert ((((UWord16)pFirst) & 0x0001) == 0);
  /* Ensure that enough memory has been allocated */
  assert (Size >= 2 * sizeof(sBlockHead));
  /* Make sure that we've allocated enough space for the mem pool. */
  assert(sizeof(mem_sPool) >= sizeof(sPool));
  /* Clear the entire memory pool. */
  memset((void *)pFirst, 0, Size);
  /* Mark the first block with the size of the entire allocatable memory
  // pool.  The size always includes the size of the sBlockHead. */
  Size -= sizeof(*pLast);
  /* Ensure that Remainder is double-word aligned */
  assert ((Size & 0x0003) == 0);
  pFirst -> Size = (Int32)Size;
  /* Point pLast to end of the memory pool and mark the end block with a
  // zero end marker. */
  pLast = (sBlockHead *) ((char *) pFirst + Size);
  /* Ensure that pLast is double-word aligned */
  assert ((((UWord16)pLast) & 0x0001) == 0);
  pLast -> Size  = 0;
  /* If the user wants atomic access to this memory pool... */
  if (Protect) {
    memProtect((mem_sPool *) pPool);
  }
  /* Prime the memory pool. */
  pPool -> Assert      = Assert;
  pPool -> pFirst      = pFirst;
  pPool -> pLast       = pLast;
  pPool -> pCurrent    = pFirst;
  pPool -> Protect     = Protect;
  archGetSetSaturationMode(bSatMode);
}


/*******************************************************
*
* Method: memExtendPool
*
* Description: Initializes the memory pool extension to all zeroes.  Extends the
*              pool previously initialized with memInitializePool.
*
* Arguments:
*   pMemPool - pointer to the memory pool
*       pMem - pointer to the memory block
*       Size - size of the memory block
*
* Return:      None
*
*******************************************************/
void memExtendPool ( mem_sPool * pMemPool,
              void      * pMem,
              size_t      Size
              )
{
  bool         bSatMode;
  sBlockHead * pFirst = (sBlockHead *)pMem;
  sBlockHead * pLast;
  sBlockHead * pTemp;
  sBlockHead * pNext;
  sPool      * pPool  = (sPool *) pMemPool;

  bSatMode = archGetSetSaturationMode(false);
  /* Ensure that pFirst is double-word aligned */
  assert ((((UWord16)pFirst) & 0x0001) == 0);
  /* Ensure that enough memory has been allocated */
  assert (Size >= 2 * sizeof(sBlockHead));
  /* Clear the entire memory pool. */
  memset((void *)pFirst, 0, Size);
  /* Mark the first block with the size of the entire extension
  // The size always includes the size of the sBlockHead. */
  Size -= sizeof(*pLast);
  /* Ensure that Remainder is double-word aligned */
  assert ((Size & 0x0003) == 0);
  pFirst -> Size = (Int32)Size;
  /* Point pLast to end of the memory pool and mark the end block with a
  // zero end marker. */
  pLast         = (sBlockHead *) ((char *) pFirst + Size);
  assert ((((UWord16)pLast) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  /* Link the extension into the pool */
  if (pLast < pPool->pFirst) {
    pLast->Size   = (Int32)((UInt32)((char*)pLast) - (UInt32)((char*)(pPool->pFirst)));
    pPool->pFirst = pFirst;
  } else if (pFirst > pPool->pLast) {
    pPool->pLast->Size = (Int32)(((UInt32)((char*)(pPool->pLast))) - ((UInt32)((char*)pFirst)));
    pLast->Size  = 0;
    pPool->pLast = pLast;
  } else {
    pTemp = pPool->pFirst;
    while (true) {
      if (pTemp->Size > 0) {
        pTemp = (sBlockHead *)(((char *)pTemp) + pTemp->Size);
        /* Ensure that pBlock is double-word aligned */
        assert ((((UWord16)pTemp) & 0x0001) == 0);
      } else {
        pNext = (sBlockHead *)(((char *)pTemp) - pTemp->Size);
        /* Ensure that pBlock is double-word aligned */
        assert ((((UWord16)pNext) & 0x0001) == 0);
        if (pFirst > pTemp && pLast < pNext) {
          pTemp->Size = (Int32)((UInt32)((char*)pTemp) - (UInt32)((char*)pFirst));
          /* Ensure that Remainder is double-word aligned */
          assert ((pTemp->Size & 0x0003) == 0);
          pLast->Size = (Int32)((UInt32)((char *)pLast) - (UInt32)((char *)pNext));
          /* Ensure that Remainder is double-word aligned */
          assert ((pLast->Size & 0x0003) == 0);
          break;
        }
        pTemp = pNext;
      }
    }
  }
  archGetSetSaturationMode (bSatMode);
}

/*******************************************************
*
* Method: memFree
*
* Description: This method frees the allocated memory.
*
* Arguments:
*   pMemPool - pointer to the memory pool
*
* Return:      None
*
*******************************************************/
#pragma warn_unusedarg off
extern void memFree(mem_sPool * pMemPool, void * pData)
{
  bool         bSatMode;
  sBlockHead * pBlock = pData;

  /* The following two lines are a check to ensure that
  // dynamic memory has been enabled in the SDK application.
  // If the user has failed to either "#define INCLUDE_MEMORY"
  // in the appconfig.h file or include a dynamic memory
  // partition list in the linker.cmd file, he will now get
  // a link error. */
  extern UInt16 memNumEMpartitions;

  bSatMode = (bool) memNumEMpartitions;
  assert (bMemInitialized);
  assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  /* If pData is NULL, return, per ANSI C. */
  if (pData == NULL)
    return;
  bSatMode = archGetSetSaturationMode(false);
  pBlock -= 1;
  if (pBlock -> Size > 0) {
    assert(!"Attempt to free memory never allocated or previously freed");
  }
  /* Make the block available. */
  /* Ensure that Remainder is double-word aligned */
  assert ((pBlock->Size & 0x0003) == 0);
  pBlock -> Size = -(pBlock -> Size);
  archGetSetSaturationMode (bSatMode);
}
#pragma warn_unusedarg reset


/*******************************************************
*
* Method: memMallocWrapper
*
*******************************************************/
#pragma warn_unusedarg off
extern void * memMallocWrapper(mem_sPool * pPool, size_t Size,
                                const char *pFile, int Line)
{
  void       * pData;

  /* Call the base allocator.  We use the parenthesis to prevent the
  // preprocessor from substituting memMalloc with memMallocWrapper,
  // causing endless recursion into this routine. */
  pData = (memMalloc)(pPool, Size);
  if (pData == NULL)
    return (void *) NULL;
  return pData;
}
#pragma warn_unusedarg reset

/*******************************************************
*
*  memMalloc
*     If the size requested is 0, return NULL, per ANSI C.
*
*  LABEL:
*     WHILE we haven't yet allocated a block DO
*       Skip blocks in use.
*
*       IF we hit the tail block of the pool THEN
*         IF we have already wrapped through the pool once THEN
*           return NULL to indicate failure to allocate.
*         ELSE
*           Reset the block pointer to the first block of the pool.
*           Indicate that we have wrapped around.
*           Continue from LABEL.
*       ENDIF
*
*       Merge all contiguous free blocks from the current block to the
*         first in-use block or the end of the pool.
*       IF the consolidated block satisfies the request THEN
*         Split the block, if it is large enough and return the first block
*           of the split.
*       ENDIF
*
*       Bump the block search pointer to the next block
*     ENDWHILE
*
*******************************************************/
void * (memMalloc)(mem_sPool * pMemPool, size_t Size)
{
  bool         bSatMode;
  Int32        SizeNeeded = (Int32) Size;
  Int32        BlockSize;
  int          Wrapped;
  sBlockHead * pBlock;
  void       * pMemory    = (void *) NULL;
  sPool      * pPool      = (sPool *) pMemPool;
  /* The following two lines are a check to ensure that
  // dynamic memory has been enabled in the SDK application.
  // If the user has failed to either "#define INCLUDE_MEMORY"
  // in the appconfig.h file or include a dynamic memory
  // partition list in the linker.cmd file, he will now get
  // a link error. */
  extern UInt16 memNumEMpartitions;

  BlockSize = memNumEMpartitions;
  if(bMemInitialized == false) {
    Initialize();
  }
  if (SizeNeeded == 0) return (void *) NULL;
  bSatMode = archGetSetSaturationMode(false);
  #ifdef ADDRESSING_8
  /* Allocate in 4 8-bit units only. */
  SizeNeeded = ((SizeNeeded + 3) & ~3);
  #endif
  SizeNeeded += sizeof(sBlockHead);
  assert ((SizeNeeded & 0x0003) == 0); /* Ensure that SizeNeeded is double-word aligned */
  pBlock  = pPool -> pCurrent;
  assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  Wrapped = false;
  while (true) {
    /* Skip blocks in use. */
    while (true) {
      BlockSize = pBlock -> Size;
      if (BlockSize >= 0) break;
      /* Typecasting required to force 32 bit operation and preserve negative BlockSize */
      pBlock = (sBlockHead *) (((UInt32)((char *)pBlock) - BlockSize)/2);
      assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
    }
    /* Found a block that is not in use.  If it's the last block of the pool,
    // wrap to the beginning. If we reach the end after wrapping, then we're
    // out of memory. */
    if (BlockSize == 0) {
      if (Wrapped) break;
      pBlock  = pPool -> pFirst;
      assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
      Wrapped = true;
      continue;
    }
    /* We're now at a block that is not in use.  We optimize for
    // the hopeful case, where the current blocksize is big
    // enough and we don't have to make a costly call to merge
    // free blocks.  If the block is big enough, we split it
    // and leave the loop. */
    if (BlockSize >= SizeNeeded) {
      pMemory = SplitBlock(pPool, pBlock, SizeNeeded);
      break;
    }
    /* Merge free blocks that immediately follow this one in an
    // attempt to make the current block big enough. */
    BlockSize = MergeFree(pPool, pBlock, SizeNeeded);
    /* If the (now merged) free block is big enough, we split it in two
    // if the remainder is big enough to make it worthwhile.
    //
    // If the block still isn't big enough, at least we made a bigger
    // free block that will make for faster allocations later. */
    if (BlockSize >= SizeNeeded) {
      pMemory = SplitBlock(pPool, pBlock, SizeNeeded);
      break;
    }
    /* Move to the next candidate block and loop back up to try again */
    pBlock = (sBlockHead *) ((char *) pBlock + BlockSize);
    assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
  }

⌨️ 快捷键说明

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