阅读:1661回复:14
主机从端点2读数,为什么只能读出开始的64字节?给分!jinhuiren大侠请进!
在应用程序中向端点2写64字节的字符‘c’作为启动命令,通知MCU发送1024字节的数据给主机。在固件中接收到端点2的OUT中断后执行如下代码:
unsigned int ioCount; void main_rxdone(void) { unsigned char len,epstatus; D12_ReadLastTransactionStatus(4); //清中断标志位 //接收数据 len = D12_ReadEndpoint(4, 64, EpBuf); epstatus=D12_ReadEndpointStatus(4); epstatus &= 0x60; if (epstatus == 0x60) len = D12_ReadEndpoint(4, 64, EpBuf);//读取双缓冲区数据 if(EpBuf[0]==\'c\'&&EpBuf[EP2_PACKET_SIZE-1]==\'c\'){ D12_WriteEndpoint(5,64,EpBuf); ioCount=15; } } 然后在端点2的IN中断处理函数如下: void main_txdone(void) { D12_ReadLastTransactionStatus(5); //清中断标志位 if(ioCount!=0) { ioCount=ioCount-1; D12_WriteEndpoint(5,64,EpBuf); } } 可是实际的情况是主机只接收了64字节,main_txdone(void)函数也只被执行一次。请问是何缘故? |
|
最新喜欢:![]() |
沙发#
发布于:2003-12-04 17:26
你主机读了几次呢
|
|
板凳#
发布于:2003-12-04 17:42
主机只读了一次如下:
ReadFile(hDevice,buf,1024,&nByteRead,NULL); |
|
地板#
发布于:2003-12-04 17:46
当我每次只读64字节,读16次时,就对了!但是速度却很慢,只有16k!我用D12Test。exe测试却是30多k,
能不能够实现执行ReadFile()函数就读进来1024字节而不是象我那样执行16次的ReadFile()函数。 |
|
地下室#
发布于:2003-12-05 09:33
呵呵,D12的端点缓冲区为64个字节,而你主机读一次只产生一个中断,所以会出现你上面所说的现象,至于速度的问题,我不知道你的16K是怎么测出来的,你可以把ReadFile函数中的一次读1024个字节改为一次读64个字节,效果应该会好一些,D12Test.exe的源代码中就是一次读64个字节,只不过他的命令是模仿WINDOWS枚举的控制模式,通过厂商请求的方式从端点0走的,不过这个跟速度应该没什么关系。
|
|
5楼#
发布于:2003-12-05 11:54
我也是模仿D12开发办应用程序的做法,两次调用timeGetTime(),来进行的。如下:
DWORD time0,time1; double rate; time0=timeGetTime(); ReadFile(hFile,buf,n,&nBytes,NULL); time1=timeGetTime(); rate=n/(time1-time0-1) 不管怎样还是谢谢的帮助!给分了! |
|
6楼#
发布于:2003-12-05 15:18
呵呵,其实给不给分都无所谓了啦,关键是大家一起探讨一起进步啊。
|
|
7楼#
发布于:2003-12-05 15:39
呵呵,不错,交个朋友吧!
|
|
8楼#
发布于:2003-12-07 11:20
楼主,我现在和你实现过程想像的问题:即主机发一次命令,下位机要发一大批数上来!
? 1)以你一次发1024个数为例,在D12的发送缓冲中一次只能写入64个字节,我看了你在发送中断中写入,举个例子说,如何保证第2次写入的是你要求的第65――128个数呢? 2)你在上位机读了16次即读到了你要求的1024个数。你在上位机是不是不间断地读。请问你是如何很好地实现这个\"不间断读\"的.是不是用一个有限的循环,在循环体内调用readfile? 忘不舍赐教! |
|
9楼#
发布于:2003-12-07 21:10
我也是一知半解,就我所知道的,我就讲一些吧!你说的都对!
1。由于端点2的缓冲区是64字节,所以每次的读写都是以64字节为单位的,在应用程序中可以只执行一次ReadFile,然后在驱动中以64字节为单位读取指定大小的数据。 2。当主机每次从USB设备读取64字节的数据后,会使D12控制器产生一个发送中断,MCU相应该中断并在该发送中断处理函数中清除中断请求。在这里我们可以发送我们要发送的数据,每次64字节。 3。当应用程序需要USB设备发送给主机的时候,必须要先通知USB设备。我们可以有2中方法通知USB设备,一种是发送VendorRequest给USB设备,在VendorReques请求中指定我们需要的数据量大小;或者是主机通过某一个端点如端点1发送一个特定的数据给USB设备,然后在USB设备的端点1的接收函数中判断是否是该特定的数据,如果是就准备发送数据给主机。 4。当主机通知USB设备结束后,紧跟着执行ReadFile函数了,我们可以指定它为同步方式,不收到指定大小的数据就不退出。 5。当USB设备接收到主机发送数据的请求以后,就先发送一个64字节的数据到相应的端点如端点2。这时我们需要有一个全局变量来记录USB设备有没有刚好发送完数据。当发送的第一个64字节的数据被主机接收到以后,D12控制器就会发送一个发送中断请求,然后我们再在发送中断处理函数中判断是否送完数据了,如果还有数据要送就继续发送64字节的数据,全局变量加1。 好像有些罗嗦,不好意思,凑合着看吧! |
|
10楼#
发布于:2003-12-08 14:26
就你说的我说几句:
1。由于端点2的缓冲区是64字节,所以每次的读写都是以64字节为单位的,在应用程序中可以只执行一次ReadFile,然后在驱动中以64字节为单位读取指定大小的数据。 “只执行一次ReadFile,然后在驱动中以64字节为单位读取指定大小的数据。”--那你这样不是只能读64个字节上来吗!怎样实现读后面的数据呢,是不是应该在应用程序中重复几次调用readfile函数呢? 2。当主机每次从USB设备读取64字节的数据后,会使D12控制器产生一个发送中断,MCU相应该中断并在该发送中断处理函数中清除中断请求。在这里我们可以发送我们要发送的数据,每次64字节。 这一点我看了你上面贴的代码,弄懂了你的意思。就是说在你一次要读1024个数的过程中,第一次读了1-64个数,pc机读这些数,读完后给下面发中断,在端点2的发送中断程序中你调用WriteEndPoint函数将你要传的65-128个数由下位机的Epbuf写到D12的FIFO中,以便第二次读,是吧? 我现在的主要问题是:你如何保证第二次写到D12的FIFO中的数是你要的第65―128号数呢?毕竟你在下位机的ram中给Epbuf的空间是有限的,一般用的好像也都是64Byte,这要求你Epbuf中的数是要更新的!这中间应该存在一个时间问题:如果你Epbuf更新太快,传上去的数可能会掉一部分;如果太慢,可能2次会读到相同的数! 不知道是否真正会存在这些问题!这个好像要和上位机的程序联系起来综合考虑!不知道你是怎样解决好这个问题的? 3。当应用程序需要USB设备发送给主机的时候,必须要先通知USB设备。我们可以有2中方法通知USB设备,一种是发送VendorRequest给USB设备,在VendorReques请求中指定我们需要的数据量大小;或者是主机通过某一个端点如端点1发送一个特定的数据给USB设备,然后在USB设备的端点1的接收函数中判断是否是该特定的数据,如果是就准备发送数据给主机。 zlg的源代码好像是用VendorReques请求实现的,根据你上面贴的代码是根据第2种方式实现的。我没有理解错吧!“如果是就准备发送数据给主机。”你就是指调用WriteEndPoint函数,将数据写到D12的FIFO中吧,数据要到主机,是不是还要上面调用readfile函数呢? 4。当主机通知USB设备结束后,紧跟着执行ReadFile函数了,我们可以指定它为同步方式,不收到指定大小的数据就不退出。 ---这里说的“同步方式”,我不是很理解!能否解释一下! 5。当USB设备接收到主机发送数据的请求以后,就先发送一个64字节的数据到相应的端点如端点2。这时我们需要有一个全局变量来记录USB设备有没有刚好发送完数据。当发送的第一个64字节的数据被主机接收到以后,D12控制器就会发送一个发送中断请求,然后我们再在发送中断处理函数中判断是否送完数据了,如果还有数据要送就继续发送64字节的数据,全局变量加1。 ---这个根据你的代码我理解! 感谢你写了这么多。我现在的主要问题就集中在第2点上。对于一个数据采集系统,我可能定时采样更新程序中Epbuf中的数据。依据我们现在的这种机制,问题在上下位机如何搭配。我感觉你一次读1024个数据对我很有参考意义!忘不舍赐教! |
|
11楼#
发布于:2003-12-08 21:55
引用:
//////////////////////////////////////// 这一点我看了你上面贴的代码,弄懂了你的意思。就是说在你一次要读1024个数的过程中,第一次读了1-64个数,pc机读这些数,读完后给下面发中断,在端点2的发送中断程序中你调用WriteEndPoint函数将你要传的65-128个数由下位机的Epbuf写到D12的FIFO中,以便第二次读,是吧? 我现在的主要问题是:你如何保证第二次写到D12的FIFO中的数是你要的第65―128号数呢?毕竟你在下位机的ram中给Epbuf的空间是有限的,一般用的好像也都是64Byte,这要求你Epbuf中的数是要更新的!这中间应该存在一个时间问题:如果你Epbuf更新太快,传上去的数可能会掉一部分;如果太慢,可能2次会读到相同的数! //////////////////////////////////////// 1。你说的非常的对,完全有可能出现你说得情况!如果出现这种情况的话,只有使用FIFO或者是其他的什么存储器作个缓冲了!但是第二种情况肯定不会发生!因为发送数据的主动权在你的手上,你可以加一个标志来判断是否有更新!这个应该不难办!但是对于第一种情况,就只有缓冲一下了,毕竟D12的传输数据的能力很有限,一般D12就做到100K左右,可是如果你的数据刷新的频率高于这个频率的话,要么换一种接口,要么加个缓冲,但是加缓冲的话,不是解决问题的最好办法! 2。同步方式的意思是说当RFeadFile语句中指定大小的数据没有读完,就会一直处于读的状态而不会返回执行下一个语句,通常这种办法比较简单,但是效率不高,会让用户感觉的到阻塞!最好是用异步方式,定义一个异步对象OVERLAPPED结构!具体的操作可以去查! 3。引用: ////////////////////////////////////// “只执行一次ReadFile,然后在驱动中以64字节为单位读取指定大小的数据。”--那你这样不是只能读64个字节上来吗!怎样实现读后面的数据呢,是不是应该在应用程序中重复几次调用readfile函数呢? ////////////////////////////////// ReadFile语句可以指定一个以64字节为单位的数据大小,譬如1024,具体的划分是在驱动中执行,驱动就执行16次的读写,每次64字节! |
|
12楼#
发布于:2003-12-09 11:22
\"但是第二种情况肯定不会发生!因为发送数据的主动权在你的手上,你可以加一个标志来判断是否有更新!\" ------这样是不是不能保证上面是在连续读数了呢? “ReadFile语句可以指定一个以64字节为单位的数据大小,譬如1024,具体的划分是在驱动中执行,驱动就执行16次的读写,每次64字节!” ---这一点我不太清楚,在readfile()的参数中ilen是设定1024,还是64? |
|
13楼#
发布于:2003-12-09 14:01
驱动设置的是64*1024,如果想变大就把读取的字节数边成1280*1024就不会有问题了。在文件EZUSBSYS。C
|
|
14楼#
发布于:2004-10-12 08:28
hoosyman,您好!我看了你的帖子有一些问题不太明白向您请教一下:您说的“ReadFile语句可以指定一个以64字节为单位的数据大小,譬如1024,具体的划分是在驱动中执行,驱动就执行16次的读写,每次64字节!”请问您的驱动程序是用ds编写的还是直接用ddk编写的,我用ds生成的驱动程序好像不能对请求的数据长度进行分割呀?请不吝赐教!!!
|
|
|