Nuoeriris · 2020年06月22日

MM32 USB功能学习笔记 —— WebUSB功能

在前面几个章节我们介绍了MM32 MCU的各种常用的USB功能,而随着物联网的发展,有时候希望我们直接可以通过网页访问USB设备,于是出现了一种新的usb使用类型即WebUSB,通过让MCU USB实现WebUSB功能,就可以直接与网页通信,因此我们本节我们讲解MM32 MCU的WebUSB功能。
 
对于WebUSB来说,其是由Reilly Grant和Ken Rockot开发的,它已经被推入W3C WICG,以求建立一个能够被浏览器制造商引用的平台。WebUSB是一个Javascript API,可以允许网页访问已连接的USB设备,这里的USB设备是指系统和工业的USB设备。通过WebUSB API,我们可以让USB设备,比如键盘、鼠标、3D打印机和硬件驱动连接到物联网,甚至在Web页面上进行定位。这一产品的目的,是为了帮助硬件制造商将他们的USB设备实现跨平台通用(包括Web),此后不需要为特定的平台写本地驱动或者SDK。除了控制硬件,WebUSB也可以通过Web页面安装固件升级或者执行其他重要任务。然而,这个草拟版本的API并不能传输文件。

当然,目前WebUSB现在只是个草拟版本,还没有正式采用W3C标准。其开发工作仍然在进展之中,但是我们现在还是可以在Github上看到完整的WebUSB代码库(https://github.com/wicg/webusb)。

WebUSB原理

当USB设备插入主机时,浏览器会读取设备发送的描述符,然后将其储存在内部USB设备储存器中。此过程由Chrome的浏览器内核Blink处理。日志可以在chrome://device-log(GET参数“refresh = 1”非常有用)中查看。

根据规范要求,设备可以在其二进制对象存储中的平台描述符中明确地声明对WebUSB的支持。
1.png
图1 WebUSB功能描述符

浏览器将每个USB设备存储在自己的设备存储器中。WebUSB的可访问性由本机驱动程序支持所决定。在Windows上,我们可以通过浏览器访问由WinUSB驱动程序处理的每个USB设备。其他的诸如大容量存储设备,网络摄像头或HID等就无法通过网络访问了,因为它们具有处理这些设备的专用驱动程序。

本节我们来讲解如何在MM32 MCU实现WebUSB设备功能,对于MM32 MCU来说,实现WebUSB只需要在之前程序基础上修改添加部分代码即可。
 
本次我们采用MM32L373 miniboard作为测试开发板。为了方便大家使用MM32 MCU的WebUSB设备功能,我们已经封装好全部代码,用户不需要自己配置那些麻烦的描述符等参数,只需要知道用之前的单一设备函数即可。

软件资源如下:

对于MM32 MCU的WebUSB,我们可以配置WebUSB的参数来让网页识别设备。

#define USBD_WEBUSB_STRDESC         L"WebUSB: MM32"
//     WebUSB support
#define USBD_WEBUSB_ENABLE          WEBUSB_INTERFACE
#define USBD_WEBUSB_VENDOR_CODE     0x21
#define USBD_WEBUSB_LANDING_URL   "os.mbed.com/webusb/landing-page/?bid="
#define USBD_WEBUSB_ORIGIN_URL      "os.mbed.com/"

参数设置如上可以看到电脑上显示的设备名称WebUSB:MM32,如下:
2.png
图2 WebUSB枚举列表
 
在使用MM32 WebUSB功能之前先调用USB初始化函数来初始化USB协议栈。

int main(void)
{
// USB Device Initialization and connect
usbd_init();
usbd_connect(__TRUE);
while (!usbd_configured())   // Wait for USB Device to configure
{
}
while (1)
{
……
}
}

然后依然和之前一样只是在WINUSB基础上添加WebUSB相关参数函数接口即可,代码如下:

#if (USBD_WEBUSB_ENABLE)
usbd_webusb_if_num = if_num++;
desc_ptr += webusb_desc_fill(&USBD_ConfigDescriptor[desc_ptr], &USBD_ConfigDescriptor_HS[desc_ptr], usbd_webusb_if_num);
#endif
 
#if (USBD_WEBUSB_ENABLE)
static U16 webusb_desc_fill(U8 * config_desc, U8 * config_desc_hs, U8 if_num) {
U8 * pD = 0;
const U8 webusb_desc[] = {
WEBUSB_DESC
};
pD = config_desc;
memcpy(pD, webusb_desc, sizeof(webusb_desc));
 ((USB_INTERFACE_DESCRIPTOR *)pD)->bInterfaceNumber = if_num;

#if (USBD_HS_ENABLE == 1)
pD = config_desc_hs;
memcpy(pD, webusb_desc, sizeof(webusb_desc));
 ((USB_INTERFACE_DESCRIPTOR *)pD)->bInterfaceNumber = if_num;
#endif

#if (USBD_WINUSB_ENABLE)
pD = USBD_WinUSBDescriptorSetDescriptor + WINUSB_DESCRIPTOR_SET_HEADER_SIZE;
 ((WINUSB_FUNCTION_SUBSET_HEADER*)pD)->bFirstInterface = if_num;
#else
#error "WEBUSB requires WINUSB!"
#endif

return sizeof(webusb_desc); 
}
#endif

这样我们就完成MM32 MCU的WebUSB功能,将程序下载到板子中,USB插上电脑,电脑上会枚举出WebUSB。在WebUSB枚举成功后,我们需要检查是否真的可以被网页识别。找了一个静态网页,通过该网页检测WebUSB工作状态。
3.png
图3 测试网页

要测试设备是否支持,请单击“选择设备”按钮打开权限提示。此提示将列出所有可用的USB设备。通过选择所需的设备并单击“连接”,工具将打开设备,并遍历每个可用的界面,并尝试声明。结果记录在页面底部的表格中。被声明的interfaces列显示可以声明的接口编号,我们点击choose A Device。
4.png
图4 WebUSB连接页面
 
从图上可以看到网页找到了MM32实现的WebUSB设备,以上就是MM32 MCU USB的WebUSB功能。

在下一张章节将会继续带来WebUSB DFU升级教程,后续将对USB的相关功能程序进行单独的封装打包,正式在MM32 MCU的官方发布,方便大家参考使用,敬请期待。

推荐阅读
关注数
6152
内容数
276
灵动MM32 MCU相关技术知识,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息