来源于《Windows CE 工程实践与完全解析》
由于WinCE的串口驱动程序的MDD层是由微软提供的。MDD层与PDD层之间的PDD COMMON层也是通用型设计,尽管必要时我们可以对他做修改。WinCE的串口驱动开发耗费最大的工作是它的PDD层。微软为开发者提供了一个CSerialPDD类作为开发工作起点。
CSerialPDD类是纯虚类,但是它的大多数成员函数都给出了通用型实现。WinCE的串口驱动程序的开发者将驱动程序的PDD层定义成为CSerialPDD类的继承类。这个类的成员函数必须准确全面的反映目标硬件平台上的特定类型串口的属性。必要时可以调用父类CSerialPDD的成员函数以减轻重复的工作量。串口驱动程序的MDD层和PDD COMMON层不需要知道用户的CSerialPDD继承类的命名和具体实现。以CSerialPDD类指针引用其继承类实例的功能。
串口驱动程序开发的实例,无非就是定义一个CSerialPDD类的具体继承类的,在CSerialPDD类的基础上扩充。最重要的是根据目标平台上的串口的实际硬件特性实现其虚拟函数及扩充其虚拟函数的功能和实现。
S3C2416 的代表串口驱动程序PDD层的抽象数据结构是CPdd2416Uart类。毫无疑问,它是CSerialPDD类的继承类。除了CSerialPDD外,CPdd2416Uart类还继承了CMiniThread类。CMiniThread类只是一个封装了WinCED 线程管理系统调用函数的简单类。供串口驱动程序启动和管理它的IST线程。CPdd2416Uart类在头文件C:\WINCE500\PLATFORM\SMDK2416\Src\Drivers\Serial\pdds3c2416_ser.h中定义如下:
class CPdd2416Uart: public CSerialPDD, public CMiniThread {
public:
CPdd2416Uart (LPTSTR lpActivePath, PVOID pMdd, PHWOBJ pHwObj);
virtual ~CPdd2416Uart();
virtual BOOL Init();
virtual void PostInit();
virtual BOOL MapHardware();
virtual BOOL CreateHardwareAccess();
// Power Manager Required Function.
virtual void SerialRegisterBackup() { m_pReg2416Uart->Backup(); };
virtual void SerialRegisterRestore() { m_pReg2416Uart->Restore(); };
// Implement CPddSerial Function.
// Interrupt
virtual BOOL InitialEnableInterrupt(BOOL bEnable ) ; // Enable All the interrupt may include Xmit Interrupt.
private:
virtual DWORD ThreadRun(); // IST
// Tx Function.
public:
virtual BOOL InitXmit(BOOL bInit);
virtual void XmitInterruptHandler(PUCHAR pTxBuffer, ULONG *pBuffLen);
virtual void XmitComChar(UCHAR ComChar);
virtual BOOL EnableXmitInterrupt(BOOL bEnable);
virtual BOOL CancelXmit();
virtual DWORD GetWriteableSize();
protected:
BOOL m_XmitFifoEnable;
HANDLE m_XmitFlushDone;
//
// Rx Function.
public:
virtual BOOL InitReceive(BOOL bInit);
virtual ULONG ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen);
virtual ULONG CancelReceive();
virtual DWORD GetWaterMark();
virtual BYTE GetWaterMarkBit();
virtual void Rx_Pause(BOOL bSet) {;};
protected:
BOOL m_bReceivedCanceled;
DWORD m_dwWaterMark;
//
// Modem
public:
virtual BOOL InitModem(BOOL bInit);
virtual void ModemInterruptHandler() { GetModemStatus();};
virtual ULONG GetModemStatus();
virtual void SetDTR(BOOL bSet) {;};
virtual void SetRTS(BOOL bSet);
//
// Line Function.
virtual BOOL InitLine(BOOL bInit) ;
virtual void LineInterruptHandler() { GetLineStatus();};
virtual void SetBreak(BOOL bSet) ;
virtual BOOL SetBaudRate(ULONG BaudRate,BOOL bIrModule) ;
virtual BOOL SetByteSize(ULONG ByteSize);
virtual BOOL SetParity(ULONG Parity);
virtual BOOL SetStopBits(ULONG StopBits);
//
// Line Internal Function
BYTE GetLineStatus();
virtual void SetOutputMode(BOOL UseIR, BOOL Use9Pin) ;
protected:
CReg2416Uart * m_pReg2416Uart;
PVOID m_pRegVirtualAddr;
volatile S3C2416_INTR_REG * m_pINTregs;
DWORD m_dwIntShift;
public:
void DisableInterrupt(DWORD dwInt) {
m_pINTregs->INTSUBMSK |= (dwInt<<m_dwIntShift);
}
void EnableInterrupt(DWORD dwInt) {
m_pINTregs->INTSUBMSK &= ~(dwInt<<m_dwIntShift);
}
void ClearInterrupt(DWORD dwInt) {
m_pINTregs->SUBSRCPND = (dwInt<<m_dwIntShift);
}
DWORD GetInterruptStatus() { return ((m_pINTregs->SUBSRCPND) >> m_dwIntShift);};
DWORD GetIntrruptMask () { return ((~(m_pINTregs->INTSUBMSK) )>> m_dwIntShift); };
protected:
CRegistryEdit m_ActiveReg;
// Interrupt Handler
DWORD m_dwSysIntr;
HANDLE m_hISTEvent;
// Optional Parameter
DWORD m_dwDevIndex;
DWORD m_dwISTTimeout;
};
但是 CPdd2416Uart类任然不是最具体的CSerialPDD继承类,在S3C2416的串口驱动程序实现中。以CPdd2416Uart类为父类又定义实现了两个继承类CPdd2416Serial1和CPdd2416Serial2,它们分别抽象代表S3C2416芯片内的UART0和UART2端口。其中的UART1端口被系统控制用于调试端口,这三个串口端口的硬件原理是基本相同的,但是它们的控制与状态寄存器的地址各不相同。导致其对CSerialPDD类的(纯)虚函数的实现方式略有不同。比如,在CPdd2416Serial0类中。除了新的构造与析构函数外,还重新实现了
Init()
SetDefaultConfiguration()
InitModem(BOOL bInit)
GetModemStatus()
SetDTR(BOOL bSet)
等成员函数。