个人成就
- 发布了50篇内容
- 获得了4次赞同
- 获得了3次收藏
个人简介
擅长领域
暂时没有设置哦~
-
USB之数据包和握手包
前面的文章我们一起了解了USB的包结构以及令牌包,今天我们来说说USB的数据包和握手包.
顾名思义,数据包就是用来传输数据的,在USB1.1协议中,只有两种数据包:DATA0包和DATA1包。在USB2.中又增加了DATA2和 MDATA包,主要用在高速分裂事务和高速高带宽同步传输中。
数据包都具有同样的结构:一个同步域,后面跟整数字节的数据,然后是CRC16校验,最后是包结束符EOP,如图1所示。
图1
之所以有不同类型的数据包,是用在当握手包出错时纠错.下面以DATA0包和DATA1包的切换为例进行具体的解释。
主机和设备都会维护自己的一个数据包类型切换机制:当数据包成功发送或者接收时,数据包类型切换。当检测到对方所使用的数据包类型不对时,USB系统认为这发生了一个错误,并试图从错误中恢复。数据包类型不匹配主要发生在握手包被损坏的情形。当一端已经正确接收到数据并返回确认信号时,确认信号却在传输过程中被损坏。这时另一端就无法知道刚刚发送的数据是否已经成功,这时它只好保持自己的数据包的类型不变。如果对方下一次使用的数据包类型跟自己的不一致,则说明它刚刚已经成功接收到数据包了(因为它已经做了数据包切换,只有正确接收才会如此);如果对方下一次使用的数据包类型跟自己的一致,则说明对方没有切换数据包类型,也就是说,刚刚的数据包没有发送成功,这是上一次的重试操作。
握手包有ACK、NAK、 STALL和NYET。ACK表示正确接收数据,并且有足够的空间来容纳数据。主机和设备都可以用ACK来确认,而NAK、 STALL、NYET只有设备能够返回,主机不能使用这些握手包。
图2
>NAK表示没有数据需要返回,或者数据正确接收但是没有足够的空间来容纳它们。当主机收到NAK时,知道设备还未准备好,主机会在以后合适的时机进行重试传输。
> STALL表示设备无法执行这个请求,或者端点已经被挂起了,它表示一种错误的状态。设备返回 STLSTALL后,需要主机进行干预才能解除这种状态。
>NYET只在USB2.0的高速设备输出事务中使用,它表示设备本次数据成功接收,但是没有足够的空间来接收下一次数据。主机在下一次输出数据时,将先使用PING令牌包来试探设备是否有空间接收数据,以避免不必要的带宽浪费。
需要注意的是,返回NAK并不表示数据出错,只是说明设备暂时没有数据传输或者暂时没有能力接收数据。当USB主机或者设备检测到数据出错时(如CRC校验错、PID校验错、位填充错等),将什么都不返回。这时等待接收握手包的一方就会收不到握手包从而等待超时。
以上就是数据包和握手包的内容,你明白了吗?
-
USB令牌包
上一篇文章我们介绍了数据包的结构以及传输过程,提到了令牌、数据、握手、特殊等等专业的名词,后面的文章我们来一个一个详细介绍一下他们,今天我们先来介绍令牌包。
令牌包用来启动一次USB传输。因为USB是主从结构的拓扑结构,所以所有的数据传输都是由主机发起的,设备只能被动地接听数据(唯一的例外是支持远程唤醒的设备能够主动改变总线的状态让集线器感知到设备的唤醒信号,但是这个过程并不传送数据,只是改变一下总线的状态)。这就需要主机发送一个令牌来通知哪个设备进行响应,如何响应。
令牌包有4种,分别为输出(OUT)、输入(In)、建立(SETUP)和帧起始(sOF Start Of Frame).
>输出令牌包用来通知设备将要输出一个数据包。
>输入令牌包用来通知设备返回一个数据包。
>建立令牌包只用在控制传输中,它跟输出令牌包的作用一样,也是通知设备将要输出一个数据包,两者的区别在于: SETUP令牌包后只使用DATA0数据包,且只能发到设备的控制端点,并且设备必须要接收,而OUT令牌包没有这些限制。
>帧起始包在每帧(或微)开始时发送,它以广播的形式发送,所有USB全速设备和高速设备都可以接收到SOF包。USB全速设备每毫秒产生一个帧,而高速设备每125s产生一个微帧USB主机会对当前帧号进行计数,在每次帧开始时(或者微帧开始时,每毫秒有8个微帧,这8个微帧的帧号是一样的,即相同的SOF)通过SOF包发送帧号。SOF中的帧号是11位的。在4个令牌包中,只有SOF令牌包之后不跟随数据传输,其他的都有数据传输图1.9.2是SOF令牌包的结构。
每个令牌包,最后都有一个CRC5的校验,它只校验PID之后的数据,不包括PID本身,因为PID本身已经有4个取反的位进行校验了。
图1 SOF令牌包的结构图
图1.9.3是OUT、IN、 SETUP令牌包的结构。它们具有同样的结构:同步域、包标识域、地址域、端点域、CRC5校验域和包结束。其中,地址域是要访问的设备的地址,端点域是要访问的端点号(还记得前面说过的教学楼模型吗?回忆一下地址和端点的概念);CRC5校验只计算PID之后的地址域和端点域,而不包括PID。前面说过,数据在总线上传输时,每个域的LSB在前,请记住这一点。例如,7位地址在总线上传输的先后就是A0、A1、A2、A3、A4、A5、A6。
图2 OUT IN SETUP令牌包结构图
上面就是令牌包的全部介绍了,大家对令牌包有一个认识了吗?
-
存储器保护单元
MPU也就是我们通常说的存储器保护单元,它可以为微控制器或片上系统(SOC)提供存储器保护特性,而且会提高所开发产品的健壮性。MPU在使用前需要进行编程使能,若MPU未使能,存储器系统的行为同没有MPU时一样。当然有的支持MPU特性,有的没有。
MPU是一种可编程的部件,用于定义不同存储器区域的存储器访问权限(如只支持特权访问或全访问)和存储器属性(如可缓冲、可缓存)。
MPU可以通过以下方面提高嵌入式系统的健壮性:
l 避免应用任务破坏其他任务或OS内核使用的栈或数据存储器。
l 避免非特权任务访问对系统可靠性和安全性很重要的外设。
l 将SRAM或RAM空间定义为不可执行的,防止代码注入攻击。
l 检测不可预期的存储器访问(例如,栈被破坏)。
还可以利用MPU定义其他存储器属性,如可被输出到系统缓存单元或存储器控制器的可缓存性。
若存储器访问和MPU定义的访问权限冲突,或者访问的存储器位置未在已编程的MPU区域中定义,则传输会被阻止且触发一次错误异常。触发的错误异常处理可以是存储器管理错误或者HardFault异常,实际情况取决于当前的优先级及存储器管理错误是否使能。然后异常处理就可以确定系统是否应该复位或只是OS环境中的攻击任务。
在使用MPU前需要对其进行设置和使能,若未使能MPU,处理器会认为MPU不存在。若MPU区域可以出现重叠,且同一个存储器位置落在两个MPU区域中,则存储器访问属性和权限会基于编号最大的那个区域。例如,若某传输的地址位于区域1和区域4定义的地址范围内,则会使用区域4的设置。
MPU的设置方法有多种。
对于没有嵌入式OS的系统,MPU可以被编程为静态配置。该配置可用于以下功能:
l 将RAM/SRAM区域设置为只读,避免重要数据被意外破坏。
l 将栈底部的一部分RAM/SRAM空间设置为不可访问的,以检测栈溢出。
l 将RAM/SRAM区域设置为XN,避免代码注入攻击。
l 定义可被系统级缓存(2级)或存储器控制器使用的存储属性配置。
对于具有嵌入式OS的系统,在每次上下文切换时都可以配置MPU,每个应用任务都有不同的MPU配置。这样可以:
l 定义存储器访问权限,使得应用任务只能访问分配给自己的栈空间,因此可以避免因为栈泄漏而破坏其栈。
l 定义存储器访问权限,使得应用任务只能访问有限的外设。
l 定义存储器访问权限,使得应用任务只能访问自己的数据或自己的程序数据(设置起来可能会有麻烦,因为多数情况下OS和程序代码是一起编译的,因此数据在存储器映射中也可能是混在一起的。)
如果需要的话,具有嵌入式OS的系统还可以使用静态配置。
简单应用大多不需要使用MPU,MPU默认为禁止状态,而且系统运行时它就如同不存在一样。在使用MPU前,需要确定程序或应用任务要访问(以及允许访问)的存储器区域:
l 包括中断处理和OS内核在内的特权应用的程序代码,一般只支持特权访问。
l 包括中断处理和OS内核在内的特权应用使用的数据存储器,一般只支持特权访问。
l 非特权应用的程序代码,全访问。
l 非特权应用(应用任务)的栈等数据存储器,全访问。
l 包括中断处理和OS内核在内的特权应用使用的外设,只支持特权访问。
l 可用于非特权应用(应用任务)的外设,全访问。
在定义存储器区域的地址和大小时,注意区域的基地址必须要对齐到区域大小的整数倍上。例如,若区域大小为4KB(0x1000),起始地址必须为N X 0x1000,其中N为整数。
若使用MPU的目的是防止非特权任务访问特定的存储器区域,则可以利用背景区域特性减少所需的设置步骤。只需设置非特权任务所用的区域,而利用背景区域,特权任务和异常处理则对其他存储器空间具有全访问权限。
-
快速应用张飞单片机之通用定时器
定时器是单片机重要功能模块之一,在检测、控制领域有广泛应用。所以基本在用到单片机基本都会用到定时器的部分,为了大家快速应用张飞单片机,节省时间去开发应用部分,所以我们要检索重要信息,实现我们的目的。
定时器常用作定时时钟,以实现定时检测、定时响应、定时控制。并且可用于产生ms的脉宽信号驱动电机。定时和计数功能最终都是通过计数实现的,若计数的事件源是周期固定的脉冲,那么可以实现定时功能,否则只能实现计数功能。
实现定时/计数的方法一般有:软件定时、专用硬件电路和可编程定时器/计数器三种方法。
软件定时:执行一个循环程序进行时间延迟。定时基本准确,不需要外加硬件电路,但增加CPU开销。
专用硬件电路定时:可实现精确的定时和计数,但参数调节不方便。
可编程定时器/计数器:不占用CPU时间,能与CPU并行工作,实现精确的定时和计数,又可以通过编辑设置其工作方式和其他参数,所以使用还是很方便的。
定时器的基本工作原理是:利用计数器对固定周期的脉冲计数,通过寄存器的溢出来触发中断。
使用定时器时主要有两种方法:
1、使用定时中断技术,计时溢出时触发中断,预先设计的中断子程序将被自动调用
2、使用查询法检查是否出现计时溢出,溢出时执行指定代码
通常我们用到是第一种方法,计数溢出产生中断。
那么对于定时器有很多种功能,也就是做出不同的配置可以实现。
比如计数器模式,输入捕获模式,PWM模式,单脉冲模式等可以通过实际需求做出配置实现这些功能。
我们以常用的几个功能模式为例来说一下如何快速用库函数实现配置,配置要点都有哪些。
1、定时中断模式
时钟选择需要配置预分频寄存器;周期(其实是计数值)需要配置自动装载寄存器;计数模式需要配置,比如向上计数或者向下计数;对齐模式需要配置,比如边沿对齐或者中央对齐。再更新使能,使能中断和定时器就可以实现定时中断功能,这个是最常用的,最基本的。
应用最广,比如延时,定时时钟,定时响应,定时控制等。
2、输入捕获模式
输入捕获需要配置捕获通道,捕获沿,捕获输入源选择,滤波配置。
配置好可以通过中断方式实现捕获,捕获可以改变捕获沿,这样可以根据需求捕获,比如不改变沿就可以捕获到一个周期的值,改变沿的捕获可以对脉宽进行捕获。
应用广泛,常用于测量脉冲宽度、周期等
3、PWM模式
PWM输出模式需要配置有PWM工作模式(强制拉高,强制拉低,PWM两种模式),对齐模式(中央对齐,边沿对齐),输出极性,分频系数,周期(计数值),占空比配置。
还有比如重装载使能,分频计数规则,这些其实都需要去看,对于上面这些功能而言,一个定时器都有几个通道可以实现,各个通道可以实现不同的占空比,对于一个定时器可以实现不同占空比的PWM。
对于PWM模式来说,应用也很广泛,比如心跳灯,电压输出,电机调速等。
对于单片机模块快速应用要结合手册和示例程序可以事半功倍,一定要先清楚自己的需求,再去看库函数如何调用可以让自己快速实现自己的应用。单片机底层驱动起来是基本的应用,然后才能更好的去服务上层应用。调试也是很重要的方面,不清楚的地方除了查手册最快的方式还是调试,可以快速解惑。
如果大家还有什么疑问或者目前有其他模块想快速应用起来,可以联系我们的器件部门,下面是我们器件部门的二维码,企业部门也可以免费申领资料。
-
USB的四种传输类型之批量传输
虽然USB定义数据在总线上传输的基本单位是包,但是我们还不能随意地使用包来传输数据.必须按照一定的关系把这些不同的包组织成事务才能传输数据.
那什么是事务呢?事务通常由两个或者三个包组成:令牌包,数据包和握手包.令牌包用来启动一个事务,总是由主机发送;数据包传送数据,可以从主机到设备,也可以是从设备到主机,方向由令牌包来指定;握手包的发送者通常为数据接收者,当数据接收正确后,发送握手.设备也可以使用NAK握手包来表示数据还未准备好.
USB协议规定了4中传输类型:批量传输,等时传输,中断传输和控制传输.其中,批量传输,等时传输,中断传输每次传输一次数据都是一个事务;控制传输包括三个过程,建立过程和状态过程分别是一个事务,数据过程则可能包含多个事务.下面我们先来说说批量传输.
批量传输是最容易理解的,它使用批量事务传输数据.一次批量事务有三个阶段:令牌包阶段,数据包阶段和握手包阶段.这里的每个阶段都是一个独立的包.批量传输分为批量读和批量写(记住,输入还是输出是以主机为参考的),批量读使用批量输入事务,批量写使用批量输出事务.
批量传输没有规定数据包中的数据的意义和结构,具体的数据结构要由设备自己定义.批量传输通常用在数据量大,对数据的实时性要求不高的场合,例如USB打印机,扫描仪,大容量存储设备等.
首先介绍批量输出事务。主机先发出一个OUT令牌包,这个令牌包中包含了设备地址、端点号。然后,再发送一个DATA包(具体是什么类型的DATA包,要看数据切换位),这时地址和端点匹配的设备就会收下这个数据包。然后主机切换到接收模式,等待设备返回握手包。设备解码令牌包、数据包都准确无误,并且有足够的缓冲区来保存数据后,就会使用ACK握手包或者NYET握手包来应答主机(只有高速模式才有NYET握手包,它表示本次数据成功接收,但是没有能力接收下一次传输)。如果没有足够的缓冲区来保存数据,那么它就会返回一个NAK握手包,告诉主机目前没有缓冲区可用,主机会在稍后的时间重试该批量输出事务。如果设备检测到数据正确,但是端点处于挂起状态,返回一个 STALL握手包。如果设备检测到有错误(例如校验错误位填充错误等),则不做任何响应,让主机等待超时再来看看批量输入事务。主机首先发出一个IN令牌包,同样IN令牌包中包含了设备地址和端点号然后主机切换到接收数据状态,等待设备返回数据如果设备检测到错误,那么不做任何响应,主机等待超时如果此时有地址和端点匹配的设备,并且没有检测到错误,则该设备要做出响应:如果设备有数据需要返回,那么它把一个数据包放到总线上(具体的数据包类型要看数据切换位);如果设备没有数据需要返回,则它直接使用NAK握手包来响应主机;如果该端点处于挂起状态,设备会返回一个 STALL握手包。如果主机接收到设备发送的数据包并解码正确后,使用ACK握手包应答设备。如果主机检测到错误,则不做任何响应,设备会检测到超时USB协议规定,不允许主机使用NAK握手包来拒绝接收数据包(否则的话,设备会在下面想:你真是USB”啊!既然你没空间接收数据,你还请求我返回数据给你干啥!浪费表情……)主机在收到NAK握手包后,知道设备暂时无数据返回,主机会在稍后的时间里重试该输入事务。另外,在USB2.0高速设备中增加了一个ING令牌包,它不发出数据,直接等待设备的握手包。因此PING事务只有令牌包和握手包。图1.10.1是一个批量事务的流程图。下面对该流程图进行简单地解释,后面几种事务的流程图表示方法是差不多的,就不再一一解释了.
平时无数据传输时,总线处于空闲状态。当需要传输一次事务时,主机发送一个令牌包,它可以是OUT令牌包、IN令牌包或者是PING令牌包,如图1.10.1中第一行所示,其中PING令牌包是USB2.0高速模式输出特有的,全速模式和低速模式没有这个令牌包如果设备解码令牌包时出错,则直接进入空闲状态。令牌阶段之后是数据阶段或者握手阶段对于批量输入事务,则由设备返回数据,或者返回应答包NAK握手包或 STALL握手包。这由设备的状态来决定对于批量输出事务,则主机在令牌包后面再发送一个数据包PING令牌用来探测设备是否有空间接收数据,它没有数据阶段,只有握手阶段,设备根据实际的情况返回握手包,AK握手包表示有空间接收数据,NAK握手包表示无空间接收, STALL握手包表示端点挂起。最后是握手阶段。对于批量输入事务,如果主机接收设备返回的数据正确,则由主机返回ACK握手包;否则数据错误,主机什么也不返回。主机必须要能够接收数据,不能用NAK握手包回应设备。对于批量输出事务,如果设备能够接收数据,则返回ACK握手包;如果设备没有空间接收数据包,则返回NAK握手包;如果设备端点挂起,则返回 STALL握手包;如果设备检测到传输错误,则什么都不回应,直接进入到空闲状态图1.10.2和图1.10.3更详细地给出一个传输正确的批量输入事务和批量输出事务的数据包图(传送了2字节数据)
今天我们就先介绍这么多,你get到了吗?