-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
//Ser_smdk2440.cpp (ce6.0\platform\mini2440\src\drivers\serial):CSerialPDD * CreateSerialObject
//这这部分位于PDD层
CSerialPDD * CreateSerialObject(LPTSTR lpActivePath, PVOID pMdd,PHWOBJ pHwObj, DWORD DeviceArrayIndex)
{
CSerialPDD * pSerialPDD = NULL;
switch (DeviceArrayIndex) {
case 0:
# if !defined(KITL_SERIAL_UART0)
pSerialPDD = new CPdd2440Serial0(lpActivePath,pMdd, pHwObj);
# endif
break;
case 1:
# if !defined(KITL_SERIAL_UART1)
pSerialPDD = new CPdd2440Serial1(lpActivePath,pMdd, pHwObj);
break;
# endif
case 2:
pSerialPDD = new CPdd2440Serial2(lpActivePath,pMdd, pHwObj);
break;
}
if (pSerialPDD && !pSerialPDD->Init()) {
delete pSerialPDD;
pSerialPDD = NULL;
}
return pSerialPDD;
}
-----------------------------------------------------------------------------------------
//这部分位于 pdd COMMOM层
PVOID
SerInit(
ULONG Identifier, // @parm Device identifier.
PVOID pMddHead, // @parm First argument to mdd callbacks.
PHWOBJ pHWObj // @parm Pointer to our own HW OBJ for this device
)
{
DEBUGMSG (ZONE_CLOSE,(TEXT("+SerInit, 0x%X\r\n"), Identifier));
CSerialPDD * pSerialPDD = NULL;
if (pHWObj) {
DWORD dwIndex= pHWObj->dwIntID;
pHWObj->dwIntID = 0;
pSerialPDD = CreateSerialObject((LPTSTR)Identifier,pMddHead, pHWObj,dwIndex);
}
if (pSerialPDD==NULL) {
ASSERT(FALSE);
LocalFree(pHWObj);
}
DEBUGMSG (ZONE_CLOSE,(TEXT("-SerInit, 0x%X\r\n"), pSerialPDD));
return pSerialPDD;
}
-----------------------------------------------------------------------------------------
typedef struct __HW_VTBL {
PVOID (*HWInit)(ULONG Identifier, PVOID pMDDContext, PHWOBJ pHWObj);
ULONG (*HWDeinit)(PVOID pHead);
--------------------------------------------------------------------------------------------------------------
HW_VTBL IoVTbl = {
SerInit,
SerPostInit,
--------------------------------------------------------------------------------------------------------------
extern "C" PHWOBJ
GetSerialObject(
DWORD DeviceArrayIndex
)
{
PHWOBJ pSerObj;
pSerObj=(PHWOBJ)LocalAlloc( LPTR ,sizeof(HWOBJ) );
if ( !pSerObj )
return (NULL);
pSerObj->BindFlags = THREAD_IN_PDD; // PDD create thread when device is first attached.
pSerObj->dwIntID = DeviceArrayIndex; // Only it is useful when set set THREAD_AT_MDD. We use this to transfer DeviceArrayIndex
pSerObj->pFuncTbl = (HW_VTBL *) &IoVTbl; // Return pointer to appropriate functions
// Now return this structure to the MDD.
return (pSerObj);
}
--------------------------------------------------------------------------------------------------------------
//这部分位于mdd层
pSerialHead->pHWObj = GetSerialObject( DevIndex );
typedef struct __HW_INDEP_INFO {
CRITICAL_SECTION TransmitCritSec1; // @field Protects tx action
CRITICAL_SECTION ReceiveCritSec1; // @field Protects rx action
PHWOBJ pHWObj; // @field Represents PDD object.
PVOID pHWHead;
PHW_INDEP_INFO pSerialHead = NULL;
--------------------------------------------------------------------------------------------------------------
HANDLE COM_Init(ULONG Identifier)
在 COM_Init函数中,对结构体(__HW_INDEP_INFO )进行初始化,这个结构体包含,串口操作所有函数,在应用层通过句柄HANDLE得到这个结构体来操作串口.
在COM_Int中,通过GetSerialObject( DevIndex );创建结构体PHWOBJ并返回他的指针,PHWOBJ就包含了所有对硬件的操作函数,并仅仅是函数,
//关于串口的端口号:dwIntID
在GetSerialObject( DevIndex );中通过参数DevIndex 初始化dwIntID
GetSerialObject在COM_Init中被调用.
//关于各个层之间的关系.
首先com_init函数为XXindep的结构体变量分配空间,
通过函参Identifier得到打开在ACTIVE下的注册表信息(OpenDeviceKey((LPCTSTR)Identifier);),然后通过
RegQueryValueEx(hKey, L"DeviceArrayIndex", NULL, &kvaluetype,(LPBYTE)&DevIndex, &datasize) ) 得到该窗口的端口号.
然后通过调用PDDCM层的函数pSerialHead->pHWObj=GetSerialObject( DevIndex )初始化XXXHWObj结构体,这个结构体,拥有自己的串口端口号,串口操作函数,
然后通过下面2行调用pdd层的
pHWHead = pSerialHead->pHWObj->pFuncTbl->HWInit(Identifier, pSerialHead, pSerialHead->pHWObj);
pSerialHead->pHWHead = pHWHead;//pHWHead这里指向一个CSerialPDD 对象.
最后调用 (void) pSerialHead->pHWObj->pFuncTbl->HWPostInit( pHWHead );函数.