请帮小弟我分析一下这个错误产生的原因

请帮我分析一下这个异常产生的原因
经过昨天的努力,终于把串口的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;