首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > WinCE >

wince 2440串口疑问,该怎么处理

2012-03-21 
wince 2440串口疑问C/C++ code最近看2440 5.0BSP的串口驱动,发现有个地方让人不可思议,搞不清楚,特向大家

wince 2440串口疑问

C/C++ code
最近看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);
}



[解决办法]
//中断绑定串口线程SerialEventHandler,这个dwIntID并不是什么中断 
//而是注册表中的DeviceArrayIndex的值why? 

他就是要这样写,你有什么办法呢?呵呵。
他只是在开始的时候用了一下dwIntID这个来传递DeviceArrayIndex这个值。
传过了,它会被置零。至于后边要不要用到它dwIntID,也是不一定的。
[解决办法]
C/C++ code
    // 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; 


[解决办法]

探讨
引用:
//中断绑定串口线程SerialEventHandler,这个dwIntID并不是什么中断
//而是注册表中的DeviceArrayIndex的值why?

他就是要这样写,你有什么办法呢?呵呵。
他只是在开始的时候用了一下dwIntID这个来传递DeviceArrayIndex这个值。
传过了,它会被置零。至于后边要不要用到它dwIntID,也是不一定的。


他就是要这样写,你有什么办法呢?
................

雷人

我再仔细看…

[解决办法]
mark下。
用线程和不用线程应该不完全是4.2和5.0的区别。只是定制BSP人员设计的一个习惯问题。我估计写我那个BSP的高手都是玩 4.2起家然后5.0都还是按照老样子写了。估计6.0会风格依旧。。。。。
我看了下我的BSP下面全是中断创建线程。。。。基本上没有看到明显说明了硬件中断的部分。
硬件中断都是再初始化的时候开启,一旦响应到中断就自己跑去创建线程了。这样跟底层的东西就透明化了。
操作上是简单了。但是理解上会比较麻烦。。个人认为。。
[解决办法]
// 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; // 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);
}

这段给你看看。看看有没有什么突破点。
[解决办法]
你扩展串口的芯片是什么16c554? 如果是的话相当写一个并行口的驱动。COM不会影响,不爽了可以改成任何三个字母。要用COM的话你注册表中制定调用的DLL也不同当然Index也要不同。
[解决办法]
探讨
顺便问下有没有人搞2440下 16c554的驱动。。。

热点排行