2017-02-24 3 views
0

9600bps에서 반이중 RS-485 프로토콜을 통해 UART 직렬 포트에 연결된 스트림에서 데이터를 읽는 중입니다. 데이터 : 8 비트, 임베디드 장치에서 패리티 없음 1 비트 중지.UART 스트림 읽기 - 데이터 청크

필자가 연결 한 시스템은 20ms 간격으로 2 바이트와 10 바이트 사이의 바이너리 명령을 전송한다는 것을 알고 있습니다.

나는 다음과 같은 플래그 스트림에 액세스 :

uart0_filestream = open(COM_UART_DEV, O_RDWR | O_NOCTTY | O_NDELAY); 

그러나, 10 바이트 명령을 내 응용 프로그램에 체크섬 오류의 원인이 절반으로 청크 분할됩니다 자주 발생합니다. 나는 매 20ms마다 폴링을 할 필요가 있는데, 내가 찾은 유일한 해결책은 설문 조사 사이의 수면 시간을 줄이는 것이고, 나는 그것을 원치 않는다.

스트림 버퍼의 내용을 읽기 전에 전송이 완료되었는지 확인하는 데 사용할 수있는 플래그 또는 스마트 방법이 있습니까?

+0

하드웨어 핸드 셰이크에 문제가 있습니까? –

+0

@ πάνταῥεῖ 아마도 다른 장치가 어떤 종류의 흐름 제어를 기대하지는 않을 것입니다. – Machinegon

+1

최악의 시나리오 (분명히 발생)는 장치가 매 20ms마다 메시지를 보내고 프로그램이 해당 전송 중간에 20ms마다 폴링/읽기 (** 10ms ** 또는 ** 50 일 수 있음)입니다 xmit 간격의 % **). 보낸 사람과 동기화 할 메커니즘이 없습니다. 폴링 간격을 늘리고 싶지는 않습니다. 당신은 투표율을 높여야합니다. BTW는 읽기 시스템 콜당 완전한 바이너리 메시지 패킷을 가져올 것을 기대합니다. 비 차단 모드를 사용 중이므로 불편할 수 있습니다. 즉 VMIN 및 VTIME 기능을 사용할 수 없습니다. – sawdust

답변

0

그래, 내 요구에 맞는 해결책을 찾았습니다. 스트림의 내용을 읽을 때 모든 데이터가 거기에있을 것이고 폴링 간격을 늘리고 싶지 않다는 것을 알 수 없기 때문에 설상가상으로 폴 비율을 높였습니다 :

unsigned char *pStartBuffer = pRxBuffer; 

    if(uart0_filestream != -1) 
    { 
     int rx_length = 0, rx = 0, elapsed = 0; 
     bool bCommand = false; 
     while(rx_length <= 10)//&& elapsed <= 10) 
     { 
      rx = read(uart0_filestream, (void*)pRxBuffer, length); 
      if(rx > 0) 
      { 
       rx_length += rx; 
       pRxBuffer += rx; 
       if(checksum(pStartBuffer, rx_length) == true) 
       { 
        bCommand = true; 
        break; 
       } 
      } 
      nanosleep(&sleep_rx, NULL); 
      //elapsed+=2; 
     } 

나는 처음에는 poll rate를 8ms로 늘렸다. 내가받을 수있는 가장 긴 명령은 10 바이트 길이라는 것을 알고 있기 때문에 체크섬이 유효하거나 읽는 내용이 10 바이트 길이가되고 여론 조사 사이에 여분의 2ms가 될 때까지 읽었습니다. 이것은 현재 매우 잘 수행됩니다.