事件驱动和异步串行端口同时通信

时间:2020-05-15 13:25:57

标签: java asynchronous serial-port

我是串口通信的新手,需要一些帮助来掌握它。

我需要与控制板通信。该委员会有时可以发送我需要作出反应的事件,并且需要将事件发送给委员会并等待响应。

我们已经建立了一个协议,其中每个事件始终为12个字节,而前2个字节确定事件的类型。

我知道,当我发送特定消息时,我需要等待具有特定指示字节的消息。 同时我希望对董事会发出的事件做出反应。例如,董事会可能会说它过热,而与此同时,我要它执行一些命令并做出答复。

我的问题是,如果我在等待期望的响应的同时写端口并阻塞一秒钟,我如何确保我不“窃取”我的听众期望的数据?例如。串行端口就像流一样工作,一旦我读完,我就越过了可以重读的地方。

我已经使用jSerialComm完成了此操作,希望可以为我的问题提供一些启发。

首先,使用addDataListener方法注册的侦听器。我希望在以“ T”开头的端口上存在事件时触发该事件。

private static LockerSerialPort getLockerSerialPort(final DeviceClient client) {
    return MySerialPort.create(COM_PORT)
            .addListener(EventListener.newBuilder()
                    .addEventHandler(createLocalEventHandler())
                    .build());
}

private static EventHandler createLocalEventHandler() {
    return new EventHandler() {
            @Override
            public void execute(final byte[] event) {
                System.out.println(new String(event));
            }

            @Override
            public byte[] getEventIdentifier() {
                // I want this listener to be executed when events that start with T are sent to the port
                return "T".getBytes();
            }

            @Override
            public String getName() {
                return "T handler";
            }
        };
}

接下来,我希望能够写入端口并立即获得响应,因为需要知道该命令是否成功。

private byte[] waitForResponse(final byte[] bytes) throws LockerException {
    write(bytes);
    return blockingRead();
}

private void write(final byte[] bytes) throws LockerException {
    try (var out = serialPort.getOutputStream()) {
        out.write(bytes);
    } catch (final IOException e) {
        throw Exception.from(e, "Failed to write to serial port %s", getComPort());
    }
}

public byte[] blockingRead() {
    return blockingRead(DEFAULT_READ_TIMEOUT);
}

private byte[] blockingRead(final int readTimeout) {
    serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, readTimeout, 0);
    try {
        byte[] readBuffer = new byte[PACKET_SIZE];
        final int bytesRead = serialPort.readBytes(readBuffer, readBuffer.length);
        if (bytesRead != PACKET_SIZE) {
            throw RuntimeException.from(null, "Expected %d bytes in packet, got %d", PACKET_SIZE, bytesRead);
        }
        return readBuffer;
    } catch (final Exception e) {
        throw RuntimeException.from(e, "Failed to read packet within specified time (%d ms)", readTimeout);
    }
}

当我打电话给waitForResponse("command")时,我怎么知道我的阻塞读取没有从监听器中窃取数据?

这两种模式不兼容吗?通常如何处理这种情况?

0 个答案:

没有答案
相关问题