基于STM32处理器的两种USB通信方法的实现
- 格式:pdf
- 大小:315.85 KB
- 文档页数:3
○IT 论坛○
SCIENCE & TECHNOLOGY INFORMATION
2010 年 第 21 期
基于 STM32 处理器的两种 USB 通信方法的实现
方旭 (重庆通信学院计算机教研பைடு நூலகம் 中国 重庆 400035)
【摘 要】本文通过解 析 USB 通 信 协 议 及 其 CDC (Communications Device Class) USB 标 准 设 备 类 ,在 意 法 半 导 体 推 出 的 基 于 ARM 公 司 的 Cortex-M 架构设计的 STM32 处理器上设计了一套基于 CDC 标准设备类的 USB 通信协议, 然后在 PC 主机上利用微软提供的 usbser.sys 驱动程序,自己编写了一个 stmcdc.inf 文件,实现了 STM32 处理器和 PC 主机的基于 CDC 标准设备类的通信。 随后又在 STM32 处理器上设计 了一个基于自己通信特点的半双工 bulk 通信,在 PC 主机上开发了一个 Windows 驱动程序 dwusb.sys,并编写了一个 dwusb.inf 文件,最终实现 了基于自己通信特点的 USB 通信协议的实现。
不论是在进行 CDC 标准设备类的设计实现还是后来进行的根据 自己的通信特点设计的设备类,都是采用了分层的设计架构,这样便 于程序的移植开发,因为底层的硬件都是一样的,所以在这两个设备 类上开发时底层的程序即硬件抽象层程序不需要改变,只是应用层的 程序根据具体的功能来实现了一些具体的函数改变了一些特性,所以 在两个设备类进行软件设计时改动并不是很大,基本结构框如图 1 所 示。
图 4 用户层程序流程图
如图 4 所示,在该层上使用了 Win32 控制平 台 进 行 的 开 发 ,很 好
图 2 在 PC 主机上的 USB 驱动程序结构
USB 设 备 所 采 用 的 驱 动 程 序 是 一 种 典 型 的 WDM 驱 动 程 序 。 在 WDM 驱动程序中,即插即用(PnP)管理器负责通知 操 作 系 统 何 时 添 加 (或删除)设备,并使用 INF 文件来查找新设备的驱动程序。 驱动程序基 本组成结构如图 2 所示,包括以下部分:
本 文 针 对 意 法 半 导 体 推 出 的 STM32 处 理 器 上 设 计 了 它 与 PC 主 机的 USB 通信协议, 先利用 CDC 标准设备类进行了 USB 通信实验。 在开发完基于 CDC 标准设备类的程序后, 考虑到往往设备通信过程 中可能会遇见一些别的通信特点,比如在传输大量数据过程既想有时 能传输大量数据可以不考虑准确性, 又想可以传输准确性高的数据, 这两个通信特点在现有的通信设备类中没有支持的,这就需要根据自 己的特点来开发上位驱动程序,因此在此基础上自己开发了一个简单 的半双工 bulk 通信特点的 USB 通信, 在此基础上可以进行进一步的 扩充和缩减。 1 STM32 处理器上 USB 协议设计与实现
图 1 软件结构图 USB 的库被分成了两层: USB 库核心层: 直接和 USB 的硬件进行通信, 并且兼容 USB2.0 的规范,是从 STM32F 固件库中分离出来的库。 应用程序接口层: 为用户应用程序提供和 底 层 的 USB 库 核 心 进
行交互的接口。 1.1 系统中定义源文件详细说明 1.1.1 核心模块
2 PC 主机上的 USB 协议设计与实现
在 PC 进行 CDC 标准设备类的软件设计时因为是标准的设备类 , 所以微软提供了 usbser.sys 驱动程序来跟从硬件设备进行通信, 只需 要进行 INF 文件的编写,以便 PC 主机识别 底 层 设 备 并 正 确 的 给 他 加 载相应驱动程序, 而在根据自己的特点设计 USB 通信时 则 需 要 自 己 编写驱动程序来识别自己的设备,因此在此简单的介绍一下根据自己 的通信特点在 PC 上的驱动程序的软件结构以及用户层的软件结构。
【关键词】USB;STM32 处理器;CDC
0 引言 在现在的电力系统中,电表的数据传输还是依靠传统的 485 总线
的方式进行传输, 这种传统的通信方式因为其开发简单而被广泛使 用,但慢慢的其弊端就暴露出来。 而 USB 规定了统一的接口 标 准 ,挂 载设备数目多,通信速度快。 因此,在现在的电力采集系统中有很广泛 的应用前景。
589
2010 年 第 21 期
SCIENCE & TECHNOLOGY INFORMATION
○IT 论坛○
科技信息
4)usb_prop (.c , .h) usb_prop 模 块 用 来 定 义 在 usb_core 模 块 中 各 个 标 准 响 应 函 数 用 到的数据结构如 Device_Propety、USER_STANDARD_REQUEST 等。 5)usb_pwr (.c , .h) 这个模块用于管理 USB 设备的电源问题。 总共编写了四个函数: (1 )Power_on() : 在 设 备 电 源 打 开 时 进 行 的 相 应 中 断 处 理 (2 )Power_off() : 在 设 备 电 源 关 闭 时 进 行 的 相 应 中 断 处 理 (3 )Suspend() : 在 设 备 挂 起 时 进 行 的 相 应 中 断 处 理 (4 )Resume() : 在 设 备 唤 醒 时 进 行 的 相 应 中 断 处 理 6)usb_desc (.c, .h) 这个文件中包含了所有的 USB 描述符, 根据我 的 设 备 特 点 定 义 了所有的设备描述符。 1.2 USB 设备请求 设备请求是在 SETUP 事务的数据阶段传送的, 不论是标准设备 请求还是各种自定义请求,它们都只能使用控制管道来进行传输。 当 USB 设备在控制传输的 SETUP 事务中返回 ACK 握手包后 ,它 就 可 以 开始处理这些请求所指定的操作了, 且必须在状态结束之前完成 (SET_ADDRESS 请求例外,它是在状态阶段结束之后才改变其设备地 址的)。 但有些请求所需的设备操作费时较多,而不能由状态阶段来标 识 结 束 ,这 时 USB 需 另 外 定 义 一 种 方 法 ,如 SET_PROT_FEATURE 请 求产生的复位操作要持续 10ms 才能完成, 而当集线器端口复位刚刚 开始时,其状态阶段就结束了,这时集线器使用端口状态的改变(端口 被使能)来标识该复位操作的完成。 当 USB 设备接收到这些控制请求后,应及时做出处理。 对于不需 要数据阶段的 控 制 请 求 ,USB 设 备 必 须 在 接 收 到 该 请 求 后 的 50ms 内 完成其指定的操作并结束该控制传输的状态阶段。 对于需要向主机返 回数据的控制请求(即包含 IN 数据阶段),USB 设备必须在接收到该请 求后的 500ms 内返回第一个数据包,之后的数据包必须在其前一数据 包传输结束后的 500ms 内返回, 且 USB 设备必须在其返回最后一 个 数据包后的 50ms 内完成该控制传输的状态阶段。 对于需要向 USB 设 备 发 送 数 据 的 控 制 请 求(即 包 含 OUT 数 据 阶 段),它 们 必 须 在 5s 内 完 成所有的传输,包括 USB 设备接收到主机发出的全部数据包,并 完 成 该控制传输的状态阶段。 另外,某些设备类定义请求和供应商自定义 请求也可不遵循上述完成时间的限制。 当 USB 设备接收到无效的或其不支持的控制请 求 时 , 它 会 对 该 事务处理的数据阶段和状态阶段返回 STALL 握手包, 该错误 状 态 会 在其接收到新的 SETUP 令牌包时自动恢复,这属于“协议 STALL”。 但 如果出现某种错误, 而导致 USB 设备不能使用缺省控制 管 道 与 主 机 进行通信时,该设备必须被复位才能清除其错误状态。
驱动程序的入口和卸载管理:处理驱动程序的初始化和释放以前 占用的系统资源。
即插即用管理:处理 PnP 设备的添加、删除和停止。 读写文件管理:处理用户程序和系统内核发出的各种 I/O 请求; 电源管理:处理电源管理请求。 系 统 消 息 管 理 :WMI(Windows Management Instrumentation), 它 是 一种系统管理员报告管理信息的协议,这个协议能测量和管理消耗在 本地客户机上的资源信息。 2.1 USB 驱动程序软件流程设计
1)usb_type.h 这个文件定义了库中主要使用的数据类型,这些数据类型依赖于 所使用的处理器。 2)usb_reg(.c, .h) usb_regs 模块实现了硬件的抽象层 ,该 文 件 以 宏 定 义 的 方 式 提 供 了 USB 硬件内部各个功能模块的基地址和偏移量。 3)usb_int (.c , .h) usb_int 模 块 提 供 了 当 有 正 确 的 数 据 传 输 过 来 时 的 中 断 处 理 例 程,该模块提供了最终的中断处理代码。 4)usb_core (.c , .h) usb_core 模块是编写的这个库的核心,实现了 所 有 的 功 能 请 求 的 函数。 (1)GET_STATUS 请求用于主机读取设备、接口或端点的状态。 (2)CLEAR_FEATURE 请求用于清除或禁止设备、 接口或端点的 某些特性。 该请求无数据阶段。 (3)SET_FEATURE 请 求 用 于 设 置 或 使 能 设 备 、 接 口 或 端 点 的 某 些特性,它与 CLEAR_FEATURE 请求相对应。 该请求无数据阶段。 (4)SET_ADDRESS 请求用于为 USB 设备分配一个唯一的 设 备 地 址。 (5)GET_DESCRIPTOR 请求用于主机读取指定的描述符。 GET_DESCRIPTOR 请求仅支持三种类型的描述符:设 备 描 述 符 、 配置描述符和字符串描述符。 (6)SET_DESCRIPTOR 请 求 用 于 更 新 USB 设 备 已 有 的 描 述 符 或 向其添加新的描述符。 (7)GET_CONFIGURATION 请 求 用 于 主 机 读 取 USB 设 备 当 前 的 配置值。 (8)SET_CONFIGURATION 请 求 用 于 为 USB 设 备 选 择 一 个 合 适 的配置。 (9)GET_INTERFACE 请求用于主机 读 取 指 定 接 口 的 当 前 可 替 换 设置值,即其接口描述符中 bAlternateSetting 字段的值。 (10)SET_INTERFACE 请求用于为指定接口选择一个合适的可替 换设置。 1.1.2 应用程序接口模块 1)usb_istr(.c) 在 usb_istr 模 块 编 写 了 一 个 函 数 USB_Istr(),用 来 从 宏 观 上 处 理 中断,判断是哪种中断类型,然后调用相应的中断处理函数。 2)usb_conf(.h) usb_conf.h 文件是用来定义 BTABLE(USB 通信过程中用于发送数 据的缓冲表)和所有节点在 PMA 中的地址;并且在这个文 件 中 定 义 了 中断掩码来规定哪些中断可以开启那些中断关闭。 3)usb_endp (.c) usb_endp 模 块 定 义 了 除 端 点 0 (EP0)以 外 的 所 有 其 余 7 个 端 点 的中断回调函数,这个函数对应的是在有数据正确传输时产生的中断 对应的处理。