我正在将VB程序移植到PC。它使用串行通信与物理设备进行交互。我有一个使用ORSSerialPort在Mac上运行的版本。但是,曾经有一个很棒的VB库是SerialPort.ReadExisting()函数。这实际上会读取所有消息并将其丢弃。

有没有人在Mac方面构建过类似的东西?我尝试将ORSSerialPort提取到一个函数中以直接读取值(请参见下文)。但是,除非我发送消息,否则收到的响应为空。 readExisting函数非常适用于某些情况,例如:

我向设备发送了一条消息“ Message1”,但没有任何反应(期望Response1)。
我向设备发送消息“ Message2”并收到:“ Response1”而不是“ Response2”

我想检测到这一点,请调用等效于SerialPort.readExisting()的方法,因为如果我继续操作,下一个将找到Response2。

我的阅读功能:

-(NSString *) directRead
{
    // Read Directly
    int localPortFD = self.fileDescriptor;
    struct timeval timeout;
    int result=0;

    fd_set localReadFDSet;
    FD_ZERO(&localReadFDSet);
    FD_SET(localPortFD, &localReadFDSet);

    timeout.tv_sec = 0;
    timeout.tv_usec = 100000; // Check to see if port closed every 100ms

    result = select(localPortFD+1, &localReadFDSet, NULL, NULL, &timeout);
    if (!self.isOpen) return nil; // Port closed while select call was waiting
    if (result < 0)
    {
        NSLog(@"No Data To Read");
    }

    if (result == 0 || !FD_ISSET(localPortFD, &localReadFDSet)) return nil;

    // Data is available
    char buf[1024];
    long lengthRead = read(localPortFD, buf, sizeof(buf));
    if (lengthRead>0)
    {
        NSData *readData = [NSData dataWithBytes:buf length:lengthRead];
        if (readData != nil)
            return [[NSString alloc] initWithData:readData encoding:NSUTF8StringEncoding];
    }

    return nil;
}


您会认为只是在做:

NSString *result = nil;
do
{
   result = [serialPort directRead];
   NSLog(@"Past Message is: %@", result);
} while(result != nil);


将清除消息。但是,它的作用就好像没有任何消息一样。但是,如果再次调用sendData:Message1,我仍然会看到Response2出现(在上述情况下)。

感谢您提供的所有帮助。

最佳答案

我在确切地遵循您在此处要执行的操作时遇到了一些麻烦,但是无论如何,您必须在比ORSSerialPort或POSIX串行读取功能更高的级别上实现它。 ORSSerialPort会告诉您任何可用的字节,这由其使用的基础标准POSIX文件API报告。因此,从其角度来看,没有什么可“冲洗”的。如果您得到了预期的答复,例如对于“旧”请求的响应,串行端口根本无法知道这一点,这取决于您的代码来解决。

像这样:

- (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data
{
    if (![self dataIsResponseToLatestRequest:data]) return; // Try again next time around

    // Process a valid (expected response)
}


这带来了另外两个问题。您不能保证数据会以“整个数据包”的形式进入。串行硬件,低级串行API和ORSSerialPort无法知道整个数据包的外观,因此只能在到达时一次传送一点数据。有关更多信息,请参见this answer。因此,由您来缓冲传入的数据并将其组装为数据包。

如果您需要匹配发送的请求和传入的响应,则必须自己进行操作。 (听起来像您确实已经在执行此操作)。

最后,如果您在发送“ Message2”后仅收到“ Response1”,这使我认为连接另一端的设备存在问题,无法正确响应请求。如果可以的话(可能是您的硬件/软件),可能值得修复。

10-08 08:24