19608|84

64

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

wince 2440串口疑问 [复制链接]

  1. 最近看2440 5.0BSP的串口驱动,发现有个地方让人不可思议,搞不清楚,特向大家请教
  2. ————————————————————————————————————————
  3. 串口驱动的流程是Com_Init中初始化中断,并绑定线程,等待中断产生,不过这个5.0BSP的实现方法很让人郁闷,请看。
  4. 在Com_Init:
  5. //读注册表的DeviceArrayIndex的值
  6. if ( RegQueryValueEx(hKey, L"DeviceArrayIndex", NULL, &kvaluetype,
  7.                          (LPBYTE)&DevIndex, &datasize) ) {
  8.         DEBUGMSG (ZONE_INIT | ZONE_ERROR,
  9.                   (TEXT("Failed to get DeviceArrayIndex value, COM_Init failed\r\n")));
  10.         RegCloseKey (hKey);
  11.         LocalFree(pSerialHead);
  12.         return(NULL);
  13.     }
  14. // Initialize hardware dependent data.其实是获得那个串口
  15.     pSerialHead->pHWObj = GetSerialObject( DevIndex );

  16. ————————————————GetSerialObject源码————————————————————


  17. // GetSerialObj : The purpose of this function is to allow multiple PDDs to be
  18. // linked with a single MDD creating a multiport driver.  In such a driver, the
  19. // MDD must be able to determine the correct vtbl and associated parameters for
  20. // each PDD.  Immediately prior to calling HWInit, the MDD calls GetSerialObject
  21. // to get the correct function pointers and parameters.
  22. //
  23. extern "C" PHWOBJ
  24. GetSerialObject(
  25.                DWORD DeviceArrayIndex
  26.                )
  27. {
  28.     PHWOBJ pSerObj;

  29.     // Unlike many other serial samples, we do not have a statically allocated
  30.     // array of HWObjs.  Instead, we allocate a new HWObj for each instance
  31.     // of the driver.  The MDD will always call GetSerialObj/HWInit/HWDeinit in
  32.     // that order, so we can do the alloc here and do any subsequent free in
  33.     // HWDeInit.
  34.     // Allocate space for the HWOBJ.
  35.     pSerObj=(PHWOBJ)LocalAlloc( LPTR ,sizeof(HWOBJ) );
  36.     if ( !pSerObj )
  37.         return (NULL);

  38.     // Fill in the HWObj structure that we just allocated.

  39.     pSerObj->BindFlags = THREAD_IN_PDD;     // PDD create thread when device is first attached.
  40.     //——这个pSerObj->dwIntID 在线程中用到,奇怪的是怎么会是注册表DeviceArrayIndex的值呢?
  41.     pSerObj->dwIntID = DeviceArrayIndex;   // Only it is useful when set set THREAD_AT_MDD. We use this to transfer DeviceArrayIndex
  42.     pSerObj->pFuncTbl = (HW_VTBL *) &IoVTbl; // Return pointer to appropriate functions

  43.     // Now return this structure to the MDD.
  44.     return (pSerObj);
  45. }


  46. //绑定线程
  47. if ( pSerialHead->pHWObj->BindFlags & THREAD_AT_INIT ) {
  48.         // Hook the interrupt and start the associated thread.
  49.         if ( ! StartDispatchThread( pSerialHead ) ) {
  50.             // Failed on InterruptInitialize or CreateThread.  Bail.
  51.             COM_Deinit(pSerialHead);
  52.             return(NULL);        
  53.         }

  54.     }

  55. ——————————————————StartDispatchThread函数源码————————————————

  56. // ****************************************************************
  57. //
  58. //        @doc INTERNAL
  59. //        @func                BOOL | StartDispatchThread | Start thread if requested by PDD.
  60. //
  61. //        @parm                 ULONG  | pSerialHead
  62. //
  63. //         @rdesc                TRUE if success, FALSE if failed.
  64. //
  65. BOOL
  66. StartDispatchThread(
  67.                    PHW_INDEP_INFO  pSerialHead
  68.                    )
  69. {
  70.     // Initialize the interrupt to be associated with the hSerialEvent
  71.     // event. GetByte waits on this event and acts as a second
  72.     // level decoder determining the type of serial event. If this return
  73.     // fails, then another process has registered for the interrupt, so
  74.     // fail the init and set the hSerialEvent to NULL.
  75.     DEBUGMSG(ZONE_INIT,
  76.              (TEXT("Initializing interrupt 0x%X, 0x%X\n\r"),
  77.               pSerialHead->pHWObj->dwIntID, pSerialHead->hSerialEvent));
  78. //中断绑定串口线程SerialEventHandler,这个dwIntID并不是什么中断
  79. //而是注册表中的DeviceArrayIndex的值why?

  80.     if ( !InterruptInitialize(pSerialHead->pHWObj->dwIntID,
  81.                               pSerialHead->hSerialEvent,
  82.                               NULL,
  83.                               0) ) {
  84.         DEBUGMSG(ZONE_INIT | ZONE_ERROR,
  85.                  (TEXT("Error initializing interrupt\n\r")));
  86.         return(FALSE);
  87.     }

  88.     InterruptDone(pSerialHead->pHWObj->dwIntID);

  89.     // Set up the dispatch thread and it's kill flag. Note that the thread
  90.     // fills in its own handle in pSerialHead.
  91.     pSerialHead->KillRxThread = 0;
  92.     pSerialHead->pDispatchThread = NULL;

  93.     DEBUGMSG(ZONE_INIT,
  94.              (TEXT("Spinning thread%X\n\r"), pSerialHead));
  95. //创建启动线程函数
  96.     pSerialHead->pDispatchThread = CreateThread(NULL,0, SerialDispatchThread,
  97.                                                 pSerialHead, 0,NULL);
  98.     if ( pSerialHead->pDispatchThread == NULL ) {
  99.         DEBUGMSG(ZONE_INIT|ZONE_ERROR,
  100.                  (TEXT("Error creating dispatch thread (%d)\n\r"),
  101.                   GetLastError()));
  102.         return(FALSE);
  103.     }

  104.     DEBUGMSG (ZONE_INIT, (TEXT("Created receive thread %X\r\n"),
  105.                           pSerialHead->pDispatchThread));     
  106.     return(TRUE);
  107. }
复制代码
此帖出自WindowsCE论坛

最新回复

茅塞顿开~~!!太短了太短了太短了太短了太短了太短了  详情 回复 发表于 2010-3-5 11:08
点赞 关注
 

回复
举报

78

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
//中断绑定串口线程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);

InterruptInitialize,InterruptDone函数都是和硬件中断相关的啊,如今怎么搞是DeviceArrayIndex的值呢?

这样有什么用啊?真是迷惑死我了。

请大家指教。
此帖出自WindowsCE论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
  1. 在2440 4.2BSP中就是使用的是硬件中断,非常干净明了

  2. // GetSerialObj : The purpose of this function is to allow multiple PDDs to be
  3. // linked with a single MDD creating a multiport driver.  In such a driver, the
  4. // MDD must be able to determine the correct vtbl and associated parameters for
  5. // each PDD.  Immediately prior to calling HWInit, the MDD calls GetSerialObject
  6. // to get the correct function pointers and parameters.
  7. //
  8. PHWOBJ
  9. GetSerialObject(DWORD DeviceArrayIndex)
  10. {
  11.         PHWOBJ pSerObj;

  12.         RETAILMSG(1,(TEXT("GetSerialObject%d\r\n"),DeviceArrayIndex));

  13.         IRDA = DeviceArrayIndex;

  14.         // Now return this structure to the MDD.
  15.         if ( DeviceArrayIndex == 0 )
  16.                 pSerObj = (PHWOBJ)(&IoObj);
  17.         else if(DeviceArrayIndex == 1)
  18.                 pSerObj = (PHWOBJ)(&IoObj2);
  19.         else if(DeviceArrayIndex == 2)
  20.                 pSerObj = (PHWOBJ)(&IoObj3);
  21.         else if(DeviceArrayIndex == 3)
  22.                 pSerObj = (PHWOBJ)(&Io16552Obj4);
  23.         else if(DeviceArrayIndex == 4)
  24.                 pSerObj = (PHWOBJ)(&Io16552Obj5);
  25.         else
  26.                 pSerObj = (PHWOBJ)(&IoObj);
  27.         return (pSerObj);
  28. }

  29. ——————————————————————————————————
  30. const HWOBJ IoObj = {
  31.         THREAD_AT_INIT,
  32.         SYSINTR_SERIAL,
  33.         (PHW_VTBL) &IoVTbl
  34. };
  35. const HWOBJ IoObj2 = {
  36.         THREAD_AT_INIT,
  37.         SYSINTR_SERIAL2,
  38.         (PHW_VTBL) &IoVTbl2
  39. };


  40. 所以搞的不明白了。InterruptInitialize,InterruptDone随便能个数组上去有什么用?

  41. 据我所知,与硬件相关的系统中断都是>=16的,DeviceArrayIndex<16莫非这个InterruptInitialize,InterruptDone还真是有这个用法?
  42. 但是这个InterruptInitialize会调用OEMInterruptEnable函数的,这个OEMInterruptEnable函数是对小于16的中断号是不予理会的,哎,真是搞什么的啊?
  43. 请大家指教了。
复制代码
此帖出自WindowsCE论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

4
 
InterruptInitialize,InterruptDone随便能个数组上去有什么用?——数
此帖出自WindowsCE论坛
 
 
 

回复

50

帖子

0

TA的资源

一粒金砂(初级)

5
 
咋没有人理我呢?正在焦急等待........
此帖出自WindowsCE论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

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

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

回复

45

帖子

0

TA的资源

一粒金砂(初级)

7
 

  1.         // Assigning  IRQ Values
  2.         IrqVal = IRQ_UART0;   // in S3c2443_intr.h
  3.         // Getting SysIntr value from OAL
  4.         if(FALSE == KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IrqVal,sizeof(DWORD), &SysIntrVal,sizeof(DWORD), NULL))
  5.                 {
  6.                         RETAILMSG(1,(TEXT("HwInit:Unable to retrieve SYSINTR for spi \r\n")));
  7.                         LocalFree (pSpiHWHeadInfo);
  8.                         return (NULL);
  9.                 }
  10.         pHWObj->dwIntID = SysIntrVal;
复制代码

不知道楼主有没有看到类似上面的代码,在GetSerialObject中的dwIntID 值,被上面的语句改变了。
此帖出自WindowsCE论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

8
 
哦,对了,我也在看com驱动,希望能向楼主学习下,有时间多交流下
此帖出自WindowsCE论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

9
 
引用 5 楼 wohuazhen 的回复:
//中断绑定串口线程SerialEventHandler,这个dwIntID并不是什么中断
//而是注册表中的DeviceArrayIndex的值why?

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


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

雷人

我再仔细看看PB帮助吧。

最近不知道为什么,只能自己解决问题,记得以前不是这样的。....

此帖出自WindowsCE论坛
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

10
 
引用 6 楼 ulovexd 的回复:
    // 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;



不知道楼主有没有看到类似上面的代码,在GetSerialObject中的dwIntID 值,被上面的语句改变了。


我的根本没有这个的,你的2443和我的2440不同的。
此帖出自WindowsCE论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

11
 
引用 8 楼 gooogleman 的回复:
引用 5 楼 wohuazhen 的回复:
//中断绑定串口线程SerialEventHandler,这个dwIntID并不是什么中断
//而是注册表中的DeviceArrayIndex的值why?

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


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

雷人

我再仔细看…


2440有官方的5.0版本吗,基本都是自己修改出来的吧。即使是官方版本,串口驱动的分层比较清晰,可能是不愿意修改原来整体结构,但是偏偏要获取具体串口端口信息,利用一个无用的成员传递一下,也是正常。不过我们编写代码一般不这么做,很容易迷惑人,宁愿把属于public的内容重写一遍。
此帖出自WindowsCE论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

12
 
关注
此帖出自WindowsCE论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

13
 
引用 10 楼 clementzhao 的回复:
2440有官方的5.0版本吗,基本都是自己修改出来的吧。即使是官方版本,串口驱动的分层比较清晰,可能是不愿意修改原来整体结构,但是偏偏要获取具体串口端口信息,利用一个无用的成员传递一下,也是正常。不过我们编写代码一般不这么做,很容易迷惑人,宁愿把属于public的内容重写一遍。


是官方的,三星够狠的,都弄得差不多了。不过人员足够的话,是有必要花时间重写这些代码的,有些东西明显写的不合理。

clementzhao 老兄,招聘到人了吧。你们做芯片的很有挑战性啊,自己做BSP很能锻炼人。

4.2BSP串口写的不好,但是如果外扩串口驱动的话容易移植,
5.0BSP写的比较好,

4.2BSP和5.0BSP的串口有较大差别,一是刚才的中断。另外一个是4.2的只在MDD有线程,
但是5.0BSP在PDD有线程。
我再好好看一下,把这个MDD的代码全部放到BSP来进行弄弄。这样就好办了。
此帖出自WindowsCE论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

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

回复

81

帖子

0

TA的资源

一粒金砂(初级)

15
 
引用 12 楼 gooogleman 的回复:
引用 10 楼 clementzhao 的回复:
2440有官方的5.0版本吗,基本都是自己修改出来的吧。即使是官方版本,串口驱动的分层比较清晰,可能是不愿意修改原来整体结构,但是偏偏要获取具体串口端口信息,利用一个无用的成员传递一下,也是正常。不过我们编写代码一般不这么做,很容易迷惑人,宁愿把属于public的内容重写一遍。

是官方的,三星够狠的,都弄得差不多了。不过人员足够的话,是有必要花时间重写这些代码的,有些东西明…


还没这么快,不过有几个有意向的。
ce的驱动很多都是外包公司代写,不一定写的好。现在看来imx21写的不错,大部分比24x0的好多了,你可以参考一下。
此帖出自WindowsCE论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

16
 
  1. 折腾了几下,发现有点明了了。

  2. ——————————在PDD有个串口产生的线程,作用是获得具体的中断类型,比如,发送中断还是接收中断等。
  3. 然后通知给MDD层。
  4. DWORD CPdd2440Uart::ThreadRun()
  5. {
  6.     while ( m_hISTEvent!=NULL && !IsTerminated()) {
  7.         if (WaitForSingleObject( m_hISTEvent,m_dwISTTimeout)==WAIT_OBJECT_0) {
  8.             m_HardwareLock.Lock();   
  9.             while (!IsTerminated() ) {
  10.                 DWORD dwData = (GetInterruptStatus() & (S2440UART_INT_RXD|S2440UART_INT_TXD|S2440UART_INT_ERR));
  11.                 DWORD dwMask = (GetIntrruptMask() & (S2440UART_INT_RXD|S2440UART_INT_TXD|S2440UART_INT_ERR));
  12.                  DEBUGMSG(ZONE_THREAD,
  13.                       (TEXT(" CPdd2440Uart::ThreadRun INT=%x, MASK =%x\r\n"),dwData,dwMask));
  14.                 dwMask &= dwData;
  15.                 if (dwMask) {
  16.                     DEBUGMSG(ZONE_THREAD,
  17.                       (TEXT(" CPdd2440Uart::ThreadRun Active INT=%x\r\n"),dwMask));
  18.                     DWORD interrupts=INTR_MODEM; // Always check Modem when we have change. It may work at polling mode.
  19.                     if ((dwMask & S2440UART_INT_RXD)!=0)
  20.                         interrupts |= INTR_RX;
  21.                     if ((dwMask & S2440UART_INT_TXD)!=0)
  22.                         interrupts |= INTR_TX;
  23.                     if ((dwMask & S2440UART_INT_ERR)!=0)
  24.                         interrupts |= INTR_LINE|INTR_RX;
  25.                     NotifyPDDInterrupt((INTERRUPT_TYPE)interrupts);
  26.                     ClearInterrupt(dwData);
  27.                 }
  28.                 else
  29.                     break;
  30.             }
  31.             m_HardwareLock.Unlock();   
  32.             InterruptDone(m_dwSysIntr);
  33.         }
  34.         else { // Polling Modem.
  35.             NotifyPDDInterrupt(INTR_MODEM);
  36.             DEBUGMSG(ZONE_THREAD,(TEXT(" CPdd2440Uart::ThreadRun timeout INT=%x,MASK=%d\r\n"),m_pINTregs->SUBSRCPND,m_pINTregs->INTSUBMSK));
  37. #ifdef DEBUG
  38.             if ( ZONE_THREAD )
  39.                 m_pReg2440Uart->DumpRegister();
  40. #endif
  41.         }
  42.     }
  43.     return 1;
  44. }
复制代码


——————————————————————————————————————
我觉得上面的DeviceArrayIndex当作中断来初始化是故意为之,及时初始化失败,还是产生了一个线程。不过这样总感觉不是很好。
等下打印出信息来看看有什么效果。
此帖出自WindowsCE论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

17
 
管它好不好,能用就好。
真的觉得不好,你自己写一个也可以啊。
此帖出自WindowsCE论坛
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

18
 
会有这种感觉才是wince的特点。
此帖出自WindowsCE论坛
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

19
 
引用 17 楼 wohuazhen 的回复:
会有这种感觉才是wince的特点。


是三星没有处理好。BSP的一些架构定了。我估计他们也是不得已而为之
此帖出自WindowsCE论坛
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

20
 
// 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);
}

这段给你看看。看看有没有什么突破点。
此帖出自WindowsCE论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表