Window XP驱动开发(十四) 驱动应用程序端代码实现(针对USB2.0 芯片CY7C68013A,基于CyAPI.lib与Bulkloop固件)

转载请标明是引用于 http://blog.csdn.net/chenyujing1234 

欢迎大家提出意见,一起讨论!

需要源码的可以与我联系.

 

在我的一篇文章    Window XP驱动开发(十二) 驱动应用程序端 (原理分析)

中讲到了驱动应用程序端的开发原理。

这里针对CY7C68013A供应商提供的 .sys .inf及提供的.lib文件进行应用程序端的开发。

 先看一下界面效果:

一、环境

http://www.cypress.com/?rID=34870 下载 CY7C68013的组件开发安装程序。

下载后得到

 

安装后得到驱动安装文件与应用程序开发库:

图一:

 

 

 

二、应用程序开发

现在我们就基于CyAPI.lib进行三次开发。

1、首先将 CyAPI.lib 与 CyAPI.lib加入到我们工程的链接中。(相对简单,不介绍了)

2、代码实现:

2、1  创建CCyUSBDevice接口

           USBDevice = new CCyUSBDevice(m_hWnd);   // Create an instance of CCyUSBDevice

2、2  获得设备列表,并找开设备。用:

         UCHAR                 DeviceCount(void);

         bool                  Open(UCHAR dev);

          获得端点列表,用:

         UCHAR                 EndPointCount(void);

         

void CBulkLoopDlg::OnRefreshBtn() 
{
    int i;

    // if we are currently running loopback, stop
    if (XferThread)
    {
        bLooping = false;

        InEndpt->Abort();
        InEndpt->Reset();

        OutEndpt->Abort();
        OutEndpt->Reset();

        m_StartBtn.SetWindowText("Start");
    }

    // clear the combo boxes
    m_DeviceListComBox.ResetContent();
	m_InEndptComBox.ResetContent();  
	m_OutEndptComBox.ResetContent();

    // make sure there is at lesat one device out there
    if (USBDevice->DeviceCount())
    {
        // search for all connected devices, and add them to the device
        // combo box
        for (i = 0; i < USBDevice->DeviceCount(); i++)
        {
            USBDevice->Open(i);

            m_DeviceListComBox.AddString(USBDevice->DeviceName);
        }


        m_DeviceListComBox.SetCurSel(0);
        OnSelchangeDeviceListCombox();		// This will set the device index and load the ep lists

    }	
}


 

void CBulkLoopDlg::OnSelchangeDeviceListCombox() 
{
    int i;
    char s[12];

    DeviceIndex = m_DeviceListComBox.GetCurSel();

    USBDevice->Open(DeviceIndex);

	// 获得端点数目
    int epts = USBDevice->EndPointCount();
    CCyUSBEndPoint *endpt;

	// Load the endpoint combo boxes
    // 跳过端点0,因为我们知道它是控制端点
	for (i=1; i<epts; i++)
    {    
        endpt = USBDevice->EndPoints[i];

        if (endpt->Attributes == 2)		// Bulk
        {
            sprintf(s, "0x%02X", endpt->Address);

			
            if (endpt->Address & 0x80)	// In 端点
            {
                m_InEndptComBox.AddString(s);
                m_InEndptComBox.SetItemData(m_InEndptComBox.GetCount()-1,i);
            }
            else						// Out端点
            {
                m_OutEndptComBox.AddString(s);
                m_OutEndptComBox.SetItemData(m_OutEndptComBox.GetCount()-1,i);
            }
        }
    }

    m_InEndptComBox.SetCurSel(0);
	m_OutEndptComBox.SetCurSel(0);

    OnSelchangeInCombox();		// Set the InEndpt member
	OnSelchangeOutCombox();		// Set the OutEndpt member

}


2、3  根据选定的In端点与Out 端点进行数据传输.

          Loop线程函数是 XferLoop,用到的函数有

        PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov);

        bool    WaitForXfer(OVERLAPPED *ov, ULONG tOut); 

        bool FinishDataXfer(PUCHAR buf, LONG &len, OVERLAPPED *ov, PUCHAR pXmitBuf, CCyIsoPktInfo* pktInfos = NULL);

 

void CBulkLoopDlg::OnStartBtn() 
{
	if (XferThread) {
		bLooping = false;

//		InEndpt->Abort();
//		InEndpt->Reset();

//		OutEndpt->Abort();
//		OutEndpt->Reset();

		m_StartBtn.SetWindowText("Start");
	} else {

		char s[12];
		ZeroMemory(s,12);
		m_XferSize.GetLine(0,s,8);
		LONG xfer = atol(s);
		if (xfer > 2048) {
			xfer = 2048;
			m_XferSize.SetWindowText("2048");
		}

        USBDevice->Open(DeviceIndex);
        OutEndpt = USBDevice->EndPoints[m_OutEndptComBox.GetItemData(m_OutEndptComBox.GetCurSel())];
        InEndpt = USBDevice->EndPoints[m_InEndptComBox.GetItemData(m_InEndptComBox.GetCurSel())];

		// Launch the looping thread  (Calls XferLoop() function, above.)
		if (xfer && USBDevice->IsOpen()) {
			bLooping = true;
			XferThread = AfxBeginThread(XferLoop, this);
		}

		m_StartBtn.SetWindowText("Stop");
	}
	
}


 

UINT XferLoop( LPVOID params ) {

    OVERLAPPED outOvLap, inOvLap; 

    CBulkLoopDlg *dlg = (CBulkLoopDlg *) params;
	char s[24];						ZeroMemory(s, 24);
	
	dlg->m_XferSize.GetLine(0,s,8);
	LONG xfer = atol(s);
	PUCHAR data = new UCHAR[xfer];	ZeroMemory(data,xfer);
	PUCHAR inData = new UCHAR[xfer];	ZeroMemory(inData,xfer);

    outOvLap.hEvent  = CreateEvent(NULL, false, false, "CYUSB_OUT"); 
    inOvLap.hEvent   = CreateEvent(NULL, false, false, "CYUSB_IN"); 

	dlg->m_SeedValue.GetLine(0,s,8);
	LONG seed = atol(s);

	int stopOnError = dlg->m_StopOnErrorChkBox.GetCheck();

	stuffBuff(data,xfer,seed,dlg->m_FillPatternComBox.GetCurSel());

	dlg->m_StatusLabel.SetWindowText(" STATUS: Transferring data . . .");
	dlg->m_SuccessCount.SetWindowText("0");
	dlg->m_FailureCount.SetWindowText("0");

	bool success;
	LONG nSuccess = 0;
	LONG nFailure = 0;

    if (dlg->m_DisableTimeoutChkBox.GetCheck())
    {
        dlg->OutEndpt->TimeOut = 0;
	    dlg->InEndpt->TimeOut = 0;
    }
    else
    {
        dlg->OutEndpt->TimeOut = 2000;
	    dlg->InEndpt->TimeOut = 2000;
    }

	for (;dlg->bLooping;) {
        LONG outlen,inlen,len;

        outlen = inlen = len = xfer;     // Use temp var because XferData can change the value of len

		// 发送数据给USB设备
	    UCHAR  *outContext = dlg->OutEndpt->BeginDataXfer(data,outlen,&outOvLap);
		// 从USB设备中读到数据
	    UCHAR  *inContext = dlg->InEndpt->BeginDataXfer(inData,inlen,&inOvLap);

		// 等待
        dlg->OutEndpt->WaitForXfer(&outOvLap,2000); 
        dlg->InEndpt->WaitForXfer(&inOvLap,2000); 

		// 完成数据传输
        success = dlg->OutEndpt->FinishDataXfer(data, outlen, &outOvLap,outContext); 
        success = dlg->InEndpt->FinishDataXfer(inData,inlen, &inOvLap,inContext); 


		if (success) {
			bool pass = (memcmp(data,inData,len) == 0);
			if (pass)
				nSuccess++;
			else
				nFailure++;
		} else 
			nFailure++;

		sprintf(s,"%d",nSuccess);
		dlg->m_SuccessCount.SetWindowText(s);
		sprintf(s,"%d",nFailure);
		dlg->m_FailureCount.SetWindowText(s);

		if ((!success) && stopOnError) dlg->bLooping = false;
	} 

    CloseHandle(outOvLap.hEvent); 
    CloseHandle(inOvLap.hEvent); 

	delete [] data;
	delete [] inData;

	dlg->m_StatusLabel.SetWindowText(" STATUS: Stopped");

	dlg->XferThread = NULL;

    dlg->USBDevice->Close();

	return true;
}


 

三、测试方法

1、加载此应用程序对应的CY7C68013固件

固件源码在CYPRESS提供的安装包下:

设计方法请看我的另一篇文章:<<>>

这里我们得把得到的bulkloop.hex单片机文件写入的CY7C里。

我们采用的工具是CYPRESS提供的工具: CyConsole.exe

(1)在运行界面下打开EZ-USB Interface选项界面

 

(2)选择Download按钮,将选择bulkloop.hex

 

(3)写入bulkloop.hex文件后,我们在设备管理器中发现此设备变化无法识别了。

这是因为我们之前的驱动是建立的VID:04B4      PID:8613 基础上的。

而现在我们的VID与PID变了,所以找不到驱动:

为什么PID发生了变化?这是因为bulkloop.hex改变了PID。请看我的文章:

<<http://blog.csdn.net/chenyujing1234/article/details/7722669>>

 

接下来我们修改CyUsb.inf文件。

 

2、修改CyUsb.Inf(请将以下的8613改为我们实际的PID,eg: 1004)

中的CyUSB.chm里有讲到怎么对CyUSB.INF进行修改,使之在具体的应该中使用.

1、1  增加设备的标识符到驱动中

把 图一中的CyUSB.inf中的

;%VID_XXXX&PID_XXXX.DeviceDesc%=CyUsb, USB\VID_XXXX&PID_XXXX

改为:

%VID_04B4&PID_8613.DeviceDesc%=CyUsb, USB\VID_04B4&PID_8613

 

1、2 替换Cypress 串,使之与自己的公司描述更确切。

CYUSB_Provider    = "Cypress"
CYUSB_Company     = "Cypress Semiconductor Corporation"
CYUSB_Description = "Cypress Generic USB Driver"
CYUSB_DisplayName = "Cypress USB Generic"

1、3  执行一个通用的GUID

   应用程序软件通过驱动的的GUID访问驱动,每一个Window系统的驱动都应该有一个唯一的GUID

因为可能会有不同的硬件供应商,这样就会有很多CYUSB.SYS的实例。我们可以通过GUIDGEN.exe来产生我们

自己的GUID。并把此GUI写在CyUSB.inf中

CYUSB.GUID="{AE18AA60-7F6A-11d4-97DD-00010229B959}"

 

1、4  在启动时执行一个脚本

  CYUSB.sys驱动在启动时能被配置到默认的控制端点(端点0)。

为了配置设备使之能表现控制传输,我们用CyConsole.exe来创建一个脚本文件。

我们保存此脚本文件为MyDevice.SPT,把此文件放到.INF文件下。

目的是让此脚夫本文件把固件镜像下载到设备中。

1、4、1  在CyUSB.inf中的 [CYUSB.AddReg.Guid]下添加

HKR,,DriverEXECSCRIPT,,%CYUSB.EXECSCRIPT%

1、4、2  在[Strings]下添加

 CYUSB.EXECSCRIPT="\systemroot\system32\MyDevice\MyDevice.spt"

 

2、强制系统用CYUSB.sys驱动

由于cyusb.inf文件中没有提供DefaultInstall 默认安装节点,但我们可以通过EzDriverInstaller安装(请参见:http://blog.csdn.net/chenyujing1234/article/details/7676812

安装完后,我们的应用程序才有意义,接下来开始测试应用程序了。

 

 

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值