现在的位置: 首页 > 综合 > 正文

CE6 实现 USB 转 串口

2013年10月26日 ⁄ 综合 ⁄ 共 8936字 ⁄ 字号 评论关闭

使用的芯片是pl2303,wince500下厂商提供驱动,但wince600没有,因为不了解USB,整个过程困难重重,参考大量帖子,有用的很少。

usb 转为 com6

首先要移植public下usbser的代码,生成USBSer.dll,这个太重要了

    1、复制Public下的USBSER整个文件夹到C:/WINCE600/PLATFORM/SMDK6410/Src/Drivers/Usb;

     2、在PB下打开命令行工具,并切换路径到当前USBSER文件夹所在的路径,使用命令 sysgen_capture -p common usbser  转换完成后,将在当前目录下会生成sources.xxx的文件,由于我们只需要生成usbser的目标文件,因此可以将其他sources.xxx文件删除。

     3、下面的工作就是如何生成dll文件:

           实现方式一:(使用LIB生成DLL)

          (1)在当前目录下新建一个文件夹XXX(USBSERDLL),把sourcess.usbser拷贝到该新建文件夹并重命名为sources;

          (2)打开该sources,将DEFFILE宏修改为DEFFILE=$(TARGETNAME).def;

          (3)从USBSER文件夹将usbser.def文件和makefile文件复制一份到USBSERDLL,即USBSERDLL文件夹中现在只有Makefile、sources和.def文件;

          (4)在USB文件夹下的dir文件中,加入USBSERDLL、USBSER的编译选项信息;

          (5)在USBSER的sources文件中删除WINCETARGETFILE0=$(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/$(TARGETDEFNAME).def;

          (6)build Usb文件夹,把编译报错的头文件(主要是在pubic下未包含的文件,该例子主要是缺少usbserv.h、usbinstl.h和usbclientfunc.h)复制到USBSER文件夹下,rebuild Usb,OK!

参考的是
http://blog.csdn.net/zhaojuncq/archive/2010/07/23/5757376.aspx

原来一直以为只要生成了USBSer.dll 就万事大吉了,其实我错了,这只是第一步而已。

Catalog Items View中 Core OS -> Device Driver -> USB Function -> USB Function Clients -> serial 打勾

修改WINCE600-6410/PUBLIC/COMMON/OAK/DRIVERS/USB/CLASS/USBSER目录下usbser.cpp

在47行增加

#define USBSER_PL2303 TEXT("USBSER_PL2303")
USB_DRIVER_SETTINGS Pl2303DriverSettings = {
    sizeof(USB_DRIVER_SETTINGS),
        0x067b,0x2303,USB_NO_INFO,//Vendor Info
        USB_NO_INFO,USB_NO_INFO,USB_NO_INFO,//Device Info
        USB_NO_INFO,USB_NO_INFO,USB_NO_INFO // Interface Info.
};
static DWORD dwPl2303Index = 2;
REGINI Pl2303Reg[] = {
   {TEXT("Prefix"),(PBYTE)PREFIX_STRING,sizeof(PREFIX_STRING),REG_SZ},
   {TEXT("DeviceArrayIndex"),(PBYTE)&dwPl2303Index,sizeof(DWORD),REG_DWORD},
   {TEXT("IClass"),(PBYTE)ICLASSSTRING,sizeof(ICLASSSTRING),REG_SZ}
};

在USBInstallDriver函数中增加

        if (usbInstall.RegisterClientDriverID(USBSER_PL2303) &&
                usbInstall.RegisterClientSettings(szDriverLibFile,USBSER_PL2303,&Pl2303DriverSettings)) {

            usbInstall.SetDefaultDriverRegistry(USBSER_PL2303, _countof(Pl2303Reg), Pl2303Reg, TRUE );
            usbInstall.SetDefaultDriverRegistry(USBSER_PL2303, 1 , &DriverDllEntry, TRUE );
        }

在USBUnInstallDriver函数中增加

        usbInstall.UnRegisterClientSettings(USBSER_PL2303,NULL,&Pl2303DriverSettings);

修改WINCE600-6410/PUBLIC/COMMON/OAK/DRIVERS/USB/CLASS/USBSER目录下userdev.cpp

增加

UsbPl2303SerialClientDriver::UsbPl2303SerialClientDriver(LPTSTR lpActivePath, PVOID pMdd, PHWOBJ pHwObj )
:   UsbSerClientDriver(lpActivePath,pMdd, pHwObj )
{
    m_dwHwType = PL2303_TYPE_0;
}

BOOL UsbPl2303SerialClientDriver::Init()
{
    DEBUGMSG(ZONE_INIT,(TEXT("+UsbSerClientDriver::Init")));
    if (m_lpUsbClientDevice && CSerialPDD::Init()) {
        LPCUSB_INTERFACE lpTargetInterface = m_lpUsbClientDevice->GetTargetInterface();
        // BulkIn, BulkOut, Option Interrupt.
        if (lpTargetInterface) {
            DWORD dwEndpoints = lpTargetInterface->Descriptor.bNumEndpoints;
            LPCUSB_ENDPOINT lpEndpoint = lpTargetInterface->lpEndpoints ;
            while (dwEndpoints && lpEndpoint!=NULL) {
                if ((lpEndpoint->Descriptor.bmAttributes &  USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) {
                    if (USB_ENDPOINT_DIRECTION_IN(lpEndpoint->Descriptor.bEndpointAddress)) {
                        CreateBulkIn(lpEndpoint);
                    }
                    else {
                        CreateBulkOut(lpEndpoint);
                    }
                }
                else
                if ((lpEndpoint->Descriptor.bmAttributes &  USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT &&
                        USB_ENDPOINT_DIRECTION_IN(lpEndpoint->Descriptor.bEndpointAddress)) {
                    CreateStatusIn(lpEndpoint);
                }
                lpEndpoint ++;
                dwEndpoints --;
            }
        }
        DEBUGMSG(ZONE_INIT,(TEXT("-UsbSerClientDriver::Init(m_lpSerialDataIn =%x, m_lpSerialDataOut =%x ,m_lpUsbSerDataStatus=%x )"),
            m_lpSerialDataIn,m_lpSerialDataOut,m_lpUsbSerDataStatus));
        ASSERT(m_lpSerialDataIn!=NULL && m_lpSerialDataOut!=NULL);

        LPCUSB_DEVICE lpTargetUsbDevice = m_lpUsbClientDevice->GetDeviceInfo();
        ASSERT(lpTargetUsbDevice!=NULL);

        if(lpTargetUsbDevice->Descriptor.bDeviceClass == 0x02)
            m_dwHwType = PL2303_TYPE_0;
        else if(lpTargetUsbDevice->Descriptor.bMaxPacketSize0 == 0x40)
            m_dwHwType = PL2303_TYPE_HX;
        else if((lpTargetUsbDevice->Descriptor.bDeviceClass == 0x00) || (lpTargetUsbDevice->Descriptor.bDeviceClass == 0xFF))
            m_dwHwType = PL2303_TYPE_1;

        RETAILMSG(1, (TEXT("m_dwHwType = %d./r/n"), m_dwHwType));

  // Hardware initialize
  UCHAR ucData = 0;
  Pl2303VendorRead(m_lpUsbClientDevice, 0x8484, 0, &ucData);
  RETAILMSG(1, (TEXT("Read0(0x8484) = 0x%02x./r/n"), ucData));
  Pl2303VendorWrite(m_lpUsbClientDevice, 0x0404, 0);
  Pl2303VendorRead(m_lpUsbClientDevice, 0x8484, 0, &ucData);
  RETAILMSG(1, (TEXT("Read1(0x8484) = 0x%02x./r/n"), ucData));
  Pl2303VendorRead(m_lpUsbClientDevice, 0x8383, 0, &ucData);
  RETAILMSG(1, (TEXT("Read0(0x8383) = 0x%02x./r/n"), ucData));
  Pl2303VendorRead(m_lpUsbClientDevice, 0x8484, 0, &ucData);
  RETAILMSG(1, (TEXT("Read2(0x8484) = 0x%02x./r/n"), ucData));
  Pl2303VendorWrite(m_lpUsbClientDevice, 0x0404, 1);
  Pl2303VendorRead(m_lpUsbClientDevice, 0x8484, 0, &ucData);
  RETAILMSG(1, (TEXT("Read3(0x8484) = 0x%02x./r/n"), ucData));
  Pl2303VendorRead(m_lpUsbClientDevice, 0x8383, 0, &ucData);
  RETAILMSG(1, (TEXT("Read1(0x8383) = 0x%02x./r/n"), ucData));
  Pl2303VendorWrite(m_lpUsbClientDevice, 0, 1);
  Pl2303VendorWrite(m_lpUsbClientDevice, 1, 0);
  if(m_dwHwType == PL2303_TYPE_HX)
   Pl2303VendorWrite(m_lpUsbClientDevice, 2, 0x44);
  else
   Pl2303VendorWrite(m_lpUsbClientDevice, 2, 0x24);

        return(m_lpSerialDataIn!=NULL && m_lpSerialDataOut!=NULL);
    }
    return FALSE;
}

void UsbPl2303SerialClientDriver::SetBreak(BOOL bSet)
{
    USB_DEVICE_REQUEST usbRequest = {
        USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE | USB_REQUEST_HOST_TO_DEVICE,
        USB_COMM_SEND_BREAK,
        BREAK_OFF,
        0,
        0
    };

    if(bSet)
    {
        usbRequest.wValue = BREAK_ON;
    }

    PREFAST_ASSERT(m_lpUsbClientDevice!=NULL)
    BOOL bReturn = m_lpUsbClientDevice->IssueVendorTransfer(0,&usbRequest,NULL, 0);
    ASSERT(bReturn==TRUE);
    m_lpUsbClientDevice->CloseTransfer();
}

void UsbPl2303SerialClientDriver::Pl2303VendorRead(PVOID pUsbClientDevice, USHORT wValue, USHORT wIndex, PUCHAR pBuf)
{
SerialUsbClientDevice * pUsbDevice = (SerialUsbClientDevice *)pUsbClientDevice;
USB_DEVICE_REQUEST usbRequest = {
  USB_REQUEST_VENDOR | USB_REQUEST_FOR_DEVICE | USB_REQUEST_DEVICE_TO_HOST,
  PL2303_VENDOR_READ_WRITE_REQUEST,
  0,
  0,
  1
};

usbRequest.wValue = wValue;
usbRequest.wIndex = wIndex;

PREFAST_ASSERT(pUsbDevice!=NULL)
BOOL bReturn = pUsbDevice->IssueVendorTransfer(0,&usbRequest,pBuf, 0);
ASSERT(bReturn==TRUE);
pUsbDevice->CloseTransfer();
}

void UsbPl2303SerialClientDriver::Pl2303VendorWrite(PVOID pUsbClientDevice, USHORT wValue, USHORT wIndex)
{
SerialUsbClientDevice * pUsbDevice = (SerialUsbClientDevice *)pUsbClientDevice;
USB_DEVICE_REQUEST usbRequest = {
  USB_REQUEST_VENDOR | USB_REQUEST_FOR_DEVICE | USB_REQUEST_HOST_TO_DEVICE,
  PL2303_VENDOR_READ_WRITE_REQUEST,
  0,
  0,
  0
};

usbRequest.wValue = wValue;
usbRequest.wIndex = wIndex;

PREFAST_ASSERT(pUsbDevice!=NULL)
BOOL bReturn = pUsbDevice->IssueVendorTransfer(0,&usbRequest,NULL, 0);
ASSERT(bReturn==TRUE);
pUsbDevice->CloseTransfer();
}

修改CreateSerialObject函数增加

    else if (DeviceArrayIndex == 2) {
        pSerialPDD= new UsbPl2303SerialClientDriver(lpActivePath,pMdd, pHwObj);
        if (pSerialPDD && !pSerialPDD->Init()) {
            delete pSerialPDD;
            pSerialPDD = NULL;
        }
    }

修改WINCE600-6410/PUBLIC/COMMON/OAK/DRIVERS/USB/CLASS/USBSER目录下userdev.h增加

#define PL2303_VENDOR_READ_WRITE_REQUEST  0x01

#define BREAK_ON        0xffff
#define BREAK_OFF        0x0000

// PL2303 hardware type
#define PL2303_TYPE_0       0
#define PL2303_TYPE_1       1
#define PL2303_TYPE_HX       2

class UsbPl2303SerialClientDriver : public UsbSerClientDriver {
public:
    UsbPl2303SerialClientDriver(LPTSTR lpActivePath, PVOID pMdd, PHWOBJ pHwObj );
    virtual BOOL Init();
    virtual void    SetBreak(BOOL bSet);

protected:
DWORD m_dwHwType;

private:
static void Pl2303VendorRead(PVOID pUsbClientDevice, USHORT wValue, USHORT wIndex, PUCHAR pBuf);
static void Pl2303VendorWrite(PVOID pUsbClientDevice, USHORT wValue, USHORT wIndex);
};

最后修改组册表

增加

[HKEY_LOCAL_MACHINE/Drivers/USB/LoadClients/1118_206/Default/Default/SERIAL_CLASS]
"Prefix"="COM"
"Dll"="USBSer.DLL"
[HKEY_LOCAL_MACHINE/Drivers/USB/ClientDrivers/SERIAL_CLASS]
"Prefix"="COM"
"Dll"="USBSer.DLL"
"RxBufferSize"=dword:4000
"DeviceArrayIndex"=dword:0
"IClass"="{CC5195AC-BA49-48a0-BE17-DF6D1B0173DD}"

[HKEY_LOCAL_MACHINE/Drivers/USB/LoadClients/1118_121/Default/Default/USBSER_CLASS]
"Prefix"="COM"
"Dll"="USBSer.DLL"
[HKEY_LOCAL_MACHINE/Drivers/USB/ClientDrivers/USBSER_CLASS]
"Prefix"="COM"
"Dll"="USBSer.DLL"
"DeviceArrayIndex"=dword:1
"RxBufferSize"=dword:4000
"IClass"="{CC5195AC-BA49-48a0-BE17-DF6D1B0173DD}"

[HKEY_LOCAL_MACHINE/Drivers/USB/LoadClients/1659_8963/Default/Default/USBSER_PL2303]
"Prefix"="COM"
"Dll"="USBSer.DLL"
[HKEY_LOCAL_MACHINE/Drivers/USB/ClientDrivers/USBSER_PL2303]
"Prefix"="COM"
"Dll"="USBSer.DLL"
"DeviceArrayIndex"=dword:2
"index"=dword:6
"RxBufferSize"=dword:4000
"IClass"="{CC5195AC-BA49-48a0-BE17-DF6D1B0173DD}"

抱歉!评论已关闭.