我正在将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”,这使我认为连接另一端的设备存在问题,无法正确响应请求。如果可以的话(可能是您的硬件/软件),可能值得修复。