【请教wince中UART驱动问题!急!!!】

hbwzh   2009-8-5 11:46 楼主
环境:S3C2440 + WinCE5.0

实现:目前开发板上有3个串口,都使用系统的分层驱动。
      因为某些需求上的原因,现在想把UART1独立出来,不使用系统的分层驱动,自己按照流驱动形式写了个UART1的驱动。

问题:
(1)动态加载写的UART流驱动后,从PC机连续发送数据,发现,能响应IRQ_UART1中断,但无法进入自己写的IST中处理。是否被原系统的UART1驱动拦截了?
(2)出现上面问题后,我在注册表platform.reg中注释了关于UART1的部分,重新编译NK,这次发现IRQ_UART1中断都无法响应,这是怎么回事?是不是还要更改什么地方?

请大侠们指点指点。

回复评论 (16)

如果你觉得被原系统的串口1拦截了。你可以在原系统的串口中加打印看看waitforsingle这个地方是否来了中断
你应该先看看你的数据室不是从你想要的那个串口发出去的。你的串口驱动有没有加载。。。。等等

为什么不是用微软的驱动呢。。只用改PDD就可以了。可能串口控制器这个地方需要注意点
点赞  2009-8-5 12:01
多谢!
因为是初学WinCE,有一个功能要对串口接收的数据实时处理,看了微软的UART驱动,好庞大,时间很紧,就想到用流驱动来实现了,但现在问题多多啊。看来还是得花时间在代码上才行。
点赞  2009-8-5 14:17
把你写的驱动的中断注册部分贴出来看看
点赞  2009-8-5 16:56

5楼 DSZ 

其它不用的串口中断有没有屏蔽?只看PDD驱动也不是很庞大,关键要懂的其结构
点赞  2009-8-5 17:56
主要功能是为了实现与外部设备串口的通信,并对约定好的协议进行实时接收处理。但是外部设备的串口有点特殊,是只用一根线进行发送和接受数据,类似:

-------------  TxD1
            |--------              |------------
S3C2440     |  RxD1 |--------------|  外部设备
            |--------              |------------
-------------

所以在S3C2440这边,发送时就得把 RxD1 关闭,接收时就得把TxD1关闭

按照大侠们的意见,有点想改PDD这部分代码,但是不知是不是在这里修改:

  1. ULONG CPdd2440Uart::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen)
  2. {
  3.     DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("+CPdd2440Uart::ReceiveInterruptHandler
  4.              pRxBuffer=%x,*pBufflen=%x\r\n"),pRxBuffer,pBufflen!=NULL?*pBufflen:0));
  5.    
  6.     DWORD dwBytesDropped = 0;

  7.     if (pRxBuffer && pBufflen )
  8.     {
  9.         DWORD dwBytesStored = 0 ;
  10.         DWORD dwRoomLeft = *pBufflen;
  11.         m_bReceivedCanceled = FALSE;
  12.         m_HardwareLock.Lock();
  13.         
  14.         while (dwRoomLeft && !m_bReceivedCanceled)
  15.         {
  16.             ULONG ulUFSTATE = m_pReg2440Uart->Read_UFSTAT();

  17.             DWORD dwNumRxInFifo = (ulUFSTATE & (0x3f<<0));

  18.             if ((ulUFSTATE & (1<<6))!=0) // Overflow. Use FIFO depth (16);
  19.                 dwNumRxInFifo = SER2440_FIFO_DEPTH_RX;

  20.             DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT
  21.                        ("CPdd2440Uart::ReceiveInterruptHandler ulUFSTATE=%x,
  22.                         UTRSTAT=%x, dwNumRxInFifo=%X\r\n"),ulUFSTATE,
  23.                         m_pReg2440Uart->Read_UTRSTAT(), dwNumRxInFifo));

  24.             if (dwNumRxInFifo)
  25.             {
  26.                 ASSERT((m_pReg2440Uart->Read_UTRSTAT () & (1<<0))!=0);

  27.                 while (dwNumRxInFifo && dwRoomLeft)
  28.                 {
  29.                     UCHAR uLineStatus = GetLineStatus();
  30.                     UCHAR uData = m_pReg2440Uart->Read_URXH();

  31.                     if(DataReplaced(&uData,(uLineStatus&UERSTATE_PARITY_ERROR)!=0))
  32.                     {
  33.                         [color=#FF0000]*pRxBuffer++ = uData;
  34.                         dwRoomLeft--;
  35.                         dwBytesStored++; [/color]                  
  36.                     }
  37.                     dwNumRxInFifo --;
  38.                 }
  39.             }
  40.             else
  41.                 break;
  42.         }
  43.         if (m_bReceivedCanceled)
  44.             dwBytesStored = 0;
  45.         
  46.         m_HardwareLock.Unlock();
  47.         *pBufflen = dwBytesStored;
  48.     }
  49.     else
  50.     {
  51.         ASSERT(FALSE);
  52.     }

  53.     DEBUGMSG(ZONE_THREAD|ZONE_READ,(TEXT("-CPdd2440Uart::ReceiveInterruptHandler
  54.               pRxBuffer=%x,*pBufflen=%x,dwBytesDropped=%x\r\n"),
  55.               pRxBuffer,pBufflen!=NULL?*pBufflen:0,dwBytesDropped));

  56.     return dwBytesDropped;
  57. }



在红色字体那里增加数据协议分析及保存到缓存区的操作吗?这是3个串口共用的程序,如何判断是UART1的呢?如何把接收到的数据发送给MDD层呢,pRxBuffer吗?

多谢各位大侠指点!!!!
点赞  2009-8-6 01:04
if(DataReplaced(&uData,(uLineStatus&UERSTATE_PARITY_ERROR)!=0))
{

    *pRxBuffer++ = uData;
    dwRoomLeft--;
    dwBytesStored++;
                  
}
字体颜色怎么没变呢
点赞  2009-8-6 01:11
帮顶一个吧,很久没有做过UART了
点赞  2009-8-6 07:55
如果你非要独立串口驱动的话,可以有一个笨方法:复制一份原来的驱动和注册表,根据需要的是哪个串口,修改对应的注册表以及删除原来驱动对应串口的PDD部分
点赞  2009-8-6 08:13
多谢大家的指点!!!

删除原来驱动对应串口的PDD部分?面向硬件不就是在PDD部分操作么,为什么还要删除PDD部分呢?
点赞  2009-8-6 08:51
楼主到底是想独立驱动还是共用驱动

我看着这代码是共用的pdd吧?

CPdd2440Uart应该有寄存器地址的member吧,可以用它区分哪个串口
点赞  2009-8-6 10:39
我想还是在共用驱动上更改,在PDD部分更改,只是不知道在哪部分更改

是在

  1. ULONG CPdd2440Uart::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen)
  2. {
  3.      .......

  4.      if(DataReplaced(&uData,(uLineStatus&UERSTATE_PARITY_ERROR)!=0))
  5.     {
  6.         *pRxBuffer++ = uData;
  7.         dwRoomLeft--;
  8.         dwBytesStored++;            
  9.     }

  10.     ......


这部分增加数据协议分析及保存到缓存区的操作吗?如何把接收到的数据发送给MDD层呢,pRxBuffer吗?

多谢各位大侠的指点!!!!
点赞  2009-8-6 11:11
这里可以肯定是可以做的

把uData放到一个你自己开的缓冲里,数据足够之后解析
然后把结果放到pRxBuffer里

不过感觉这样写很shit
点赞  2009-8-6 11:41
初学CE,很多东西还不是很清楚,不知道大侠有更好的方法没有。
我先试试这个很shit的方法,时间紧,只能先实现再说了

多谢!
点赞  2009-8-6 14:26
uping
点赞  2009-8-6 14:55
引用: 引用 9 楼 y2dg4lf 的回复:
多谢大家的指点!!!

删除原来驱动对应串口的PDD部分?面向硬件不就是在PDD部分操作么,为什么还要删除PDD部分呢?

删除原来PDD部分你想要分离出来的那个串口号
点赞  2009-8-8 11:18
最近杂事太多,效率也低,问题现在还没完全解决

独立出一个串口,复制了一份原来的驱动和注册表
因为COM2得TxD和RxD连在了一起,与外部设备通信时,就得发送时屏蔽接收,接收时屏蔽发送,所以我做了如下修改:

  1. void CPdd2440Uart::XmitInterruptHandler(PUCHAR pTxBuffer, ULONG *pBuffLen)
  2. {
  3.     PREFAST_DEBUGCHK(pBuffLen!=NULL);
  4.     m_HardwareLock.Lock();   
  5.     if (*pBuffLen == 0)
  6.     {
  7.         EnableXmitInterrupt(FALSE);
  8.     }
  9.     else
  10.     {
  11.         DEBUGCHK(pTxBuffer);
  12.         PulseEvent(m_XmitFlushDone);
  13.         DWORD dwDataAvaiable = *pBuffLen;
  14.         *pBuffLen = 0;

  15.         Rx_Pause(TRUE);
  16.         if((m_DCB.fOutxCtsFlow &&IsCTSOff())||(m_DCB.fOutxDsrFlow && IsDSROff()))
  17.         { // We are in flow off
  18.             DEBUGMSG(ZONE_THREAD|ZONE_WRITE,(TEXT("CPdd16550::XmitInterruptHandler!
  19.                      Flow Off, Data Discard.\r\n")));
  20.             EnableXmitInterrupt(FALSE);
  21.         }
  22.         else  
  23.         {
  24.             DWORD dwWriteSize = GetWriteableSize();
  25.             DEBUGMSG(ZONE_THREAD|ZONE_WRITE,(TEXT("CPdd16550::XmitInterruptHandler!
  26.                      WriteableSize=%x to FIFO,dwDataAvaiable=%x\r\n"),  
  27.                      dwWriteSize,dwDataAvaiable));
  28.             [color=#FF0000]
  29.             g_ps3c2440IOPRegs->GPHCON &= 0x3ff3ff;   // Close RxD1
  30.                                
  31.             g_ps3c2440IOPRegs->GPHCON &= 0x3ffcff;   // Open  TxD1
  32.             g_ps3c2440IOPRegs->GPHCON |= 0x000200;

  33.             g_ps3c2440IOPRegs->GPHUP  &= 0xfef;
  34.             [/color]
  35.             for (DWORD dwByteWrite=0; dwByteWrite
  36.             {
  37.                 m_pReg2440Uart->Write_UTXH(*pTxBuffer);
  38.                 CardTraBuffer[CardTraBuffIndex++] = *pTxBuffer;
  39.                 pTxBuffer ++;
  40.                 dwDataAvaiable--;
  41.             }
  42.                        
  43.             RETAILMSG(1, (TEXT("dwByteWrite = %d\r\n"), dwByteWrite));
  44.        
  45.             DEBUGMSG(ZONE_THREAD|ZONE_WRITE,(TEXT("CPdd16550::XmitInterruptHandler! Write %d byte to FIFO\r\n"),dwByteWrite));
  46.             *pBuffLen = dwByteWrite;
  47.             EnableXmitInterrupt(TRUE);
  48.         }
  49.         ClearInterrupt(S2440UART_INT_TXD);
  50.         [color=#FF0000]
  51.         RETAILMSG(1, (TEXT("ClearInterrupt(S2440UART_INT_TXD)\r\n")));
  52.         g_ps3c2440IOPRegs->GPHCON &= 0x3ffcff;   // Close TxD1

  53.         g_ps3c2440IOPRegs->GPHCON &= 0x3ff3ff;   // Open RxD1
  54.         g_ps3c2440IOPRegs->GPHCON |= 0x000800;

  55.         g_ps3c2440IOPRegs->GPHUP  &= 0xfdf;
  56.         [/color]
  57.         if (m_pReg2440Uart->Read_ULCON() & (0x1<<6))
  58.             while( (m_pReg2440Uart->Read_UFSTAT() >> 0x8 ) & 0x3f );
  59.         Rx_Pause(FALSE);
  60.     }
  61.     m_HardwareLock.Unlock();
  62. }



增加了红色部分的内容,数据发送正常,但是发现接收时数据有时能收到有时收不到,请大侠们指教指教。
点赞  2009-8-13 01:49
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复