제공된 코드를 http://playground.arduino.cc/Interfacing/Cocoa (IOKit/ioctl 메서드)에 따라 Arduino에서 코코아 응용 프로그램으로 데이터를 보내려면 직렬 통신 예제를 실행하려고합니다. 그것은 작동하지만, 일단 시작 수신기 스레드를 멈출 수 없습니다.코코아 백그라운드 스레드에서 직렬 통신을 닫는 방법
내가 스위치 버튼 시작 시간에 시리얼 포트를 열고 수신기 스레드 실행 (시작/정지) 구현했습니다:
- (IBAction) startButton: (NSButton *) btn {
(…)
error = [self openSerialPort: [SelectPort titleOfSelectedItem] baud:[Baud intValue]];
(…)
[self refreshSerialList:[SelectPort titleOfSelectedItem]];
[self performSelectorInBackground:@selector(incomingTextUpdateThread:) withObject:[NSThread currentThread]];
(…)
}
스레드 코드, 실질적으로 예에서와 동일 제외를 내가받은 버퍼에서 직렬 패킷을 재건하고 SQLite 데이터베이스에 저장하는 코드를 포함했다고 :이 코드는 startButton 선택의도 부분 메인 스레드에서 포트를 닫으려고
- (void)incomingTextUpdateThread: (NSThread *) parentThread {
// mark that the thread is running
readThreadRunning = TRUE;
const int BUFFER_SIZE = 100;
char byte_buffer[BUFFER_SIZE]; // buffer for holding incoming data
int numBytes=0; // number of bytes read during read
(…)
// assign a high priority to this thread
[NSThread setThreadPriority:1.0];
// this will loop until the serial port closes
while(TRUE) {
// read() blocks until some data is available or the port is closed
numBytes = (int) read(serialFileDescriptor, byte_buffer, BUFFER_SIZE); // read up to the size of the buffer
if(numBytes>0) {
// format serial data into packets, but first append at start the end of last read
buffer = [[NSMutableString alloc] initWithBytes:byte_buffer length:numBytes encoding:NSASCIIStringEncoding];
if (status == 1 && [ipacket length] != 0) {
[buffer insertString:ipacket atIndex:0];
numBytes = (int) [buffer length];
}
ipacket = [self processSerialData:buffer length:numBytes]; // Recompose data and save to database.
} else {
break; // Stop the thread if there is an error
}
}
// make sure the serial port is closed
if (serialFileDescriptor != -1) {
close(serialFileDescriptor);
serialFileDescriptor = -1;
}
// mark that the thread has quit
readThreadRunning = FALSE;
}
, 제공된 예를 따르면 다음과 같습니다 :
if (serialFileDescriptor != -1) {
[self appendToIncomingText:@"Trying to close the serial port...\n"];
close(serialFileDescriptor);
serialFileDescriptor = -1;
// Revisar... crec que el thread no s'adona que s'ha tancat el file descriptor...
// wait for the reading thread to die
while(readThreadRunning);
// re-opening the same port REALLY fast will fail spectacularly... better to sleep a sec
sleep(0.5);
//[btn setTitle:@"Start"];
[Start setTitle:@"Start"];
}
그러나 수신자 스레드가 전역 변수 serialFileDescriptor의 상태 변화를 인식하지 못하는 것으로 보입니다.
사람이 읽을 수있는 일반 텍스트 나 바이너리 데이터를 보낼 수 있습니까? NSString과 그 자손은 전자의 경우에만 사용해야합니다. 후자를 읽고 있다면 NSMutableData를 사용해야한다. –
또한,'buffer' /'ipacket' 댄스가 내가하는 일을하기위한 것이라는 가정하에, 그렇게하는 것이 훨씬 더 효율적인 방법이 있습니다. 'appendString :'또는'appendData :'를보십시오. –