第 2 章 - Azure RTOS USBX 设备堆栈安装

主机注意事项

计算机类型

嵌入式开发通常在 Windows PC 或 Unix 主机计算机上执行。 在对应用程序进行编译和链接并将其放置在主机上之后,应用程序将下载到目标硬件进行执行。

下载接口

虽然并行接口、USB 接口和以太网接口变得越来越普遍,但目标下载通常通过 RS-232 串行接口进行。 有关可用选项,请参阅开发工具文档。

调试工具

通常通过与程序映像下载相同的链接进行调试。 存在多种调试器,包括在目标上运行的小型监视器程序、后台调试监视器 (BDM) 和在线仿真器 (ICE) 工具等。 ICE 工具提供最可靠的实际目标硬件调试。

所需的硬盘空间

USBX 的源代码以 ASCII 格式提供,并要求主计算机的硬盘具有约 500 KB 可用空间。

目标注意事项

USBX 要求处于主机模式的目标具有 24 KB 到 64 KB 只读内存 (ROM)。 所需的内存量取决于所使用的控制器类型和链接到 USBX 的 USB 类。 USBX 全局数据结构和内存池要求目标具有额外的 32 KB 随机存取内存 (RAM)。 还可以根据 USB 接口上预期连接的设备数和 USB 控制器的类型调整此内存池。 USBX 设备端需要大约 10 K 到 12 K ROM,具体取决于设备控制器的类型。 RAM 内存使用量取决于设备仿真的类的类型。

USBX 还依赖于 ThreadX 信号灯、互斥体和线程进行多线程保护、I/O 暂停和定期处理,以监视 USB 总线拓扑。

产品分发

可以从我们的公共源代码存储库获取 Azure RTOS USBX,网址为:https://github.com/azure-rtos/usbx/

下面列出了该存储库中的几个重要文件。

  • ux_api.h:此 C 头文件包含所有系统等式、数据结构和服务原型。
  • ux_port.h:此 C 头文件包含所有特定于开发工具的数据定义和结构。
  • ux.lib:这是 USBX C 库的二进制版本。 它随标准包一起分发。
  • demo_usbx.c:包含简单 USBX 演示的 C 文件

所有文件名均为小写。 此命名约定使你可以更轻松地将命令转换为 Unix 开发平台命令。

USBX 安装

可以通过将 GitHub 存储库克隆到本地计算机来安装 USBX。 下面是用于在 PC 上创建 USBX 存储库的克隆的典型语法:

    git clone https://github.com/azure-rtos/usbx

或者,也可以使用 GitHub 主页上的“下载”按钮来下载存储库的副本。

你还可以在联机存储库的首页上找到有关生成 USBX 库的说明。

以下一般说明适用于几乎所有安装:

  1. 使用之前在主机硬盘驱动器上安装 ThreadX 的同一目录。 所有 USBX 名称都是唯一的,不会干扰以前的 USBX 安装。
  2. 在 tx_application_define 的开头或附近添加对 ux_system_initialize 的调用。 这是初始化 USBX 资源的位置。
  3. 添加对 ux_host_stack_initialize 的调用。
  4. 添加一个或多个调用,以初始化所需的 USBX 类(主机和/或设备类)
  5. 添加一个或多个调用,以初始化系统中可用的设备控制器。
  6. 可能需要修改 tx_low_level_initialize.c 文件,以添加低级别硬件初始化并中断矢量路由。 此说明特定于硬件平台,本文不做讨论。|
  7. 编译应用程序源代码并将其与 USBX 运行时库和 ThreadX 运行时库(如果要编译 USB 存储类和/或 USB 网络类,则可能还需要 FileX 和/或 Netx)、ux.a(或 ux.lib)以及 tx.a(或 tx.lib)链接起来。 生成的结果可下载到目标并执行!

配置选项

有多个配置选项用于生成 USBX 库。 所有选项都位于 ux_user.h 中。

以下列表详细介绍了每个配置选项。

配置选项 说明
UX_PERIODIC_RATE 此值表示特定硬件平台每秒的时钟周期数。 默认值为 1000,表示每毫秒 1 个时钟周期。
UX_THREAD_STACK_SIZE 此值为 USBX 线程的堆栈大小(以字节为单位)。 它通常可以是 1024 字节或 2048 字节,具体取决于所用的处理器和主机控制器。
UX_THREAD_PRIORITY_ENUM 这是用于监视总线拓扑的 USBX 枚举线程的 ThreadX 优先级值。
UX_THREAD_PRIORITY_CLASS 这是标准 USBX 线程的 ThreadX 优先级值。
UX_THREAD_PRIORITY_KEYBOARD 这是 USBX HID 键盘类的 ThreadX 优先级值。
UX_THREAD_PRIORITY_DCD 这是设备控制器线程的 ThreadX 优先级值。
UX_NO_TIME_SLICE 此值实际上定义将用于线程的时间片。 例如,如果定义为 0,则 ThreadX 目标端口不使用时间片。
UX_MAX_SLAVE_CLASS_DRIVER 这是可通过 ux_device_stack_class_register 注册的 USBX 类的最大数目。
UX_MAX_SLAVE_LUN 此值表示设备存储类驱动程序中表示的当前 SCSI 逻辑单元数。
UX_SLAVE_CLASS_STORAGE_INCLUDE_MMC 如果已定义,则存储类将处理多媒体命令 (MMC),即 DVD-ROM 命令。
UX_DEVICE_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES 此值表示 CDC-ECM 类的数据包池中的 NetX 数据包数。 默认值为 16。
UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 此值表示在设备堆栈中的控制终结点上收到的最大字节数。 默认值为 256 字节,但在内存约束环境中可以减少。
UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH 此值表示 HID 报告的最大长度(以字节为单位)。
UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE 此值表示一次可以排队的最大 HID 报告数。
UX_SLAVE_REQUEST_DATA_MAX_LENGTH 此值表示在设备堆栈中的大量终结点上收到的最大字节数。 默认值为 4096 字节,但在内存约束环境中可以减少。
UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT 如果定义了,设备端会启用双向终结点支持,例如寻址为 0x01 和 0x81 的终结点。 在其他情况下(默认情况下),终结点编号在相同配置中必须唯一。 请注意,该功能必须与兼容的 DCD 和外围设备配合使用。

源代码树

USBX 文件在多个目录中提供。

Source Code Tree

为了使文件可通过其名称识别,已采用以下约定:

文件后缀名 文件说明
ux_host_stack usbx 主机堆栈核心文件
ux_host_class usbx 主机堆栈类文件
ux_hcd usbx 主机堆栈控制器驱动程序文件
ux_device_stack usbx 设备堆栈核心文件
ux_device_class usbx 设备堆栈类文件
ux_dcd usbx 设备堆栈控制器驱动程序文件
ux_otg usbx otg 控制器驱动程序相关文件
ux_pictbridge usbx pictbridge 文件
ux_utility usbx 实用工具函数
demo_usbx USBX 的演示文件

USBX 资源的初始化

USBX 有自己的内存管理器。 在初始化 USBX 的主机或设备端之前,需要将内存分配给 USBX。 USBX 内存管理器可以容纳可缓存内存的系统。

以下函数可将 USBX 内存资源初始化为具有 128 K 常规内存且没有用于缓存安全内存的单独池:

/* Initialize USBX Memory */
ux_system_initialize(memory_pointer,(128*1024),UX_NULL,0);

ux_system_initialize 的原型如下所示:

UINT ux_system_initialize(VOID *regular_memory_pool_start,
        ULONG regular_memory_size,
        VOID *cache_safe_memory_pool_start,
        ULONG cache_safe_memory_size);

输入参数:

参数 说明
VOID *regular_memory_pool_start 常规内存池的开头
ULONG regular_memory_size 常规内存池的大小
VOID *cache_safe_memory_pool_start 缓存安全内存池的开头
ULONG cache_safe_memory_size 缓存安全内存池的大小

并非所有系统都需要定义缓存安全内存。 在此类系统中,在初始化过程中为内存指针传递的值将设置为 UX_NULL,并且池的大小会设置为 0。 然后,USBX 将使用常规内存池来代替缓存安全池。

在常规内存不是缓存安全内存的系统中,如果控制器需要执行 DMA 内存,则需要在缓存安全区域中定义一个内存池。

USBX 资源的取消初始化

可以通过释放 USBX 的资源来将其终止。 在终止 USBX 之前,需要正确终止所有类和控制器资源。 以下函数将取消初始化 USBX 内存资源:

/* Unitialize USBX Resources */

ux_system_uninitialize();

ux_system_initialize 的原型如下所示:

UINT ux_system_uninitialize(VOID);

USB 设备控制器的定义

在任何时候,只能定义一个以设备模式运行的 USB 设备控制器。 应用程序初始化文件应包含此定义。 以下行将定义通用 USB 控制器:

ux_dcd_controller_initialize(0x7BB00000, 0, 0xB7A00000);

USB 设备初始化具有以下原型:

UINT ux_dcd_controller_initialize(ULONG dcd_io,
    ULONG dcd_irq, ULONG dcd_vbus_address);

使用以下参数:

参数 描述
ULONG dcd_io 控制器 IO 的地址
ULONG dcd_irq 控制器使用的中断
ULONG dcd_vbus_address VBUS GPIO 的地址

以下示例演示如何使用存储设备类和通用控制器初始化处于设备模式的 USBX:

/* Initialize USBX Memory */

ux_system_initialize(memory_pointer,(128*1024), 0, 0);

/* The code below is required for installing the device portion of USBX */
status = ux_device_stack_initialize(&device_framework_high_speed,
    DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED, &device_framework_full_speed,
    DEVICE_FRAMEWORK_LENGTH_FULL_SPEED, &string_framework,
    STRING_FRAMEWORK_LENGTH, &language_id_framework,
    LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);

/* If status equals UX_SUCCESS, installation was successful. */

/* Store the number of LUN in this device storage instance: single LUN. */
storage_parameter.ux_slave_class_storage_parameter_number_lun = 1;

/* Initialize the storage class parameters for reading/writing to the Flash Disk. */
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba = 0x1e6bfe;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length = 512;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type = 0;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag = 0x80;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read = tx_demo_thread_flash_media_read;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write = tx_demo_thread_flash_media_write;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status = tx_demo_thread_flash_media_status;

/* Initialize the device storage class. The class is connected with interface 0 */
status = ux_device_stack_class_register(ux_system_slave_class_storage_name ux_device_class_storage_entry,
    ux_device_class_storage_thread,0, (VOID *)&storage_parameter);

/* Register the device controllers available in this system */
status = ux_dcd_controller_initialize(0x7BB00000, 0, 0xB7A00000);

/* If status equals UX_SUCCESS, registration was successful. */

疑难解答

USBX 附带演示文件和模拟环境。 最好先让演示平台在目标硬件或特定演示平台上运行。

USBX 版本 ID

当前版本的 USBX 在运行时可供用户和应用程序软件使用。 程序员可以通过检查 ux_port.h 文件来获取 USBX 版本。 此外,该文件还包含相应端口的版本历史记录。 应用程序软件可以通过检查全局字符串 ux_version_id(在 ux_port.h 中定义)来获取 USBX 版本。