gpt4 book ai didi

objective-c - Mac 相当于 .Net SerialPort.ReadExisting()

转载 作者:行者123 更新时间:2023-12-03 17:21:54 24 4
gpt4 key购买 nike

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

关于objective-c - Mac 相当于 .Net SerialPort.ReadExisting(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22385716/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com