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

📄 memorybuffer.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
字号:
// MemoryBuffer.cpp: implementation of the CMemoryBuffer class.
//
//////////////////////////////////////////////////////////////////////

#include "includes.h"
#include "MemoryBuffer.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMemoryBuffer::CMemoryBuffer():
	m_pChunks(NULL),	// the physical addresses of the memory chunks
	m_pVirtualAddress(NULL),			// the virtual address
	m_ulSize(0),			// the size
	m_nChunks(0)

{
	FUNCMSG("+CMemoryBuffer::CMemoryBuffer()");
}

CMemoryBuffer::~CMemoryBuffer()
{
	FUNCMSG("+CMemoryBuffer::~CMemoryBuffer()");
	FreeBuffer();
}

bool CMemoryBuffer::ReservePhysicalMem(ULONG dwSize)
{

	FUNCMSG1("+CMemoryBuffer::ReservePhysicalMem(%d)", dwSize);

	FreeBuffer();
	
	//
	// Allocate a buffer
	//
	m_pVirtualAddress = (LPBYTE)VirtualAlloc(0, dwSize, MEM_COMMIT , PAGE_READWRITE | PAGE_NOCACHE);
	if (!m_pVirtualAddress)
	{
		ERRMSG("CMemoryBuffer:ReservePhysicalMem:Allocate: Buffer Allocation Failed");
		FreeBuffer();
		return false;
	}

    // let's first find the maximum # of pages that could be locked
    UINT cPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(NULL, dwSize);

	//INFMSG1(" CMemoryBuffer::ReservePhysicalMem; needs %d pages", cPages);

    // allocate an array for the maximum # of pages
    ULONG *pPages = new ULONG[cPages];
	if(!pPages)
	{
		ERRMSG("CMemoryBuffer:ReservePhysicalMem: Failed to allocate Pageframe array");
		VirtualFree((VOID *)(m_pVirtualAddress), 0, MEM_RELEASE);
		m_pVirtualAddress = NULL;
		m_pChunks = NULL;
		return false;
	}

	if (!LockPages((VOID *)(m_pVirtualAddress), dwSize, pPages, LOCKFLAG_WRITE))
	{
		ERRMSG("CMemoryBuffer:ReservePhysicalMem: LockPages Failed");
		VirtualFree((VOID *)(m_pVirtualAddress), 0, MEM_RELEASE);
		delete[] pPages;
		m_pVirtualAddress = NULL;
		return false;
	}

	//
	// consolidate contiguous pages into chunks
	//

	// how many chunks?

	m_nChunks = 1;
	SYSTEM_INFO siSystemInfo;
	//get page size
	GetSystemInfo (&siSystemInfo);
	for (UINT uCurrentPage=0; uCurrentPage < cPages-1; uCurrentPage++) 
	{ 
		// LockPages fills pPages[] with the PFNs (Page Frame Numbers?) of the locked pages.
		// We need to left-shift by a magic number to get the actual physical address.
		// Note that as of this writing, the PB online help incorrectly states that we should right-shift.
		if((pPages[uCurrentPage] << UserKInfo[KINX_PFN_SHIFT]) + siSystemInfo.dwPageSize != (pPages[uCurrentPage+1] << UserKInfo[KINX_PFN_SHIFT]) )
		{
			m_nChunks++;
		}
	}

	//INFMSG1("CMemoryBuffer::ReservePhysicalMem: Number of chunks is %d", m_nChunks);

	m_pChunks = new struct SMemoryChunk[m_nChunks];

	if (!m_pChunks)
	{
		ERRMSG("CMemoryBuffer::ReservePhysicalMem: can't allocate chunks array");
		delete[] pPages;
		FreeBuffer();
		return false;
	}
	// start filling the chunks array
	UINT uCurrentChunk = 0;
	DWORD dwRemainingSize = dwSize;
	uCurrentPage = 0;
	DWORD dwCurrentPageSize;
	m_pChunks[uCurrentChunk].m_ulAddress = pPages[uCurrentPage] << UserKInfo[KINX_PFN_SHIFT];
	m_pChunks[uCurrentChunk].m_ulSize = 0;

	while (true)
	{

		// what's the size of the current page?
		dwCurrentPageSize = (dwRemainingSize > siSystemInfo.dwPageSize)?siSystemInfo.dwPageSize:dwRemainingSize;
		m_pChunks[uCurrentChunk].m_ulSize += dwCurrentPageSize;
		dwRemainingSize -= dwCurrentPageSize;
		//INFMSG2("m_pChunks[uCurrentChunk].m_ulSize is %d, dwRemainingSize is %d", m_pChunks[uCurrentChunk].m_ulSize, dwRemainingSize );
		if (dwRemainingSize <= 0)
			break;
		// is the next page in the same chunk?
		if((pPages[uCurrentPage] << UserKInfo[KINX_PFN_SHIFT]) + siSystemInfo.dwPageSize != (pPages[uCurrentPage+1] << UserKInfo[KINX_PFN_SHIFT]))
		{
			// no: go to next chunk
			uCurrentChunk++;
			m_pChunks[uCurrentChunk].m_ulSize = 0;
			m_pChunks[uCurrentChunk].m_ulAddress = (pPages[uCurrentPage+1] << UserKInfo[KINX_PFN_SHIFT]);
		}
		uCurrentPage++;
	}



#ifdef DEBUG

	for (uCurrentChunk = 0; uCurrentChunk < m_nChunks; uCurrentChunk++)
	{
		INFMSG3("CMemoryBuffer::ReservePhysicalMem: chunk %d, addr 0x%8.8x, size %d", 
			uCurrentChunk, m_pChunks[uCurrentChunk].m_ulAddress, m_pChunks[uCurrentChunk].m_ulSize);
	}


#endif

	RETAILMSG((dwRemainingSize != 0)?ZONE_ERROR:0, (TEXT("CMemoryBuffer::ReservePhysicalMem: dwRemainingSize is %d\r\n"), dwRemainingSize));
	
	delete[] pPages;

	//INFMSG2("Call memset on 0x%8.8x, size %d", m_pVirtualAddress, dwSize);
	
	memset((VOID *)(m_pVirtualAddress), 0, dwSize);
	m_ulSize = dwSize;
	return true;
}

void CMemoryBuffer::FreeBuffer()
{
	FUNCMSG1("+CMemoryBuffer::FreeBuffer(): 0x%x", m_pVirtualAddress);
	if(m_pVirtualAddress)
	{
		UnlockPages(m_pVirtualAddress, m_ulSize);
		VirtualFree(m_pVirtualAddress, 0, MEM_RELEASE);
	}
	delete[] m_pChunks;
	m_pChunks = NULL;
	m_pVirtualAddress = NULL;
	m_ulSize = m_nChunks = 0;
	FUNCMSG("-CMemoryBuffer::FreeBuffer()");
}

⌨️ 快捷键说明

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