Go Down

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


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

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;

// 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"];
serialFileDescriptor = -1;
       // wait for the reading thread to die
// re-opening the same port REALLY fast will fail spectacularly... better to sleep a sec
       [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 ?


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

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131