使用WebUSB从串行设备读取整个响应

时间:2019-12-13 16:40:49

标签: javascript webusb

我一直在尝试通过WebUSB使用串行设备。我可以打开设备并使用transferIntransferOut对其进行读写。由于USB设备不会一次发送所有数据,因此我编写了一个函数,该函数发送命令,然后通过递归调用transferIn来回读结果:

/** Send command to a device, and get its response back.
 * @param {string} command
 * @param {USBDevice} device
 * @returns {Promise<string>}
 */
function sendCommand(command, device) {
    return new Promise(function (resolve, reject) {
        var pieces = [];
        device.transferOut(1, new TextEncoder().encode(command + '\n')).then(function readMore() {
            device.transferIn(1, 64).then(function (res) {
                if (res.status !== 'ok')
                    reject(new Error('Failed to read result: ' + res.status));
                else if (res.data.byteLength > 0) {
                    pieces.push(res.data);
                    readMore();
                } else
                    resolve(new TextDecoder().decode(join(pieces))); // join() concatenates an array of arraybuffers
            }).catch(reject);
        }).catch(reject);
    });
}

但是,这不起作用,因为transferIn在解析新数据之前等待新数据可用。如何检查USB串行设备是否已完成发送其响应?

2 个答案:

答案 0 :(得分:2)

串行设备正在传输数据源。当设备可以随时发送更多数据时,如何定义“完成”?

如果您的设备以高级概念“消息”发送数据,则必须在串行层的顶部进行定义。也许您的设备根据终止字符(例如换行符或空字节)定义了一条消息。也许它以消息的长度作为前缀。也许它没有做任何事情,并且唯一可以证明完成的唯一方法是在规定的毫秒数内没有收到新数据。

在USB中,一种常见的模式是设备响应具有批量的最大端点大小的数据包来响应批量传输IN请求。如果收到小于该长度的数据包,则表明消息已结束。这不适用于USB串行设备,因为串行通信没有数据包的概念,并且在接收到传输请求时,大数据包中填充了UART缓冲区中的任何数据。

答案 1 :(得分:0)

WebUSB不支持串行设备,但是Chrome目前正在开发Web Serial API来解锁此功能。