2

我一直在尝试通过 WebUSB 使用串行设备。我可以使用transferIn和打开设备并对其进行读/写transferOut。由于 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 串行设备是否已完成发送响应?

4

2 回答 2

3

串行设备是流数据源。当设备可以随时发送更多数据时,您如何定义“完成”?

如果您的设备在“消息”中发送数据,这是一个高级概念,您必须在串行层之上定义。也许您的设备根据终止字符(例如换行符或空字节)定义消息。也许它会在消息前面加上它的长度。也许它不做这些事情,唯一的方式告诉它完成是在定义的毫秒数内没有接收到新数据。

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

于 2020-01-03T07:24:30.800 回答
0

WebUSB 不支持串行设备,但是目前正在为 Chrome 开发一个Web 串行 API,可以解锁此功能。

于 2019-12-13T20:32:37.107 回答