2017-02-24 50 views
0

我正在通過半雙工RS-485協議以9600bps的速率讀取連接在UART串行端口上的數據流,數據:8位,停止1位與嵌入式設備無奇偶校驗。正在讀取UART流 - 數據分塊

我知道我連接的系統以20ms的間隔發送2字節到10字節長的二進制命令。

我用下面的標誌訪問流:

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

然而,頻繁地發生在10個字節長的命令將於半小時進行分塊在我的應用程序導致校驗和錯誤。我需要每隔20毫秒進行一次輪詢,我發現的唯一解決方案是增加民意調查之間的休息時間,這是我不想要的。

在讀取流緩衝區的內容之前,有沒有可以用來確保傳輸完成的標誌或智能方法?

+0

硬件握手問題? –

+0

@πάνταῥεῖ實際上可能不是,我不認爲其他設備期望任何流量控制。 – Machinegon

+1

最糟糕的情況(明顯發生)是設備每20ms發送一次消息,並且您的程序在該傳輸過程中每20ms輪詢/讀取一次(可能長達** 10ms **或** 50 xmit間隔的%**)。您沒有與發件人同步的機制。您不想增加輪詢間隔;你需要增加投票率。順便說一句,每個讀取系統調用期望檢索完整的二進制消息包是愚蠢的。您正在使用非阻塞模式,這可能是不利的,即您無法使用VMIN和VTIME功能。 – sawdust

回答

0

好的,我找到了一個解決方案,可以滿足我的需求。由於我無法確定當我讀取流的內容時,所有的數據都會在那裏,我不想增加我的輪詢間隔,就像@sawdust建議的那樣,我增加了輪詢率:

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; 
     } 

我首先將投票率增加到8ms。由於我知道我能接收的最長命令長度爲10個字節,所以我讀取直到校驗和有效,或者讀取的內容長度爲10個字節,並且在輪詢之間額外休眠2ms。目前這表現非常好。