Pages: [1]   Go Down
Author Topic: Serial code in Cocoa (Mac) cannot close communication.  (Read 338 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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.
« Last Edit: March 07, 2013, 03:04:52 am by Coding Badly » Logged

Pages: [1]   Go Up
Jump to: