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

📄 objcore.cpp

📁 基于Nuleus操作系统和s3c4510的编写的EFC。已经包含了该EFC的设计说明。这是个实际产品的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003, Ulink Telecom Equipment Co., Ltd. All rights reserved.
//
// File:
//
//    OBJCORE.CPP
//
// Abstract:
//
//    implementation of the CRTObject class. CRTObject class is the  principal 
//	  base class for Embedded Foundation Classes.  It serves as the root class
//	  not only for library classes such as CRTApp and CDevice,but also for the
//	  classes that you write. CRTObject provides base services, including  en-
//	  capsulation of the RTOS resources and Run-Time Type Information(RTTI).
//
// History:
//
//    V1.0	2003-06-19	Alex Duan	Original version.
//    V1.1	2003-06-30	Alex Duan	Add RTTI support
//    V1.2	2003-07-02	Alex Duan	Add HISR, PIPE, MAILBOX support
//	  V2.0  2007-5-31   Bozhong xu  Modified CreateQueue, from dwQueueSize to 
// dwQueueSize * dwMessageSize in NU_Create_Queue.
///////////////////////////////////////////////////////////////////////////////

#include "OBJCORE.h"
#include "tm_defs.h"
#include "qu_defs.h"
#include "pi_defs.h"

///////////////////////////////////////////////////////////////////////////////
// TIMERCALLBACK structure: store timer callback function pointer & parameters.
template<class TYPE>
struct TIMERCALLBACK
{
	TYPE *pThis; // this pointer of the instance of the TYPE class
	void (TYPE::*pfnTimer)(UINT); // pointer of the member function
	UINT nIDEvent;	// timer id
};

// Entry point of all timers. executes when one of the timers expires.
static void TimerProc(DWORD dwCallback)
{
	TIMERCALLBACK<CRTObject> *pCallback = (TIMERCALLBACK<CRTObject>*)dwCallback;
	ASSERT(pCallback);
	ASSERT(pCallback->pThis);
	ASSERT(pCallback->pfnTimer);
	(pCallback->pThis->*pCallback->pfnTimer)(pCallback->nIDEvent);
}

///////////////////////////////////////////////////////////////////////////////
// TASKCALLBACK structure: store task callback function pointer & parameters.
template<class TYPE>
struct TASKCALLBACK
{
	TYPE *pThis; // this pointer of the instance of the TYPE class
	void (TYPE::*pfnTask)(DWORD, void*); // pointer of the member function
	void *argv; //
};

// Entry point of all tasks.
static void TaskProc(DWORD argc, void *argv)
{
	ASSERT(argv);
	TASKCALLBACK<CRTObject> *pCallback = (TASKCALLBACK<CRTObject>*)argv;
	CRTObject *pThis = pCallback->pThis;
	PFNTASK pfnTask = pCallback->pfnTask;
	void *pArgv = pCallback->argv;
	delete pCallback;
	
	// The following function call will not return until task finished.
	(pThis->*pfnTask)(argc, pArgv);
}

///////////////////////////////////////////////////////////////////////////////
// HISRCALLBACK structure: store HISR callback function pointer & parameters
template<class TYPE>
struct HISRCALLBACK
{
	TYPE *pThis; // this pointer of the instance of the TYPE class
	void (TYPE::*pfnHISR)(void); // pointer of the member function
};

// Entry point of all HISR
static void HISRProc(void)
{
	TC_HCB *pHISR = (TC_HCB*)NU_Current_HISR_Pointer();
	ASSERT(pHISR);
	HISRCALLBACK<CRTObject> *pCallback = 
		(HISRCALLBACK<CRTObject>*)pHISR->tc_app_reserved_1;
	ASSERT(pCallback);
	(pCallback->pThis->*pCallback->pfnHISR)();
}

///////////////////////////////////////////////////////////////////////////////
// Run-Time Type Information (RTTI)

// special runtime-class structure for CRTObject (no base class)
const struct CRuntimeClass CRTObject::classCRTObject =
{ "CRTObject", sizeof(CRTObject), 0xffff, NULL, NULL, NULL };

///////////////////////////////////////////////////////////////////////////////
// Allocation/Creation

// Classes derived from CRTObject can support dynamic creation, which is the 
//	 ability to create an object of a specified class at run time. 
CRTObject* CRuntimeClass::CreateObject()
{
	if (m_pfnCreateObject == NULL)
	{
		TRACE("Error: Trying to create object which is not "\
			"DECLARE_DYNCREATE: %hs.\n", m_lpszClassName);
		return NULL;
	}
	
	CRTObject* pObject = NULL;
	pObject = (*m_pfnCreateObject)();
	return pObject;
}

// Returns TRUE if the class of the class member calling  IsDerivedFrom is 
//	 derived from the base class whose CRuntimeClass structure is given as 
//	   a parameter. 
BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
{
	ASSERT(this != NULL);
	ASSERT(pBaseClass != NULL);
	
	const CRuntimeClass* pClassThis = this;
	while (pClassThis != NULL)
	{
		if (pClassThis == pBaseClass)
			return TRUE;
		pClassThis = pClassThis->m_pBaseClass;
	}
	return FALSE;       // walked to the top, no match
}

// Returns the CRuntimeClass structure corresponding to this object’s class.
CRuntimeClass* CRTObject::GetRuntimeClass() const
{
	return RUNTIME_CLASS(CRTObject);
}

// Tests this object's relationship to a given class.
BOOL CRTObject::IsKindOf(const CRuntimeClass* pClass) const
{
	ASSERT(this != NULL);
	
	CRuntimeClass* pClassThis = GetRuntimeClass();
	return pClassThis->IsDerivedFrom(pClass);
}

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

CRTObject::CRTObject()
{
}

CRTObject::~CRTObject()
{
	CString strName;
	POSITION pos;
	
	// free memory of tasks	
	NU_TASK *pTask = NULL;
	pos = m_mapTasks.GetStartPosition();
	while (pos != NULL)
	{
		m_mapTasks.GetNextAssoc(pos, strName, pTask);
		VERIFY(DeleteTask(strName));
	}

	// free memory of timers	
	NU_TIMER *pTimer = NULL;
	pos = m_mapTimers.GetStartPosition();
	while (pos != NULL) 
	{
		m_mapTimers.GetNextAssoc(pos, strName, pTimer);
		VERIFY(DeleteTimer(strName));
	}
	
	// free memory of drivers	
	NU_DRIVER *pDriver = NULL;
	pos = m_mapDrivers.GetStartPosition();
	while (pos != NULL)
	{
		m_mapDrivers.GetNextAssoc(pos, strName, pDriver);
		VERIFY(DeleteDriver(strName));
	}
	
	// free memory of queues	
	NU_QUEUE *pQueue = NULL;
	pos = m_mapQueues.GetStartPosition();
	while (pos != NULL)
	{
		m_mapQueues.GetNextAssoc(pos, strName, pQueue);
		VERIFY(DeleteQueue(strName));
	}
	
	// free memory of event groups	
	NU_EVENT_GROUP *pEventGroup = NULL;
	pos = m_mapEventGroups.GetStartPosition();
	while (pos != NULL)
	{
		m_mapEventGroups.GetNextAssoc(pos, strName, pEventGroup);
		VERIFY(DeleteEventGroup(strName));
	}
	
	// free memory of semaphores	
	NU_SEMAPHORE *pSemaphore = NULL;
	pos = m_mapSemaphores.GetStartPosition();
	while (pos != NULL)
	{
		m_mapSemaphores.GetNextAssoc(pos, strName, pSemaphore);
		VERIFY(DeleteSemaphore(strName));
	}

	// free memory of HISR	
	NU_HISR *pHISR = NULL;
	pos = m_mapHISRs.GetStartPosition();
	while (pos != NULL) 
	{
		m_mapHISRs.GetNextAssoc(pos, strName, pHISR);
		VERIFY(DeleteHISR(strName));
	}

	// free memory of Mailbox
	NU_MAILBOX *pMailbox = NULL;
	pos = m_mapMailboxes.GetStartPosition();
	while (pos != NULL) 
	{
		m_mapMailboxes.GetNextAssoc(pos, strName, pMailbox);
		VERIFY(DeleteMailbox(strName));
	}

	// free memory of pipe
	NU_PIPE *pPipe = NULL;
	pos = m_mapPipes.GetStartPosition();
	while (pos != NULL) 
	{
		m_mapPipes.GetNextAssoc(pos, strName, pPipe);
		VERIFY(DeletePipe(strName));
	}
}

///////////////////////////////////////////////////////////////////////////////
// Parameters:
//		All the parameters are same as those in Nucleus
// Return Value:
//		pointer of the task been created if successful, otherwise NULL.
// Remarks:
//		Create an application task.
NU_TASK* CRTObject::CreateTask(LPCSTR lpszName, PFNTASK pfnTask, 
	DWORD argc, void *argv, DWORD dwStackSize, DWORD dwTimeSlice, 
	OPTION oPriority, OPTION oPreempt, OPTION oAutoStart)
{
	ASSERT(lpszName);
	ASSERT(pfnTask);
	
	NU_TASK *pTask = NULL;	// New task block
	
	// check if the task of this name has been created before in DEBUG 
	//   version.
	ASSERT(!m_mapTasks.Lookup(lpszName, pTask));	// Check existing task
	
	pTask = new NU_TASK;
	ASSERT(pTask);
	
	BYTE *puMem = new BYTE[dwStackSize];
	ASSERT(puMem);
	
	TASKCALLBACK<CRTObject> *pCallback = new TASKCALLBACK<CRTObject>;
	ASSERT(pCallback);
	pCallback->pThis = this;
	pCallback->pfnTask = pfnTask;
	pCallback->argv = argv;
	if (NU_Create_Task(pTask, (LPSTR)lpszName, TaskProc, argc, pCallback, puMem, 
		dwStackSize, oPriority, dwTimeSlice, oPreempt, oAutoStart) != NU_SUCCESS)
	{// failed to create task
		delete pTask;
		pTask = NULL;
		delete[] puMem;
		delete pCallback;
		ASSERT(FALSE);
	}
	else
	{
		m_mapTasks.SetAt(lpszName, pTask);
	}
	return pTask;
}

///////////////////////////////////////////////////////////////////////////////
// Parameters:
//		lpszName		Name of the timer
//		nIDEvent		Specifies a timer identifier
//		nElapse			Specifies a time-out value (nElapse * 1ms)
//		pfnTimerProc	Specifies the address of the application-supplied call-
//						back function, if this parameters is NULL, OnTimer is
//						called when timer expires.
//		nInitialTicks	Specifies the initial number of the timer ticks
//		oEnable			NU_ENABLE_TIEMR/NU_DISABLE_TIMER
// Return Value:
//		pointer of the timer been created if successful, otherwise NULL.
// Remarks:
//		Creates an system timer. A Time-out value is specified, and every time
//		a time-out occurs, the system automatically calls OnTimer when pfnTimer
//		is NULL or calls the application-defined callback function.
NU_TIMER* CRTObject::CreateTimer(LPCSTR lpszName, UINT nIDEvent, UINT nElapse,
	UINT nInitialTicks, PFNTIMER pfnTimer, OPTION oEnable)
{
	ASSERT(lpszName);
	NU_TIMER *pTimer = NULL;
	
	// check if the timer of this name has been created before in DEBUG 
	//   version.
	ASSERT(!m_mapTimers.Lookup(lpszName, pTimer));
	
	pTimer = new NU_TIMER;
	ASSERT(pTimer);
	
	TIMERCALLBACK<CRTObject> *pCallback = new TIMERCALLBACK<CRTObject>;
	ASSERT(pCallback);
	pCallback->pThis = this;
	pCallback->pfnTimer = (pfnTimer == NULL) ? &CRTObject::OnTimer : pfnTimer;
	pCallback->nIDEvent = nIDEvent;
	if (NU_Create_Timer(pTimer, (LPSTR)lpszName, TimerProc, (DWORD)pCallback, 
		nInitialTicks, nElapse, oEnable) != NU_SUCCESS)
	{// failed to create timer
		delete pTimer;
		pTimer = NULL;
		delete pCallback;
		ASSERT(FALSE);
	}
	else
	{
		m_mapTimers.SetAt(lpszName, pTimer);
	}
	return pTimer;
}

///////////////////////////////////////////////////////////////////////////////
// Parameters:
//		lpszName		The name of the driver
//		pfnDriverProc	Specifies the function entry point to the driver.
// Return Value:
//		pointer of the driver been created if successful, otherwise NULL.
// Remarks:
//		Creates an Input/Output driver
NU_DRIVER* CRTObject::CreateDriver(LPCSTR lpszName, void(*pfnDriverProc)
								   (NU_DRIVER*, NU_DRIVER_REQUEST*))
{
	ASSERT(lpszName);
	ASSERT(pfnDriverProc);
	
	NU_DRIVER *pDriver = NULL;
	
	// check if the driver of this name has been created before in DEBUG 
	//   version.
	ASSERT(!m_mapDrivers.Lookup(lpszName, pDriver));
	
	pDriver = new NU_DRIVER;
	ASSERT(pDriver);
	
	if (NU_Create_Driver(pDriver, (LPSTR)lpszName, pfnDriverProc) != NU_SUCCESS)
	{// failed to create driver
		delete pDriver;
		pDriver = NULL;
		ASSERT(FALSE);
	}
	else
	{
		m_mapDrivers.SetAt(lpszName, pDriver);
	}
	return pDriver;
}

///////////////////////////////////////////////////////////////////////////////
// Parameters:
//		lpszName		Name of the queue
//		dwQueueSize		Specifies the number of DWORD elements in the queue. 
//		oMessageType	Specifies the type of messages managed by the queue.
//						(NU_FIXED_SIZE/NU_VARIABLE_SIZE)
//		dwMessageSize	Size of each message in DWORDs
//		oSuspendType	Specifies how tasks suspend on the queue.
//						(NU_FIFO/NU_PRIORITY)
// Return Value:
//		pointer of the queue been created if successful, otherwise NULL
// Remarks:
//		Creates a message queue. Queues are created to support management of
//		either fixed or variable sized messages. Queue messages are comprised
//		of one or more DWORD data elements.
NU_QUEUE* CRTObject::CreateQueue(LPCSTR lpszName, DWORD dwQueueSize, 
	OPTION oMessageType, DWORD dwMessageSize, OPTION oSuspendType)
{
	ASSERT(lpszName);
	NU_QUEUE *pQueue = NULL;
	
	// check if the queue of this name has been created before in DEBUG 
	//   version.
	ASSERT(!m_mapQueues.Lookup(lpszName, pQueue)); // Check exists queue
	
	pQueue = new NU_QUEUE;
	ASSERT(pQueue);
	
	BYTE *puMem = new BYTE[dwQueueSize * dwMessageSize * sizeof(DWORD)];
	ASSERT(puMem);
	
	if (NU_Create_Queue(pQueue, (LPSTR)lpszName, puMem, 
		(dwQueueSize * dwMessageSize), oMessageType, 
		dwMessageSize, oSuspendType) != NU_SUCCESS)
	{// failed to create queue
		delete pQueue;
		pQueue = NULL;
		delete[] puMem;
		ASSERT(FALSE);
	}
	else
	{
		m_mapQueues.SetAt(lpszName, pQueue);
	}
	return pQueue;
}

///////////////////////////////////////////////////////////////////////////////
// Parameters:
//		lpszName		Name of the event group
// Return Value:
//		pointer of the event group created if successful, otherwise NULL.
// Remarks:
//		Creates an event flag group. Each event flag group contains 32 event
//		flags.  All event flags are initially set to 0. 
NU_EVENT_GROUP* CRTObject::CreateEventGroup(LPCSTR lpszName)
{
	ASSERT(lpszName);

	NU_EVENT_GROUP *pEventGroup = NULL;

	// check if the event group of this name has been created before in DEBUG
	//   version.
	ASSERT(!(m_mapEventGroups.Lookup(lpszName, pEventGroup)));
	
	pEventGroup = new NU_EVENT_GROUP;
	ASSERT(pEventGroup);

	if (NU_Create_Event_Group(pEventGroup, (LPSTR)lpszName) != NU_SUCCESS)
	{// failed to create the event group
		delete pEventGroup;
		pEventGroup = NULL;
		ASSERT(FALSE);
	}
	else
	{
		m_mapEventGroups.SetAt(lpszName, pEventGroup);
	}
	return pEventGroup;
}

///////////////////////////////////////////////////////////////////////////////
// Parameters:
//		lpszName		The name of the semaphore
//		dwInitialCount	Specifies the initial count of the semaphore
//		oSuspendType	NU_FIFO/NU_PRIORIFY
// Return Value:
//		pointer of the semaphore been created if successful, otherwise NULL
// Remarks:
//		Creates a counting semaphore
NU_SEMAPHORE* CRTObject::CreateSemaphore(LPCSTR lpszName, DWORD dwInitialCount, 
							   OPTION oSuspendType)
{
	ASSERT(lpszName);

	NU_SEMAPHORE *pSemaphore = NULL;

	// check if the semaphore of this name has been created before in DEBUG 
	//   version.
	ASSERT(!m_mapSemaphores.Lookup(lpszName, pSemaphore));

	pSemaphore = new NU_SEMAPHORE;
	ASSERT(pSemaphore);

	if (NU_Create_Semaphore(pSemaphore, (LPSTR)lpszName, dwInitialCount,
		oSuspendType) != NU_SUCCESS)
	{// failed to create semaphore
		delete pSemaphore;
		pSemaphore = NULL;
		ASSERT(FALSE);
	}
	else
	{
		m_mapSemaphores.SetAt(lpszName, pSemaphore);
	}
	return pSemaphore;
}

///////////////////////////////////////////////////////////////////////////////
// Parameters:
//		lpszName		The name of the HISR
//		pfnHISR			pointer of the HISR's entry member function
//		dwStackSize		number of bytes in the HISR stack
//		oPriority		There are three HISR priorities (0-2). 0 is the highest. 

⌨️ 快捷键说明

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