javascript - 使用 WebUSB 从串行设备读取整个响应
问题描述
我一直在尝试通过 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 串行设备是否已完成发送响应?
解决方案
串行设备是流数据源。当设备可以随时发送更多数据时,您如何定义“完成”?
如果您的设备在“消息”中发送数据,这是一个高级概念,您必须在串行层之上定义。也许您的设备根据终止字符(例如换行符或空字节)定义消息。也许它会在消息前面加上它的长度。也许它不做这些事情,唯一的方式告诉它完成是在定义的毫秒数内没有接收到新数据。
在 USB 中,一个常见的模式是设备使用端点的最大数据包大小的数据包来响应批量传输 IN 请求。如果收到小于该长度的数据包,则表明消息结束。这不适用于 USB 串行设备,因为串行通信没有数据包的概念,当接收到传输请求时,批量数据包会填充 UART 缓冲区中的任何数据。
推荐阅读
- r - 使用列表元素的名称将列表元素带入它们自己的小标题
- sql - 具有不同时区的 Oracle DB 查询
- android - Flutter Release apk 无法在 android 11.0 移动设备上连接互联网,但能够在 android 8.0 上连接互联网
- css - 具有 90% 窗口大小的引导程序的超大模态
- python - 如何使用 sql lab 在 apache 超集中获取登录用户名?
- assembly - jmp 的绝对地址是如何在汇编中计算出来的?
- r - R,未知数量的向量/矩阵的成对乘积
- javascript - 如何使用 WDIOReporter 自定义报告记录失败测试的路径
- python - Exchangelib:返回附加到主帐户电子邮件的电子邮件别名
- python - 在 docker-compose 中跨容器共享模型定义的最佳实践?