Mac相当于.Net SerialPort.ReadExisting()

时间:2014-03-13 17:00:37

标签: objective-c vb.net macos cocoa serial-port

我正在努力将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出现(在上面的场景中)。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我确实在跟踪你在这里尝试做的事情时遇到了一些麻烦,但无论如何,你必须在比ORSSerialPort更高的级别实施它或POSIX串行读取功能。 ORSSerialPort会告诉您任何时候字节可用,正如它使用的基础标准POSIX文件API所报告的那样。所以,&#34; flush&#34;从它的角度来看。如果你收到了你没想到的回复,例如回应一个&#34; old&#34;请求,串口完全没有办法知道,它取决于你的代码来解决它。

这样的事情:

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

    // Process a valid (expected response)
}

这引发了一些其他问题。您无法保证数据会进入&#34;整个数据包&#34;。串行硬件,低级串行API和ORSSerialPort无法知道整个数据包的外观,因此只需在数据到达时一次传送一点数据。有关详情,请参阅this answer。因此,您可以缓冲传入的数据并将其组装成数据包。

如果您需要匹配您发送的回复请求,则必须自己执行此操作。 (听起来你真的已经这样做了)。

最后,如果您仅接收&#34; Response1&#34;在发送&#34; Message2&#34;之后,这使我认为连接另一端的设备没有正确响应请求时出现问题。如果可以的话(假设它是你的硬件/软件)可能值得修复。