周立功老师的《PDIUSBD12固件编程与驱动开发》这本书的68页有代码:void ep0_txdone(),在76页有代码code_transmit(unsigned char *code pRomeData,unsigned short len),黑体字的函数其实是为了服务像get_descriptor()这种属于“从设备上传数据给主机”类型的标准请求的。
而ep0_txdone()不也是这样的功能的么?,那为什么还需要把这两段代码都放在程序中呢?或者,应该这么问:在USB设备枚举过程中,单片机MCU调用的到底是ep0_txdone()还是code_transmit( , , ,)呢?
我们就拿get_descriptor标准请求作为例子来说说这两段代码。
在详细说明之前,先列出两个事实:
事实1,PDIUSBD12的EP0的缓冲区只有16B
事实2,PDIUSBD12有中断EP0IN和EP0OUT,这两个中断发生的时间段分别为:
事实2.1,EP0out中断发生在主机在数据阶段把数据发送至EP0的缓冲区 后
事实2.2,EP0in中断发生在EP0in将数据发送至主机,且主机返回Ack后,这个中断告诉EP0IN需要继续准备数据(如果有数据的话)
有了这两个事实后,接下来拿get_descriptor来回答开始提出的问题:在设备枚举阶段或者在我们自己发送设备请求的时候,固件端的单片机MCU到底调用了哪个函数(code_transmit() or ep0in() ?)了呢?
答案是:两者都需要调用
就“get device descritor”来说,因为device descriptor的总长度是18bytes,因此单片机MCU会先调用get_descritor()函数(也就是调用code_transmit()函数),这个函数将16bytes的数据发送至Ep0的buffer然后传送至主机,在主机成功接收返回ACK后产生EP0IN中断,于是就调用EP0IN()函数继续把剩下的两字节的数据传送给EP0buffer,等待主机来取走
那么,如果是get_status这样的标准请求是否就不再调用EP0IN( )函数了呢?
答案是仍然需要而且是必然会调用:一来,肯定会产生EP0IN中断,再者在“控制传输”里控制传输需要三个阶段:建立阶段-->数据阶段-->状态阶段,对于get_status这样的返回的字节数比较少的标准请求来说,这个时候的EP0IN中断函数实际上扮演的就是“状态阶段”上传0字节数据这样的一个角色
不知道说的对不对。
文章评论(0条评论)
登录后参与讨论