简体   繁体   English

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

[英]Reading the entire response from a serial device using WebUSB

I have been trying to use a serial device over WebUSB.我一直在尝试通过 WebUSB 使用串行设备。 I can open the device and read/write to it using transferIn and transferOut .我可以打开设备并使用transferIntransferOut对其进行读/写。 Since USB devices don't send all their data in one go, I have written a function that sends a command and then reads back the result by calling transferIn recursively:由于 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);
    });
}

However, this does not work, as transferIn waits for new data to be available before it resolves.但是,这不起作用,因为transferIn在解析之前等待新数据可用。 How can I check if a USB serial device is done sending its response?如何检查 USB 串行设备是否已完成发送响应?

Serial devices are streaming data sources.串行设备是流式数据源。 How do you define "done" when the device can send more data at any time?当设备可以随时发送更多数据时,您如何定义“完成”?

If your device sends data in "messages" that is a high-level concept you must define on top of the serial layer.如果您的设备在“消息”中发送数据,这是一个高级概念,您必须在串行层之上进行定义。 Maybe your device defines a message in terms of a termination character such as a newline or null byte.也许您的设备根据终止字符(例如换行符或空字节)定义消息。 Maybe it prefixes a message with its length.也许它用它的长度作为消息的前缀。 Perhaps it does neither of these things and the only way to tell it is done is that no new data is received for a defined number of milliseconds.也许它既不做这些事情,唯一表明它完成的方法是在定义的毫秒数内没有接收到新数据。

In USB a common pattern is for a device to respond to a bulk transfer IN request with packets of exactly the endpoint's maximum packet size.在 USB 中,一个常见的模式是设备使用完全符合端点最大数据包大小的数据包来响应批量传输 IN 请求。 If a packet less than that length is received that indicates the end of the message.如果收到小于该长度的数据包,则表明消息结束。 This does not apply for USB serial devices because serial communication does not have the concept of a packet and the bulk packets are filled with whatever data was in the UART's buffer when the transfer request was received.这不适用于 USB 串行设备,因为串行通信没有数据包的概念,当接收到传输请求时,批量数据包会填充 UART 缓冲区中的任何数据。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM