1.包的四种类型
根据包的组成把包分为四种类型,分别是、帧首包SOF(Start of Frame)、命令包(Token)、数据包(Data)、握手包(Handshake),如下图(大家一定要把PID类型和包类型分开)。
4种PID类型和4种包类型(按照组成分类)的区别如下,大家注意区分。
2.SOF包组成
我们今天看SOF包的详细结构。SOF包由USB主机控制器以全速总线的标称速率每1.00 ms±0.0005 ms发出一次,对于高速总线则为125μs±0.0625μs。SOF数据包由PID域+帧号域+5bit CRC域,下图为SOF包各个域和抓包协议的对应图。
3.SOF包发送时间及USB总线包结构
SOF包的发送时间和USB总线的包数据结构大家可以看下图。
(1)SOF包的发送时间
(2)USB总线包组成
4.SOF包其它核心概念
所有高速和全速功能(包括集线器)都接收SOF数据包。SOF包不会引起任何功能生成应答包,因此,无法保证所有的功能都能收到SOF包。
SOF包由两个作用。第一个作用是当一个功能检测到SOF包后,就知道USB主机控制器开始启动一个帧(微帧)了。第二个作用为帧时间敏感功能,讲的通俗一点就是时标功能, 每一个设备功能可以接收SOF包,通过Frame域来判断当前的时间走到哪里了。不需要跟踪帧号(例如,全速操作集线器)的设备功能则只需要解码SOF包的PID,可以忽略帧号域及其CRC域。
5.STM32 SOF包处理机制
STM32的对SOF包的处理代码如下。ISTR_SOF中断位 指示一个新的USB帧的开始,它是在SOF数据包通过USB总线到达时设置的。中断服务例程可以监视SOF事件,使其具有到USB主机的1 ms同步事件,并安全地读取在SOF数据包接收处更新的USB_FNR(USB frame number register),当发生SOF中断时,我们可以读取USB_FNR寄存器来判断帧号并且计算出当前时间或者做其他事情。
//读出的中断标志是SOF中断标志,且SOF中断使能了
if (wIstr & ISTR_SOF & wInterrupt_Mask){//清除SOF中断标志_SetISTR((uint16_t)CLR_SOF);//统计共接收到多少SOFbIntPackSOF++; //当定义了SOF_CALLBACK,则调用SOF_Callback,//像钩子函数一样,在发生SOF中断时做点什么
#ifdef SOF_CALLBACKSOF_Callback();
#endif
}