经过昨天的努力,终于把串口的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就产生异常对了呢?以前大学都是调试单片机,代码比较简单,对这个异常几乎没有什么经验处理。请大家帮忙分析一下,谢谢。
------解决方案--------------------
没有正确使用WRITE_PORT_UCHAR( )这个函数?有没进行参数检查?最好调此函数前进行参数检查,无效指针就不要传了,直接返回。我一次就是因为无效指针引起异常的。
------解决方案--------------------
- C/C++ code
//// @doc HWINTERNAL// @struct LS_SERIAL_INFO | Passed to serial lib routines.// typedef struct __LS_SERIAL_INFO { // Store volatile pointers to each 16550 register volatile PUCHAR pData; // @field RX data / Transmit Holding Reg volatile PUCHAR pIER; // @field Interrupt Enable volatile PUCHAR pIIR_FCR; // @field read IIR (Int ID) / Write FCR (FIFO Ctrl) volatile PUCHAR pLCR; // @field Line Control volatile PUCHAR pMCR; // @field Modem Control volatile PUCHAR pLSR; // @field Line Status volatile PUCHAR pMSR; // @field Modem Status volatile PUCHAR pScratch; // @field Scratch Register // And we keep shadows of many of the 16550 registers UCHAR FCR; // @field FIFO control state. UCHAR IIR; // @field State of Interrupt Identification Register. UCHAR LSR; // @field Line Status Register. UCHAR MSR; // @field Modem Status Register. // We wouldn't normally shadow these, except for power on/off UCHAR IER; // @field Interrupt Enable Register. UCHAR LCR; // @field Line Control Register. UCHAR MCR; // @field Modem Control Register. UCHAR Scratch; // @field Scratch Register. // We have an event callback into the MDD EVENT_FUNC EventCallback; // This callback exists in MDD PVOID pMddHead; // This is the first parm to callback // Keep a copy of DCB since we rely on may of its parms DCB dcb; // @field Device Control Block (copy of DCB in MDD) // And the same thing applies for CommTimeouts COMMTIMEOUTS CommTimeouts; // @field Copy of CommTimeouts structure // Misc fields used by ser16550 library ULONG OpenCount; // @field Count of simultaneous opens. PLOOKUP_TBL pBaudTable; // @field Pointer to Baud Table ULONG DroppedBytes; // @field Number of dropped bytes HANDLE FlushDone; // @field Handle to flush done event. BOOL CTSFlowOff; // @field Flag - CTS flow control state. BOOL DSRFlowOff; // @field Flag - DSR flow control state. BOOL AddTXIntr; // @field Flag - Fake a TX intr. COMSTAT Status; // @field Bitfield representing Win32 comm status. ULONG CommErrors; // @field Bitfield representing Win32 comm error status. ULONG ModemStatus; // @field Bitfield representing Win32 modem status. CRITICAL_SECTION TransmitCritSec; // @field Protects UART Registers for non-atomic accesses CRITICAL_SECTION RegCritSec; // @field Protects UART ULONG ChipID; // @field Chip identifier (CHIP_ID_16550 or CHIP_ID_16450) BOOL PowerDown; // did we power down the chip BOOL bSuspendResume; // Indicate Suspend/Resume happens // // now hardware specific fields Duplicated Info DWORD dwIrq; // IRQ field DWORD dwSysIntr; // @field System Interrupt number for this peripheral PVOID pVirtualStaticAddr;// Static Address. WCHAR RegIsrDll[DEVDLL_LEN];// ISR Dll name. WCHAR RegIsrHandler[DEVENTRY_LEN];//ISR Handle Name. volatile ISR16550_INFO * pIsrInfoVirt; volatile XmitDataBuffer * pXmitBuffer; volatile RcvDataBuffer * pReceiveBuffer; HANDLE hIsrHandler; BOOL bMoreXmitData;// For software xmit buffering DWORD dwIsrIndex; // For test only } SER16550_INFO, *PSER16550_INFO;