2012-10-04 5 views
0

직렬 소프트웨어 포트를 통해 장치에서 보낸 일부 데이터를 읽을 수 있어야하는 Java 소프트웨어를 개발 중이므로 통신 속도가 매우 중요합니다. 전송 속도는 921600으로 설정됩니다. 처음에는 모든 것이 잘 작동하므로 (장치가 직렬 포트를 통해 전송하는 올바른 데이터를 읽음) 소프트웨어가 잘못된 데이터를 읽기 시작합니다. 소프트웨어가 너무 느리고 실제로 입력 버퍼에 들어가는 동안 데이터 손실이 발생합니다 (입력 버퍼가 처음으로 완전히 채워 졌을 때). 읽기 작업을 빠르게하기 위해 나는 현재 소프트웨어가 읽기 당 가능한 많은 바이트를 다루는 읽기 접근 방식을 사용하고 있습니다. 또한 serialPort.setInputBufferSize (byte) 메서드를 사용하여 입력 버퍼 크기를 더 크게 만들려고 시도했지만 내 문제가 해결되지 않았습니다. 그래서 Java로 빠른 직렬 통신을 한 사람이 있습니까? 내가 놓친 게 있니? 모든 것이 잠시 동안 제대로 작동 한 다음 제대로 작동하지 않는 이유는 무엇입니까?Java : 직렬 포트 읽기 (baudrate 921600)

이것은 읽기 부분 (내 동등한 경우) 코드입니다. 모든 데이터가 실제로 2 바이트 씩 구성되어 있기 때문에 데이터 변환 부분을 건너 뛰고 작성하기 전에 작성해야합니다. txt 파일.

/** 
* 
* @param evt 
*/ 
@Override 
public void serialEvent(SerialPortEvent evt) { 

    switch(evt.getEventType()) { 

     case SerialPortEvent.OUTPUT_BUFFER_EMPTY: 
      System.out.println("THE OUTPUT BUFFER IS EMPTY"); 
      break; 

     case SerialPortEvent.DATA_AVAILABLE: 
      try {  

       while(SerialPortEvent.DATA_AVAILABLE == 1) { 


        num_bytes = input.available(); 
        array = new byte[num_bytes]; 

        bytes_read = input.read(array, 0, num_bytes); 

        dato = new short[bytes_read]; 
        datoc = new int[bytes_read/2]; 
        datos = new String[bytes_read/2]; 


        for(j=0;j<bytes_read;j++){       
         dato[j] = (short) (((byte) array[j]) & 0xff); 
        } 

        k = 0; 
        for(j=0;j<(bytes_read/2);j++){ 

         datoc[j] = dato[k]; 
         datoc[j] = (datoc[j]<<8) + dato[k+1]; 
         datoc[j] = datoc[j] & 0xffffffff; 
         k = k + 2; 
        } 

        for(j=0;j<(bytes_read/2);j++){ 

         System.out.println(datoc[j]); 
         datos[j] = Integer.toString(datoc[j]); 
         output1.write(datos[j] + " "); 
        } 

       } 
      } catch(IOException ex) { 
       logText = "Failed to read data. (" + ex.toString() + ")"; 
       System.out.println(logText); 
      } 
      break; 

    } 
+0

얼마나 걸리나요? 실패하기 전에 한 시간 동안 데이터를 처리 할 수 ​​있다면 메모리 누수가 있거나 Java가 가비지 콜렉션을 수행하는 동안 오류가 발생했다고 추측 할 수 있습니다. 또한 마지막 이벤트 처리를 완료하기 전에 직렬 이벤트가 다시 실행됩니까? – Jeff

답변

0

시리얼 통신 속도가 느려지는 것이 System.out.println()입니다. 그것 없이는 데이터 수신은 결국 괜찮아졌습니다.

0

들어오는 데이터를 충분히 빠르게 처리하지 못하는 것 같습니다. 입력이 버퍼에 들어가기 때문에 일정 시간 동안 작동하고, 버퍼를 비울 때 더 많은 입력을위한 공간이 더 있습니다. 그러나 데이터가 전반적으로 처리하는 것보다 빠르게 들어 오면 결국 버퍼가 가득 차고 데이터는 계속 들어오고 아무데도 갈 수 없습니다. 이러한 데이터가 (가상) 층에 버려지는 것은 직렬 통신에서 전형적이었습니다.

"버퍼 오버플로"를 나타내는 상태가 설정되는 것이 일반적이기도합니다. 가장 먼저 확인해야 할 것은 직렬 데이터를 읽는 데 사용하는 라이브러리가 무엇이든지이 상태를 사용할 수 있는지 여부와 설정이되었는지 여부를 확인하는 것입니다. 이렇게하면 위의 상황이 발생하는지 확인할 수 있습니다.

XON/XOFF 기능을 사용하는 것이 합당한지를 확인하는 또 다른 사항입니다. 이는 수신자가 버퍼가 거의 가득 찼음을 송신자에게 알려주고 다시 시작할 수 있다고 말할 때까지 (XON) 송신을 중지하도록 허용하는 일부 직렬 통신의 기능이었습니다. 모든 하드웨어 및 소프트웨어가이 기능을 지원하지는 않습니다.

어떤 이유로 든 작동하지 않으며 이것이 실제로 문제가되는 경우 데이터를 빠르게 처리하거나 버퍼링을 더 잘 수행해야합니다. 간단한 brute-force 접근법은 들어온 바이트를 저장소에 쓰고 별도의 스레드에서 읽는 것입니다. 예를 들어, 기존의 컴퓨터 시스템이라면 디스크 파일을 디스크에 기록한 다음 디스크 파일을 처리하여 하나의 스레드에서 읽고 다른 파일에서 쓰기 (어떤 재미있는 일인지) 할 수 있습니다.

+0

XON/XOFF는 소프트웨어 흐름 제어이므로 하드웨어 지원과 관련이 없습니다. XON/XOFF를 사용하는 것은 매우 드뭅니다. 훨씬 일반적인 흐름 제어 솔루션은 하드웨어 RTS/CTS입니다. 대다수의 하드웨어가 RTS/CTS를 지원합니다. – TJD

+0

XON/XOFF를 지원하려면 전이중이어야합니다. 아마 나는 너무 오래 전의 역사로 돌아가고있다. 거기에는 많은 반이중 시스템이 존재한다. 그러나 실제로 소프트웨어가 신호를 보내도록 하드웨어 지원이 필요하다. 당신은 소프트웨어 기반이라는 것이 옳았습니다. RTS/CTS에 대해서 언급하는 것을 잊었습니다. - OP가 그것을 봐야만합니다. 당신이 그것을 언급했기 때문에 기쁩니다. – arcy