6679|27

67

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请帮我分析一下这个异常产生的原因 [复制链接]

经过昨天的努力,终于把串口的MDD层代码移植到BSP下了,并且调试成功了2440的三个自带串口的驱动。但是不知道怎么回事,两个外部扩展串口却不行,在加载驱动的时候产生异常。
在SL_Initq函数出现了问题。
SL_Initq, 0x9BA5A0
pRegBase, 0x0
pHWHead->pIER  = 1
pHWHead->pIIR_FCR  = 2
pHWHead->pLCR  = 3
pHWHead->pMCR  = 4
pHWHead->pLSR  = 5
pHWHead->pMSR  = 6
pHWHead->pIER  = 7
pBaudTable != NULL  0x98B2BBF0
Data Abort Test@@@@@@-before OUTB(pHWHead, pIER, 0x0f);
Data Abort: Thread=98b2bbf0 Proc=81d46340 'device.exe'
AKY=00001005 PC=03d723bc(ceddk.dll+0x000023bc) RA=01e29f34(wogoser2440.dll+0x00009f34) BVA=06000001 FSR=00000007
RaiseException: Thread=98b2bbf0 Proc=81d46340 'device.exe'
AKY=00001005 PC=03f8dfec(coredll.dll+0x0001dfec) RA=802135e8(NK.EXE+0x000135e8) BVA=00000001 FSR=00000001

经过串口信息+map文件查看,发现代码是在OUTB(pHWHead, pIER, 0x0f);这句发生了异常
OUTB(pHWHead, pIER, 0x0f);原型是
#define OUTB(pInfo, reg, value) (WRITE_PORT_UCHAR((UCHAR *)((pInfo)->reg), (unsigned char)(value)))
WRITE_PORT_UCHAR是属于CEDDK.DLL的
NTKERNELAPI
VOID
WRITE_PORT_UCHAR(
    PUCHAR  Port,
    UCHAR   Value
    );

说明刚开始我以为是pHWHead这个指针出现了问题,但是我发现不是,因为在前面已经使用了它,并没有发生异常。
关于pHWHead是这样定义的:PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

在map文件中,直接指明(WRITE_PORT_UCHAR((UCHAR *)((pInfo)->reg), (unsigned char)(value)))出问题。

现在我怎么也想不通是什么造成的。因为这个串口代码本来是在4.2BSP下运行的,现在我只是修改了中断相关代码而已。怎么放到5.0BSP就产生异常对了呢?以前大学都是调试单片机,代码比较简单,对这个异常几乎没有什么经验处理。请大家帮忙分析一下,谢谢。

最新回复

嘿嘿,以前我真菜鸟。  详情 回复 发表于 2009-11-4 08:57
点赞 关注

回复
举报

75

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
没有正确使用WRITE_PORT_UCHAR( )这个函数?有没进行参数检查?最好调此函数前进行参数检查,无效指针就不要传了,直接返回。我一次就是因为无效指针引起异常的。
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
如果是无效指针的话,那么这个
pHWHead->pIER  = 1
pHWHead->pIIR_FCR  = 2
pHWHead->pLCR  = 3
pHWHead->pMCR  = 4
pHWHead->pLSR  = 5
pHWHead->pMSR  = 6
pHWHead->pIER  = 7

赋值操作就会引起异常了。但是它在这里没有产生异常。

真是郁闷死我了,我把微软的16550的例子拿来对比,这个指针使用基本一致。

并且我这个代码在4.2下运行是好好的,从来没有异常过。现在异常导致加载DLL失败了。我并没有改动一句代码就这样了,让我感到不解。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

4
 
如果是无效指针的话,那么这个
pHWHead->pIER  = 1
pHWHead->pIIR_FCR  = 2
pHWHead->pLCR  = 3
pHWHead->pMCR  = 4
pHWHead->pLSR  = 5
pHWHead->pMSR  = 6
pHWHead->pIER  = 7

赋值操作就会引起异常了。但是它在这里没有产生异常。

真是郁闷死我了,我把微软的16550的例子拿来对比,这个指针使用基本一致。

并且我这个代码在4.2下运行是好好的,从来没有异常过。现在异常导致加载DLL失败了。我并没有改动一句代码就这样了,让我感到不解。
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

5
 
加个判断好了,是野指针就打消息到串口
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

6
 
引用 4 楼 xqhrs232 的回复:
加个判断好了,是野指针就打消息到串口


怎么判断?



  1. //=========================================================================
  2. //串口初始化
  3. VOID
  4. SL_Initq(
  5.        PVOID   pHead, // @parm points to device head
  6.        PUCHAR  pRegBase, // Pointer to 16550 register base
  7.        UINT8   RegStride, // Stride amongst the 16550 registers
  8.        EVENT_FUNC EventCallback, // This callback exists in MDD
  9.        PVOID   pMddHead,   // This is the first parm to callback
  10.        PLOOKUP_TBL   pBaudTable  // BaudRate Table
  11.        )
  12. {
  13.     PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;
  14.         //pSerObj=(PHWOBJ)LocalAlloc( LPTR ,sizeof(HWOBJ) );
  15.         //if ( !pSerObj )
  16.         //        return (NULL);

  17.         //pHWHead=(PSER16550_INFO)LocalAlloc( LPTR ,sizeof(SER16550_INFO) );
  18.         RETAILMSG(QYDEBUG,(TEXT("#include ser16550.h\r\n")));
  19.         //if ( !pHWHead )
  20.         //        return (NULL);
  21.        
  22.     RETAILMSG(QYDEBUG,(TEXT("+SL_Initq@@@@gooogleman, 0x%X\r\n"), pHWHead));
  23.     RETAILMSG(QYDEBUG,(TEXT("+SL_Initq, 0x%X\r\n"), pHead));
  24.         RETAILMSG(1,(TEXT("pRegBase, 0x%X\r\n"), pRegBase));

  25.     // Set up pointers to 16550 registers
  26.     pHWHead->pData    = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
  27.     pHWHead->pIER     = pRegBase + (RegStride * INTERRUPT_ENABLE_REGISTER);
  28.     pHWHead->pIIR_FCR = pRegBase + (RegStride * INTERRUPT_IDENT_REGISTER);
  29.     pHWHead->pLCR     = pRegBase + (RegStride * LINE_CONTROL_REGISTER);
  30.     pHWHead->pMCR     = pRegBase + (RegStride * MODEM_CONTROL_REGISTER);
  31.     pHWHead->pLSR     = pRegBase + (RegStride * LINE_STATUS_REGISTER);
  32.     pHWHead->pMSR     = pRegBase + (RegStride * MODEM_STATUS_REGISTER);
  33.     pHWHead->pScratch = pRegBase + (RegStride * SCRATCH_REGISTER);
  34.        
  35.         //        if (!SerMapRegisterAddresses3())
  36. //RETAILMSG( ,(TEXT("+SL_Initq, 0x%X\r\n"), pHead));
  37.                
  38.         RETAILMSG(QYDEBUG,(TEXT("pHWHead->pIER  = %X\r\n"),pHWHead->pIER ));
  39.         RETAILMSG(QYDEBUG,(TEXT("pHWHead->pIIR_FCR  = %X\r\n"),pHWHead->pIIR_FCR ));
  40.         RETAILMSG(QYDEBUG,(TEXT("pHWHead->pLCR  = %X\r\n"),pHWHead->pLCR ));
  41.         RETAILMSG(QYDEBUG,(TEXT("pHWHead->pMCR  = %X\r\n"),pHWHead->pMCR ));
  42.         RETAILMSG(QYDEBUG,(TEXT("pHWHead->pLSR  = %X\r\n"),pHWHead->pLSR  ));
  43.         RETAILMSG(QYDEBUG,(TEXT("pHWHead->pMSR  = %X\r\n"), pHWHead->pMSR ));
  44.         RETAILMSG(QYDEBUG,(TEXT("pHWHead->pIER  = %X\r\n"),pHWHead->pScratch ));
  45.        

  46.     // Store info for callback function
  47.     pHWHead->EventCallback = EventCallback;
  48.     pHWHead->pMddHead = pMddHead;

  49.     // Now set up remaining fields
  50.     if ( pBaudTable != NULL ){
  51.         pHWHead->pBaudTable = (LOOKUP_TBL *) pBaudTable;
  52.                 RETAILMSG(QYDEBUG,(TEXT("pBaudTable != NULL  0x%X\r\n")));
  53.             }
  54.     else
  55.         pHWHead->pBaudTable = (LOOKUP_TBL *) &SER_BaudTable;
  56.         pHWHead->FlushDone   = CreateEvent(0, FALSE, FALSE, NULL);

  57.     pHWHead->OpenCount = 0;
  58.     //RETAILMSG(QYDEBUG,(TEXT("OpenCount  0x%X\r\n")));


  59.         //OUTB(pHWHead, pIER, (UCHAR)2);
  60.         //RETAILMSG(QYDEBUG,(TEXT("pIER=  0x%X\r\n"),INB(pHWHead,pIER)));
  61.         RETAILMSG(QYDEBUG,(TEXT("Data Abort Test@@@@@@-before OUTB(pHWHead, pIER, 0x0f);\r\n")));

  62.         OUTB(pHWHead, pIER, (UCHAR)0x0f);

  63.         RETAILMSG(QYDEBUG,(TEXT("Data Abort Test@@@@@@\r\n")));
  64.        
  65.        
  66.     // Don't allow any interrupts till PostInit.
  67.     OUTB(pHWHead, pIER, (UCHAR)0);

  68.         OUTB(pHWHead, pIER, (UCHAR)IER_NORMAL_INTS);
  69.         RETAILMSG(QYDEBUG,(TEXT("pIER  0x%X\r\n"),INB(pHWHead, pIER)));

  70.     OUTB(pHWHead, pMCR, 0x0b);
  71.     RETAILMSG(QYDEBUG,(TEXT("pIER  0x%X\r\n"),INB(pHWHead, pIER)));


  72.     InitializeCriticalSection(&(pHWHead->TransmitCritSec));
  73.     InitializeCriticalSection(&(pHWHead->RegCritSec));
  74.     // Clear any interrupts which may be pending.  Normally only
  75.     // happens if we were warm reset.
  76.     ClearPendingIntsq( pHWHead );
  77.     RETAILMSG(QYDEBUG,(TEXT("-SL_INITq, 0x%d\r\n"), pHWHead));
  78. }
复制代码
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

7
 
if(xxx==NULL)

    RETAILMSG(  )
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

8
 
引用 6 楼 xqhrs232 的回复:
if(xxx==NULL)

    RETAILMSG(  )


这个只是判断是否是空指针。空指针和野指针是不同的。

我刚才Google了一下,他们说野指针很难判断的。只能靠经验。

现在奇怪的是pHWHead->pData    = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
这样不产生异常,使用
OUTB(pHWHead, pIER, (UCHAR)0x0f);
OUTB(pHWHead, pIER, (UCHAR)0);

等就异常了。让人迷惑不解。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

9
 
加下面进去
if(pHWHead==NULL)
            RETAILMSG(QYDEBUG,(TEXT("pHWHead==NULL@@@@@@@@@@\r\n")));

没有打印出来,说明不是这个问题,如果这个if(pHWHead==NULL)成立,那么前面pHWHead->pData    = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
早就产生异常了。

这个问题的确比较郁闷,不是指针没有分配空间的问题。
           
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

10
 
  1. //
  2. // @doc HWINTERNAL
  3. // @struct LS_SERIAL_INFO | Passed to serial lib routines.
  4. //
  5.    
  6.     typedef struct __LS_SERIAL_INFO
  7.     {
  8.          // Store volatile pointers to each 16550 register
  9.         volatile PUCHAR pData;           // @field RX data / Transmit Holding Reg
  10.         volatile PUCHAR pIER;            // @field Interrupt Enable
  11.         volatile PUCHAR pIIR_FCR;        // @field read IIR (Int ID) / Write FCR (FIFO Ctrl)
  12.         volatile PUCHAR pLCR;            // @field Line Control
  13.         volatile PUCHAR pMCR;            // @field Modem Control
  14.         volatile PUCHAR pLSR;            // @field Line Status
  15.         volatile PUCHAR pMSR;            // @field Modem Status
  16.         volatile PUCHAR pScratch;        // @field Scratch Register

  17.          // And we keep shadows of many of the 16550 registers
  18.         UCHAR                FCR;                        // @field FIFO control state.
  19.         UCHAR                IIR;                        // @field State of Interrupt Identification Register.
  20.         UCHAR                LSR;                        // @field Line Status Register.
  21.         UCHAR                MSR;                        // @field Modem Status Register.
  22.          // We wouldn't normally shadow these, except for power on/off
  23.         UCHAR                IER;                        // @field Interrupt Enable Register.
  24.         UCHAR                LCR;                        // @field Line Control Register.
  25.         UCHAR                MCR;                        // @field Modem Control Register.
  26.         UCHAR                Scratch;                // @field Scratch Register.
  27.         
  28.          // We have an event callback into the MDD
  29.         EVENT_FUNC EventCallback; // This callback exists in MDD
  30.         PVOID        pMddHead;  // This is the first parm to callback
  31.         
  32.          // Keep a copy of DCB since we rely on may of its parms
  33.         DCB         dcb;        // @field Device Control Block (copy of DCB in MDD)
  34.          // And the same thing applies for CommTimeouts
  35.         COMMTIMEOUTS CommTimeouts;  // @field Copy of CommTimeouts structure
  36.         
  37.          // Misc fields used by ser16550 library
  38.         ULONG                OpenCount;            // @field Count of simultaneous opens.
  39.         PLOOKUP_TBL pBaudTable;     // @field Pointer to Baud Table
  40.         ULONG                DroppedBytes;        // @field Number of dropped bytes
  41.         HANDLE                FlushDone;                // @field Handle to flush done event.
  42.         BOOL                CTSFlowOff;                // @field Flag - CTS flow control state.
  43.         BOOL                DSRFlowOff;                // @field Flag - DSR flow control state.
  44.                 BOOL                AddTXIntr;                // @field Flag - Fake a TX intr.
  45.         COMSTAT                Status;                 // @field Bitfield representing Win32 comm status.
  46.         ULONG                CommErrors;                // @field Bitfield representing Win32 comm error status.
  47.         ULONG                ModemStatus;        // @field Bitfield representing Win32 modem status.
  48.         CRITICAL_SECTION        TransmitCritSec; // @field Protects UART Registers for non-atomic accesses
  49.         CRITICAL_SECTION        RegCritSec; // @field Protects UART
  50.         ULONG                ChipID;                        // @field Chip identifier (CHIP_ID_16550 or CHIP_ID_16450)        
  51.         BOOL                PowerDown;      // did we power down the chip
  52.         BOOL                bSuspendResume; // Indicate Suspend/Resume happens
  53.         //
  54.         // now hardware specific fields Duplicated Info
  55.         DWORD       dwIrq;          // IRQ field
  56.         DWORD       dwSysIntr;       // @field System Interrupt number for this peripheral
  57.         PVOID       pVirtualStaticAddr;// Static Address.
  58.         WCHAR       RegIsrDll[DEVDLL_LEN];// ISR Dll name.
  59.         WCHAR       RegIsrHandler[DEVENTRY_LEN];//ISR Handle Name.

  60.         volatile ISR16550_INFO * pIsrInfoVirt;
  61.         volatile XmitDataBuffer    * pXmitBuffer;
  62.         volatile RcvDataBuffer     * pReceiveBuffer;
  63.         HANDLE          hIsrHandler;
  64.         BOOL            bMoreXmitData;// For software xmit buffering
  65.         DWORD           dwIsrIndex; // For test only
  66.     } SER16550_INFO, *PSER16550_INFO;
复制代码
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

11
 
郁闷,再次查看微软的16550驱动,写法基本一致。

我怀疑是不是我以前 build and sysgen过,把OUTB使用到的库CEDDK.lib给搞坏了?

明天重装系统吧。哎
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

12
 
把串口的MDD层代码移植到BSP,这个想法不错。同一个驱动,放两个地方。不说别的,查看都麻烦!
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 11 楼 wjf_zjut 的回复:
把串口的MDD层代码移植到BSP,这个想法不错。同一个驱动,放两个地方。不说别的,查看都麻烦!


这样是为了好修改,并且安全,一个MDD可能和N个PDD配对的。


一个小问题居然导致这样,真是遇到麻烦了。以前都是看的多,现在实战起来束手无策。
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

14
 
发现一些原因了。


这个串口驱动还真不简单啊。

这个造成异常的原因是pHWHead指向了不合法的地址,请看如下打印信息。

pRegBase, 0x0
pHWHead->pIER  = 1
pHWHead->pIIR_FCR  = 2
pHWHead->pLCR  = 3
pHWHead->pMCR  = 4
pHWHead->pLSR  = 5
pHWHead->pMSR  = 6
pHWHead->pIER  = 7

在代码中有
// Set up pointers to 16550 registers
    pHWHead->pData    = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
    pHWHead->pIER     = pRegBase + (RegStride * INTERRUPT_ENABLE_REGISTER);
    pHWHead->pIIR_FCR = pRegBase + (RegStride * INTERRUPT_IDENT_REGISTER);
    pHWHead->pLCR     = pRegBase + (RegStride * LINE_CONTROL_REGISTER);
    pHWHead->pMCR     = pRegBase + (RegStride * MODEM_CONTROL_REGISTER);
    pHWHead->pLSR     = pRegBase + (RegStride * LINE_STATUS_REGISTER);
    pHWHead->pMSR     = pRegBase + (RegStride * MODEM_STATUS_REGISTER);
    pHWHead->pScratch = pRegBase + (RegStride * SCRATCH_REGISTER);

右侧就是外部串口在wince系统中的虚拟地址,但是非常遗憾,这个pRegBase 居然等于零。

这样右侧的地址就会非常的小,在这时候wince通过这个地址去访问,不再wince的内存映射表的虚拟地址范围就出现了异常。

怎么这个pRegBase 会是0呢?怎么搞的?看看2440的自带串口会是什么东西。


 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

15
 
看不明白阿
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

16
 
郁闷,2440的自带串口却是另外一套的。

pHWHead->s2440SerReg = (S2440_UART_REG *)v_pUART2regs;
                        pRegBase = (PUCHAR)pHWHead->s2440SerReg;

我觉得极有可能是这个问题了,明天再试试吧。这个驱动问题真是防不胜防——多谢各位支持。       
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

17
 
支持
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(高级)

18
 
支持……
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

19
 
经过两小时的代码改造。异常消失了。这个异常果然是是访问了非虚拟地址造成的。

不过现在郁闷,估计中断错乱,这个wince加载到这个外部串口五的时候,重启了,哈哈有趣,估计刚好和POWEBUTTON的驱动撞上了。
哈哈,感觉离成功越来越近。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

20
 
引用 18 楼 gooogleman 的回复:
经过两小时的代码改造。异常消失了。这个异常果然是是访问了非虚拟地址造成的。

不过现在郁闷,估计中断错乱,这个wince加载到这个外部串口五的时候,重启了,哈哈有趣,估计刚好和POWEBUTTON的驱动撞上了。
哈哈,感觉离成功越来越近。

  1. //------------------------------------------------------------------------------
  2. // 果然,这个EINT2在这里被初始化了,正好碰到了。哈哈,也许等下修改一下全部外部串口都好了。哦悦。
  3. //  Function:  BSPIntrInit
  4. //
  5. BOOL BSPIntrInit()
  6. {
  7.     S3C2440A_IOPORT_REG *pOalPortRegs;
  8.     S3C2440A_INTR_REG *pIntrRegs;
  9.     ULONG value;
  10.     UINT32 sysIntr, irq;


  11.     OALMSG(OAL_INTR&&OAL_FUNC, (L"+BSPIntrInit\r\n"));
  12.    
  13.     // Then get virtual address for IO port
  14.     pOalPortRegs = OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);

  15.         // EINT2(softreset) Interrupt service is available
  16.         value = INREG32(&pOalPortRegs->GPFCON);
  17.         OUTREG32(&pOalPortRegs->GPFCON, (value & ~(3 << 4))|(2 << 4));                /* Set EINT2(GPF2) as EINT2                                                        */

  18.         value = INREG32(&pOalPortRegs->EXTINT0);
  19.         OUTREG32(&pOalPortRegs->EXTINT0, (value & ~(7 << 8))|(2 << 8));                /* Configure EINT2 as Falling Edge Mode                                */

  20.         CLRREG32(&pIntrRegs->INTMSK, (1<

  21.         irq = IRQ_EINT2;
  22.         sysIntr = OALIntrRequestSysIntr(1, &irq, OAL_INTR_FORCE_STATIC);
  23.         if (!OEMInterruptEnable(sysIntr, NULL, 0)) {
  24.                 OALMSG(OAL_ERROR, (L"ERROR: BSPIntrInit: Interrupt enable for reset button failed"));
  25.         }

  26.     // Set GPG1 as EINT9
  27.     value = INREG32(&pOalPortRegs->GPGCON);
  28.     OUTREG32(&pOalPortRegs->GPGCON, (value & ~(3 << 2))|(2 << 2));

  29.     // Disable pullup
  30.     value = INREG32(&pOalPortRegs->GPGUP);
  31.     OUTREG32(&pOalPortRegs->GPGUP, value | (1 << 1));

  32.     // High level interrupt
  33.     value = INREG32(&pOalPortRegs->EXTINT1);
  34.     OUTREG32(&pOalPortRegs->EXTINT1, (value & ~(0xf << 4))|(0x1 << 4));

  35.     // Add static mapping for Built-In OHCI
  36.     OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBH);

  37.         // OALIntrStaticTranslate(SYSINTR_USBFN, IRQ_USBFN);
  38.     OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrInit(rc = 1)\r\n"));
  39.     return TRUE;
  40. }
复制代码
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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