2017-02-24 119 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。目前这表现非常好。