wince 2440串口疑问
最近看2440 5.0BSP的串口驱动,发现有个地方让人不可思议,搞不清楚,特向大家请教
————————————————————————————————————————
串口驱动的流程是Com_Init中初始化中断,并绑定线程,等待中断产生,不过这个5.0BSP的实现方法很让人郁闷,请看。
在Com_Init:
//读注册表的DeviceArrayIndex的值
if ( RegQueryValueEx(hKey, L"DeviceArrayIndex", NULL, &kvaluetype,
(LPBYTE)&DevIndex, &datasize) ) {
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("Failed to get DeviceArrayIndex value, COM_Init failed\r\n")));
RegCloseKey (hKey);
LocalFree(pSerialHead);
return(NULL);
}
// Initialize hardware dependent data.其实是获得那个串口
pSerialHead->pHWObj = GetSerialObject( DevIndex );
————————————————GetSerialObject源码————————————————————
// GetSerialObj : The purpose of this function is to allow multiple PDDs to be
// linked with a single MDD creating a multiport driver. In such a driver, the
// MDD must be able to determine the correct vtbl and associated parameters for
// each PDD. Immediately prior to calling HWInit, the MDD calls GetSerialObject
// to get the correct function pointers and parameters.
//
extern "C" PHWOBJ
GetSerialObject(
DWORD DeviceArrayIndex
)
{
PHWOBJ pSerObj;
// Unlike many other serial samples, we do not have a statically allocated
// array of HWObjs. Instead, we allocate a new HWObj for each instance
// of the driver. The MDD will always call GetSerialObj/HWInit/HWDeinit in
// that order, so we can do the alloc here and do any subsequent free in
// HWDeInit.
// Allocate space for the HWOBJ.
pSerObj=(PHWOBJ)LocalAlloc( LPTR ,sizeof(HWOBJ) );
if ( !pSerObj )
return (NULL);
// Fill in the HWObj structure that we just allocated.
pSerObj->BindFlags = THREAD_IN_PDD; // PDD create thread when device is first attached.
//——这个pSerObj->dwIntID 在线程中用到,奇怪的是怎么会是注册表DeviceArrayIndex的值呢?
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);
}
//绑定线程
if ( pSerialHead->pHWObj->BindFlags & THREAD_AT_INIT ) {
// Hook the interrupt and start the associated thread.
if ( ! StartDispatchThread( pSerialHead ) ) {
// Failed on InterruptInitialize or CreateThread. Bail.
COM_Deinit(pSerialHead);
return(NULL);
}
}
——————————————————StartDispatchThread函数源码————————————————
// ****************************************************************
//
//@doc INTERNAL
//@funcBOOL | StartDispatchThread | Start thread if requested by PDD.
//
//@parm ULONG | pSerialHead
//
// @rdescTRUE if success, FALSE if failed.
//
BOOL
StartDispatchThread(
PHW_INDEP_INFO pSerialHead
)
{
// Initialize the interrupt to be associated with the hSerialEvent
// event. GetByte waits on this event and acts as a second
// level decoder determining the type of serial event. If this return
// fails, then another process has registered for the interrupt, so
// fail the init and set the hSerialEvent to NULL.
DEBUGMSG(ZONE_INIT,
(TEXT("Initializing interrupt 0x%X, 0x%X\n\r"),
pSerialHead->pHWObj->dwIntID, pSerialHead->hSerialEvent));
//中断绑定串口线程SerialEventHandler,这个dwIntID并不是什么中断
//而是注册表中的DeviceArrayIndex的值why?
if ( !InterruptInitialize(pSerialHead->pHWObj->dwIntID,
pSerialHead->hSerialEvent,
NULL,
0) ) {
DEBUGMSG(ZONE_INIT | ZONE_ERROR,
(TEXT("Error initializing interrupt\n\r")));
return(FALSE);
}
InterruptDone(pSerialHead->pHWObj->dwIntID);
// Set up the dispatch thread and it's kill flag. Note that the thread
// fills in its own handle in pSerialHead.
pSerialHead->KillRxThread = 0;
pSerialHead->pDispatchThread = NULL;
DEBUGMSG(ZONE_INIT,
(TEXT("Spinning thread%X\n\r"), pSerialHead));
//创建启动线程函数
pSerialHead->pDispatchThread = CreateThread(NULL,0, SerialDispatchThread,
pSerialHead, 0,NULL);
if ( pSerialHead->pDispatchThread == NULL ) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("Error creating dispatch thread (%d)\n\r"),
GetLastError()));
return(FALSE);
}
DEBUGMSG (ZONE_INIT, (TEXT("Created receive thread %X\r\n"),
pSerialHead->pDispatchThread));
return(TRUE);
}
// Assigning IRQ Values IrqVal = IRQ_UART0; // in S3c2443_intr.h // Getting SysIntr value from OAL if(FALSE == KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IrqVal,sizeof(DWORD), &SysIntrVal,sizeof(DWORD), NULL)) { RETAILMSG(1,(TEXT("HwInit:Unable to retrieve SYSINTR for spi \r\n"))); LocalFree (pSpiHWHeadInfo); return (NULL); } pHWObj->dwIntID = SysIntrVal;
[解决办法]