Go Down

Topic: Serial code in Cocoa (Mac) cannot close communication. (Read 351 times) previous topic - next topic

joanba

Mar 07, 2013, 08:40 am Last Edit: Mar 07, 2013, 09:04 am by Coding Badly Reason: 1
Hi,

I've used the provided example in http://playground.arduino.cc/Interfacing/Cocoa, the one that uses IOKit/ioctl in order to receive serial data from an Arduino UNO and send it to a Mac mini. I've done some changes but the serial code has not changed. I'm able to receive data normally but I've a problem when I stop the application and close the communication, simply it hangs and the only way to close the application is killing it.

The serial port is open with this code:

Code: [Select]
if (serialFileDescriptor == -1) {
// check if the port opened correctly
errorMessage = @"Error: couldn't open serial port";
} else {
// TIOCEXCL causes blocking of non-root processes on this serial-port
success = ioctl(serialFileDescriptor, TIOCEXCL);
if ( success == -1) {
errorMessage = @"Error: couldn't obtain lock on serial port";
} else {
success = fcntl(serialFileDescriptor, F_SETFL, 0);
if ( success == -1) {
// clear the O_NONBLOCK flag; all calls from here on out are blocking for non-root processes
errorMessage = @"Error: couldn't obtain lock on serial port";
} else {
// Get the current options and save them so we can restore the default settings later.
success = tcgetattr(serialFileDescriptor, &gOriginalTTYAttrs);
if ( success == -1) {
errorMessage = @"Error: couldn't get serial attributes";
} else {
// copy the old termios settings into the current
//   you want to do this so that you get all the control characters assigned
options = gOriginalTTYAttrs;

/*
cfmakeraw(&options) is equivilent to:
options->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
options->c_oflag &= ~OPOST;
options->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
options->c_cflag &= ~(CSIZE | PARENB);
options->c_cflag |= CS8;
*/
cfmakeraw(&options);

// set tty attributes (raw-mode in this case)
success = tcsetattr(serialFileDescriptor, TCSANOW, &options);
if ( success == -1) {
errorMessage = @"Error: coudln't set serial attributes";
} else {
// Set baud rate (any arbitrary baud rate can be set this way)
success = ioctl(serialFileDescriptor, IOSSIOSPEED, &baudRate);
if ( success == -1) {
errorMessage = @"Error: Baud Rate out of bounds";
} else {
// Set the receive latency (a.k.a. don't wait to buffer data)
success = ioctl(serialFileDescriptor, IOSSDATALAT, &mics);
if ( success == -1) {
errorMessage = @"Error: coudln't set serial latency";
}
}
}
}
}
}
       }


And the port is closed when a button is pressed in the graphical interface with this code, also from the examples:

Code: [Select]
if (serialFileDescriptor != -1) {
       [self appendToIncomingText:@"Trying to close the serial port...\n"];
       close(serialFileDescriptor);
serialFileDescriptor = -1;
       
       // 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);
       
       [Start setTitle:@"Start"];
   }


The application hangs in the close function.

I've tried several things, different parameters and settings at open time, but basically the result is always the same: it hangs in the close function.

Does anybody have solved this issue ?

Regards,
Joan


Moderator edit: [code] [/code] tags added.

Go Up