簡體   English   中英

使用ProcessBuilder構建的Java子進程從串行端口釋放數據

[英]Java subprocess built using ProcessBuilder looses data from serial port

我正在嘗試從Java應用程序內子進程中的串行端口讀取數據。 這是我當前正在使用的代碼:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Text {
    public static void main(String... arguments) throws IOException, InterruptedException {
        Process pb = new ProcessBuilder().command("/bin/sh", "-c", "(stty raw; cat) < /dev/ttyAMA0").start();
        final Scanner scanner = new Scanner(new InputStreamReader(new BufferedInputStream(pb.getInputStream())));

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (scanner.hasNextLine()) {
                    System.out.println(scanner.nextLine());
                }
            }
        });

        t.start();
        pb.waitFor();
    }
}

這個想法是這樣的:我不會依賴操作系統(在Raspberry Pi上是Raspbian)從串行端口向我發送原始輸入。 因此,我啟動了一個子進程,該進程使用stty將串行端口設置為RAW模式,並使用cat轉發數據。 這個技巧在命令行上完美地起作用。 然后,如果我將stdout重定向到Java程序,數據將正確地流到其輸入流。

這里的問題是,使用此代碼將數據獲取到子進程(您猜不到它不是Java程序的標准輸入),我正在丟失字符。 我希望每行包含10個數字(由3個數字組成),並以逗號分隔,而我得到4到6個數字,有時后面跟一個逗號。

我認為有一個緩沖問題,我的Java應用程序可能無法清空(非常有限的)串行端口緩沖區。

有什么我可以做Java明智的選擇,還是應該轉向Linux內核極客尋求一些OS技巧?

謝謝,

馬修

嘗試在寫入后刷新,我想這就是您“松散”數據的原因:)

while (scanner.hasNextLine()) {
    System.out.println(scanner.nextLine());
    System.out.flush();
}

只是一個技巧,但是嘗試一下。 cat的stdout默認情況下是緩沖的,但是您想要的是未緩沖的stream。 嘗試更改該行:

(stty raw; cat) < /dev/ttyAMA0

(stty raw; cat -u) < /dev/ttyAMA0

好的,我使用來自那里的輸入使代碼正常工作: https : //unix.stackexchange.com/questions/40005/alternate-fifo-device-for-linux-with-a-way-bigger-buffer-while-still -有-fi

我們想要的是在(不是那么多字節)串行端口緩沖區和管道中的下一個命令之間有一個較大的緩沖區。 假設我希望包含82個字節的所有行,我使用buffer -s 82 -b 2命令,該命令允許在每次掃描程序nextLine調用之間的共享內存中存儲一​​行的兩個塊。

這是完整的演示,它會使每個Raspberry Pi所有者嘗試讀取Java串行數據感到高興(我是唯一的嗎?):

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Text2 {
    public static void main(String... arguments) throws IOException, InterruptedException {
        Process pb = new ProcessBuilder().command("/bin/sh", "-c", "(stty raw; cat | buffer -s 82 -b 2) < /dev/ttyAMA0").start();
        final Scanner scanner = new Scanner(new InputStreamReader(new BufferedInputStream(pb.getInputStream())));

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (scanner.hasNextLine()) {
                    System.out.println(scanner.nextLine());
                }
            }
        });

        t.start();
        pb.waitFor();
    }
}

這需要buffer工具,可以輕松地鍵入sudo apt-get install buffer這也依賴於一些技巧來啟用板載串行端口,如https://github.com/lurch/rpi-serial-console

感謝brettw帶來的投入,即使它最初並沒有奏效。

馬修

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM