全部文档
概述 硬件支持 快速开发指南 内核 驱动 通用组件 专业组件 常见问题

USBD设备用户开发


基础BSP配置

建立工程文件

以正点原子潘多拉开发板为例,介绍用开发板USB接口模拟鼠标例程。

使用STM32CUBEMX配置硬件

  1. 打开 oneos\projects\stm32l475-atk-pandora\board\CubeMX_Config下 的 CUBE 工程文件;
  2. 在 CUBE 工程中进行usb 配置,如下图所示,配置usb,点击 Clock Configuration 检查时钟配置,然后点击 GENARATE CODE 生成代码; usb_cube

使用 Menuconfig 配置工程选项

  1. 在对应的 oneos\projects\stm32l475-atk-pandora目录下打开 OneOS-Cube 工具,在命令行输入 menuconfig 打开可视化配置界面;

  2. 如下图示,通过空格或向右方向键选择 Drivers 下的 USB 选项;

    (Top) → Drivers
                                                OneOS Configuration
    -*- Enable device manager
     Audio  --->
     BLOCK  --->
     CAN  --->
     CONSOLE  --->
     DMA  --->
     FAL  --->
     Graphic  --->
     HAL  --->
     HwCrypto  --->
     I2C  --->
     Infrared  --->
     Low power manager  --->
     MISC  --->
     MTD  --->
     NAND  --->
     PIN  --->
     RTC  --->
     SDIO  --->
     Sensors  --->
     Serial  --->
     SN  --->
     SPI  --->
     Timer  --->
     Touch  --->
     USB  --->
     WDG  --->
     WLAN  --->
    
  3. 在Drivers->USB下配置如下;

    (Top) → Drivers→ USB
                                             OneOS Configuration
    [*] Using USB device
    (4096) usb task stack size (NEW)
    (0x0FFE) USB Vendor ID (NEW)
    (0x0001) USB Product ID (NEW)
    [*] Enable composite device
    [ ] Enable to use device as CDC device (NEW)
    [ ] Enable to use device as Mass Storage device (NEW)
    [*] Enable to use device as HID device
    [ ] Enable to use device as winusb device (NEW)
    [ ] Enable to use device as audio device (NEW)
    [ ] Use to HID device as Keyboard (NEW)
    [*] Use to HID device as Mouse
    [ ] Use to HID device as General HID device
    [ ] Use to HID device as media keyboard
    

使用 Scons 构建工程

在上一步打开的 OneOS-Cube 工具命令行输入 scons --ide=mdk5 构建工程;

工程编译及实现

  1. 打开对应的 oneos\projects\stm32l475-atk-pandora目录下的 project.uvprojx 工程文件;
  2. 将 usbd_hid_test.c文件加入到 application子文件夹中;
  3. 编译并下载工程,运行程序;
  4. 将开发板USB接口用USB线连接至PC机;
  5. 在PC机设备管理器中可以看到新增了一个鼠标设备; usb_mouse
  6. 在开发板shell中输入usbd_hid_test命令,开发板会向PC发送模拟鼠标移行的数据,可以看到鼠标在桌面移动;

USB设备


应用API 列表

接口 说明
os_device_find() 根据usb设备名称查找设备
os_device_open() 打开usb设备
os_device_read_nonblock() 读数据
os_device_write_nonblock() 写数据

os_device_find

该函数根据usb设备名称查找设备,函数原型如下:

os_device_t *os_device_find(const char* name);
参数 说明
name usb设备名称
返回 说明
设备指针 查找到对应设备将返回相应的设备指针
OS_NULL 没有找到相应的设备对象

os_device_open

该函数用于打开usb设备,函数原型如下:

os_err_t os_device_open(os_device_t *dev, os_uint16_t oflag);
参数 说明
dev 设备指针
oflag 设备模式标志,一般以读写方式打开,即取值:OS_DEVICE_OFLAG_RDWR
返回 说明
OS_EOK 设备打开成功
OS_EBUSY 设备忙
其他错误码 设备打开失败

os_device_read_nonblock

该函数用于读取接收到的数据,函数原型如下:

os_size_t os_device_read_nonblock(os_device_t *dev, os_off_t pos, void *buffer, os_size_t size);
参数 说明
dev 设备指针
pos 读取数据偏移量,固定为0
buffer 缓冲区指针,读取的数据将会被保存在缓冲区中
size 读取数据的大小
返回 说明
读到数据的实际大小 返回读取到数据的个数
0 需要读取当前线程的 errno 来判断错误状态

os_device_write_nonblock

该函数用于写入发送数据,函数原型如下:

os_size_t os_device_write_nonblock(os_device_t *dev, os_off_t pos, const void *buffer, os_size_t size);
参数 说明
dev 设备指针
pos 写入数据偏移量
buffer 内存缓冲区指针,放置要写入的数据
size 写入数据的大小
返回 说明
写入数据的实际大小 如果是字符设备,返回大小以字节为单位;
0 需要读取当前线程的 errno 来判断错误状态

USBD事件处理函数API列表

接口 说明
os_usbd_reset_handler() 复位事件处理函数
os_usbd_connect_handler() 连接事件处理函数
os_usbd_disconnect_handler() 断开连接事件处理函数

os_usbd_reset_handler

该函数用于驱动程序向usbd协议栈传递 reset 事件,函数原型如下:

os_err_t os_usbd_reset_handler(udcd_t dcd);
参数 说明
dcd usb设备控制对象
返回 说明
OS_EOK 成功

os_usbd_connect_handler

该函数用于驱动程序向usbd协议栈传递 connect 事件,函数原型如下:

os_err_t os_usbd_connect_handler(udcd_t dcd);
参数 说明
dcd usb设备控制对象
返回 说明
OS_EOK 成功

os_usbd_disconnect_handler

该函数用于驱动程序向usbd协议栈传递 disconnect 事件,函数原型如下:

os_err_t os_usbd_disconnect_handler(udcd_t dcd);
参数 说明
dcd usb设备控制对象
返回 说明
OS_EOK 成功

使用示例

本例程为usb模拟鼠标的测试例程:

#include <board.h>
#include <shell.h>
#include <stdint.h>

static int x      = 0;
static int y      = 0;
static int left   = 0;
static int right  = 0;
static int scroll = 0;

static void left_callback(void *args)
{
    left = 1;
    os_kprintf("left button click\r\n");
}

static void right_callback(void *args)
{
    right = 1;
    os_kprintf("right button click\r\n");
}

static void update_mouse(os_device_t *device)
{
    uint8_t report[4];

    if ((left | right) != 0)
    {
        report[0] = 0x08 | left | right << 1;
    }
    else
    {
        report[0] = 0;
    }

    report[1] = x;
    report[2] = y;
    report[3] = scroll;

    os_device_write_nonblock(device, HID_REPORT_ID_MOUSE, report, 4);

    left  = 0;
    right = 0;
}

static int usbd_hid_test(int argc, char **argv)
{
    int          i, j;
    os_device_t *device = os_device_find("hidd");
    OS_ASSERT(device != OS_NULL);
    os_device_open(device);

    /* Mouse left button */
    if (key_table_size > 0)
    {
        os_pin_mode(key_table[0].pin, key_table[0].mode);
        os_pin_attach_irq(key_table[0].pin, key_table[0].irq_mode, left_callback, NULL);
        os_pin_irq_enable(key_table[0].pin, PIN_IRQ_ENABLE);
    }

    /* Mouse right button */
    if (key_table_size > 1)
    {
        os_pin_mode(key_table[1].pin, key_table[1].mode);
        os_pin_attach_irq(key_table[1].pin, key_table[1].irq_mode, right_callback, NULL);
        os_pin_irq_enable(key_table[1].pin, PIN_IRQ_ENABLE);
    }

    for (j = 0; j < 5; j++)
    {
        os_kprintf("loop %d/5\r\n", j + 1);

        for (i = 0; i < 20; i++)
        {
            x = 10;
            y = 0;
            update_mouse(device);
            os_task_msleep(100);
        }

        for (i = 0; i < 20; i++)
        {
            x = 0;
            y = 10;
            update_mouse(device);
            os_task_msleep(100);
        }

        for (i = 0; i < 20; i++)
        {
            x = -10;
            y = 0;
            update_mouse(device);
            os_task_msleep(100);
        }

        for (i = 0; i < 20; i++)
        {
            x = 0;
            y = -10;
            update_mouse(device);
            os_task_msleep(100);
        }
    }

    return 0;
}

SH_CMD_EXPORT(usbd_hid_test, usbd_hid_test, "usbd_hid_test");

运行结果如下:

sh>usbd_hid_testloop 1/5left button clickleft button clickloop 2/5right button clickloop 3/5loop 4/5loop 5/5

results matching ""

    No results matching ""