📄 objcore.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// 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 + -