打印

关于USB Lib里面的一段代码的疑问 (香版主帮忙!)

[复制链接]
1876|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yan2005|  楼主 | 2013-8-22 16:55 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
库里面的中断部分处理的部分代码:
void CTR_LP(void)
{
.....
SaveRState = _GetENDPOINT(ENDP0);
SaveTState = SaveRState & EPTX_STAT;
SaveRState &=  EPRX_STAT;
SetEPRxTxStatus(ENDP0,EP_RX_NAK,EP_TX_NAK)
.....
_ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
Setup0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
........
}

问题1:下面的理解是否正确?
_ClearEP_CTR_RX(ENDP0)执行之后,设备的硬件会立刻给主机发送一个ACK握手包?

问题2:下面的理解是否正确?
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState)只是说明设备准备好了收或者发数据。
但此时设备不能立刻把已经准备好的数据发送给主机,而是要等IN令牌包过来。
收到IN令牌包的一瞬间,设备的硬件自动把待发的数据发送给主机。

问题3:下面的理解是否正确?
因为一开始的时候设置了SetEPRxTxStatus(ENDP0,EP_RX_NAK,EP_TX_NAK),所以在执行_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState)之前,对来自主机的任何令牌包,设备都会不予接收而回复NAK。在设备回复NAK的情况下,主机会不停地发送控制传输第二阶段的令牌包(IN包或OUT包)。

下面,以第二阶段的IN包为例理解:
当设备执行了_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState)之后,接收功能被打开。一旦设备收到主机的IN令牌包,就会使CTR_RX或者CTR_TX置位,同时已经准备好的待发数据被发送给主机。然后在设备的中断程序里面,软件再次清除CTR_RX或者CTR_TX,于是硬件发送ACK握手包给主机。完成第二阶段的传输。

不知以上的理解是否正确,望香版主和各位高手指点下。
沙发
trumpxp| | 2013-8-22 19:58 | 只看该作者
不是很了解这一块   楼主  帮你顶一个   看看别人的意见

使用特权

评论回复
板凳
yan2005|  楼主 | 2013-8-23 09:43 | 只看该作者
原先理解有点问题,晚上重新看了遍,现在感觉基本上能自圆其说了。

控制传输由设置阶段(SETUP事务), 可选的数据阶段(IN或者OUT事务), 状态阶段(IN事务)组成。
当一个事务的令牌、数据、握手三个过程顺利结束之后,才会置位CTR标志,触发中断进入CTR_LP()。
- 调用Setup0_Process()的时候,当前SETUP事务已经结束了;
- 调用In0_Process()的时候,当前IN事务已经结束了;
- 调用Out0_Process()的时候,当前OUT事务已经结束了;

1. 控制传输的设置阶段(SETUP事务):
   设备硬件同意接收令牌包,接着把request数据存放到设备缓冲区之后,会自动发送ACK握手包给主机,整个设置阶段结束,此时才置位CTR触发中断。这个过程全部由硬件完成,软件不参与。
   后续的Setup0_Process()是为下阶段的数据接收或者发送做好准备,该函数执行期间USB总线上不发生包的传递。
2. 控制传输的可选数据阶段:
   - 如果是IN事务(比如Get Descritpor控制传输的数据阶段):
   在第一阶段的Setup0_Process()期间,设备的数据已经在缓冲区里面等待发送了。设备一旦收到主机的IN令牌包,数据立刻被设备上的硬件(SIE)发送给主机;主机收到数据,立刻回复ACK握手包给设备。整个过程全部由硬件处理。设备收到ACK握手包之后,CTR置位触发中断,接着调用In0_Process()。
   In0_Process()执行期间,USB总线上不发生任何数据的传递。如果后续还有数据需要发送给主机,In0_Process()就把数据搬到待发送区等待下一个IN令牌包的到来;如果后续没有数据需要发送给主机,In0_Process()就进入WAIT_STATUS_OUT状态,此后等待控制传输的第三阶段(状态阶段)。
   - 如果是OUT事务:
3. 控制传输的状态阶段:
   - 如果是不带数据阶段的控制传输(比如Set Address控制传输的状态阶段):
   在第一阶段的Setup0_Process()期间调用NoData_Setup()进入WAIT_STATUS_IN状态,并且在待发送区准备好了一个空包准备发送给主机。
   当状态阶段的IN令牌包一到,该空包就被发送给主机;主机再回复一个ACK握手包给设备。这个过程是硬件自动完成的,设备收到ACK握手包,就会置位CTR标志触发中断。后续会调用In0_Process(),并且执行WAIT_STATUS_IN状态下的代码,完成配置设备地址等操作,进入STALLED状态。最后Post0_Process()释放USB总线,并且把状态切换为PAUSE(空闲暂停),到此整个控制传输结束。
   - 如果是设备往主机发数据的控制传输(比如Get Descriptor控制传输的状态阶段):
   主机会发送一个OUT包和一个空数数包给设备说明第二阶段(数据阶段)的数据已经全部接收,设备收到这两个包之后,立刻回复一个ACK包给主机,状态阶段结束。这个过程是由硬件完成的,此后CTR标志置位触发中断,进入Out0_Process()。
   在第二阶段In0_Process()已经进入WAIT_STATUS_OUT状态,所以Out0_Process()执行WAIT_STATUS_OUT状态下的代码,通常啥也不做。最后调用Post0_Process(),释放USB总线,并且把状态切换为PAUSE(空闲暂停),到此整个控制传输结束。

枚举过程里面的控制传输都可以用上面的话来解释:
Get Descriptor
Set Address
Set Config
Set Interface

使用特权

评论回复
地板
airwill| | 2013-8-23 12:11 | 只看该作者
看样子大体看通了. 是需要先看看协议部分的.
进步很快哦, 加油.

使用特权

评论回复
5
yan2005|  楼主 | 2013-8-23 12:39 | 只看该作者
呵呵,大家一起加油!

使用特权

评论回复
6
beanandpeach| | 2013-8-23 15:35 | 只看该作者
加油了

使用特权

评论回复
7
543049411| | 2014-3-14 22:03 | 只看该作者
airwill 发表于 2013-8-23 12:11
看样子大体看通了. 是需要先看看协议部分的.
进步很快哦, 加油.

版主,你确定他这样对吗?调用Setup0_Process()的时候,当前SETUP事务已经结束了;
我在百度上看到一个人的博客,上有把主机的setup包后的数据打印出来,他就是在Setup0_Process()中间加了个return,然后就有看到主机有多次的setup数据发来,最后再挂起,这样子跟这个说法完全不同。麻烦解答一下

使用特权

评论回复
8
543049411| | 2014-3-14 22:07 | 只看该作者
yan2005 发表于 2013-8-23 09:43
原先理解有点问题,晚上重新看了遍,现在感觉基本上能自圆其说了。

控制传输由设置阶段(SETUP事务), 可选 ...

你确定这样对吗?调用Setup0_Process()的时候,当前SETUP事务已经结束了;
我在百度上看到一个人的博客,上有把主机的setup包后的数据打印出来,他就是在Setup0_Process()中间加了个return,然后就有看到主机有多次的setup数据发来,最后再挂起,这样子跟这个说法完全不同。麻烦解答一下

使用特权

评论回复
9
airwill| | 2014-3-15 07:12 | 只看该作者
543049411 发表于 2014-3-14 22:03
版主,你确定他这样对吗?调用Setup0_Process()的时候,当前SETUP事务已经结束了;
我在百度上看到一个人 ...

这位朋友看得很仔细, 问得很好.
他这么处理, 我起码应该也做个测试验证才能做出评论.
等我找个时间也验证和分析一下, 再来回复你, 谢谢!

使用特权

评论回复
10
一清如水| | 2014-3-15 08:45 | 只看该作者
占位,再学习

使用特权

评论回复
11
543049411| | 2014-3-15 14:38 | 只看该作者
airwill 发表于 2014-3-15 07:12
这位朋友看得很仔细, 问得很好.
他这么处理, 我起码应该也做个测试验证才能做出评论.
等我找个时间也验 ...

非常感谢版主百忙中抽空回复我的消息。我发这个疑问,不是要来质疑您啦,我看了这个帖子,然后又看了另一份博文,之间有矛盾就产生疑问了。再麻烦您百忙之中再抽个时间帮我看看。
非常感谢~!

使用特权

评论回复
12
yan2005|  楼主 | 2014-3-18 08:32 | 只看该作者
543049411 发表于 2014-3-14 22:07
你确定这样对吗?调用Setup0_Process()的时候,当前SETUP事务已经结束了;
我在百度上看到一个人的博客, ...

两者完全不同,过程并不矛盾。

前面的贴里面已经说过了。控制传输分成三个阶段。调用Setup0_Process()的时候,是第一阶段结束了。Setup0_Process()里面的代码要做好第二阶段的数据收发准备。如果在Setup0_Process()里面直接加return, 那么猜测是没有做好数据的收发准备,于是第二阶段的数据传输被NAK。接着主机协议栈重新发起控制传输,于是就又看到几个setup包过来。这些后面的setup包和前面的第一个包不是在同一次传输里面的。

以上注意传输和事务的差别。只能说这么细了。

使用特权

评论回复
13
香水城| | 2014-3-18 17:28 | 只看该作者
LS看的很清楚啊!

下面这张图,诶,懂的立马懂;不懂的,看一看容易帮助理解USB device库的流程。

以带数据阶段(且是主机读取数据)的控制传输为例,比如Get Descriptor这个transfer(LS说的传输)为例:



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:Activist > thinker  与大家一起进步

47

主题

302

帖子

1

粉丝