• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How to set scheduling in NSThread based application
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to set scheduling in NSThread based application


  • Subject: Re: How to set scheduling in NSThread based application
  • From: Gilles Celli <email@hidden>
  • Date: Mon, 12 Feb 2007 22:02:49 +0100

Shawn,

Thanks for your quick reply.
To get the data from the multimeter a 'READ' command is sent to it every 0.5seconds.


I'm polling with gettimeofday() the time, and sleeping with a nanosleep of 250000000L after the acquisition, something like this:
I wonder in fact if this is the right way to do it.... so please don't laugh at my hobbyist-programming horror code ;-)


So here comes the first execution after detaching the first NSThread:
// Start and loop the acquisition until the user clicked the button 'Disconnect'

while ( threadIsRunning ) {


gettimeofday(&tval, NULL);

if ( ( tval.tv_usec == SECOND_ZERO ) || (tval.tv_usec == HALF_SECONDS_IN_MICROSEC ) )
{
// Read one shot from the Keithley 2700 multimeter as string
k2700_read_data( fdSerial, keithleyRawDataBufferCString );

// Store data
supraData[currentRow].supraChannel = atof ( keithleyRawDataBufferCString );
....
....


			// Write data
			tsoft_file_handler(....);

		nanosleep()
		}

}
	


I first open the device like this:

int openSerialPort(const char *deviceFilePath)
{
int fileDescriptor = -1;

static struct termios gOriginalTTYAttrs;

struct termios rs232_attr;

fileDescriptor = open(deviceFilePath, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);
...
...
rs232_attr = gOriginalTTYAttrs;

//printf("Current input baud rate is %d\n", (int) cfgetispeed (&rs232_attr));
//printf("Current output baud rate is %d\n", (int) cfgetospeed (&rs232_attr));

// Clear struct for new port settings
bzero( &rs232_attr, sizeof(rs232_attr) );

// Set Baudrate to 9600 bps by default
cfsetospeed( &rs232_attr, B9600);
cfsetispeed( &rs232_attr, B9600); // this line is important

// CS8 : 8n1 (8bit, no parity, 1 stopbit)
// CLOCAL : local connection, no modem control
// CREAD : enable receiving characters
// Enable the receiver and set local mode...
rs232_attr.c_cflag |= (CLOCAL | CREAD);

// Character and parity settings No parity (8N1):
rs232_attr.c_cflag |= CS8;
rs232_attr.c_cflag &= ~PARENB; // Set NO parity
rs232_attr.c_cflag &= ~CSTOPB; // Set 1 Stop Bit
rs232_attr.c_cflag &= ~CSIZE;



// Set raw input (non-canonical) mode, with reads blocking until either a single character
// has been received or a one second timeout expires.
// See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") for details.
cfmakeraw(&rs232_attr);
rs232_attr.c_cc[VMIN] = 1;
rs232_attr.c_cc[VTIME] = 10;


}

for Reading data:
void k2700_read_data( int fileDescriptor, char *k2700Buffer )
{
if ( write( fileDescriptor, ":READ?\r", 7) == -1)

// Read characters into our buffer until we get a CR or LF
bufPtr = buffer;
do
{
numBytes = read(fileDescriptor, bufPtr, &buffer[sizeof(buffer)] - bufPtr - 1);
if (numBytes == -1)
printf("Error reading from modem - %s(%d).\n", strerror(errno), errno);
else if (numBytes > 0)
{
bufPtr += numBytes;
if (*(bufPtr - 1) == '\n' || *(bufPtr - 1) == '\r')
{
break;
}
}

else {
printf("Nothing read.\n");
}
} while (numBytes > 0);


// NUL terminate the string and see if we got an OK response
*bufPtr = '\0';
// Example of 'buffer' output for 16 channels read from the Keithley 2700
// -3.80132586E-01VDC,-3.86980623E-01VDC,-3.94014210E-01VDC,-4.01051730E-01 VDC,-4.08394873E-01VDC,-4.15606618E-01VDC, 4.22780007E-01VDC,-4.29845721E-01VDC,-4.42195922E-01VDC,-4.49257135E-01V DC,-4.56305921E-01VDC,-4.63421822E-01VDC,-4.70700681E-01VDC,-4.77828979E -01VDC,-4.85090911E-01VDC,-4.92547929E-01VDC

// Extract the value of each channel without UNITS (VDC) and put them in an 'k2700Buffer'
// For performance reason we don't use a for() loop

k2700Buffer[0] = buffer[0];
k2700Buffer[1] = buffer[1];
k2700Buffer[2] = buffer[2];
k2700Buffer[3] = buffer[3];
k2700Buffer[4] = buffer[4];
k2700Buffer[5] = buffer[5];
k2700Buffer[6] = buffer[6];
k2700Buffer[7] = buffer[7];
k2700Buffer[8] = buffer[8];
k2700Buffer[9] = buffer[9];
k2700Buffer[10] = buffer[10];
k2700Buffer[11] = buffer[11];
k2700Buffer[12] = buffer[12];
k2700Buffer[13] = buffer[13];
k2700Buffer[14] = buffer[14];
k2700Buffer[15] = (char)0; // We stop here by appending a '\0' to proper end string k2700Buffer[]
// since we don't want to append the chars "VDC" for function atof()


}	




On Feb 12, 2007, at 5:57 PM, Shawn Erickson wrote:

On 2/12/07, Shawn Erickson <email@hidden> wrote:
On 2/12/07, Gilles Celli <email@hidden> wrote:
> Hi,
>
> I've written a data acquisition-program under Cocoa which detach 2
> new NSThreads:
>
> One which collects data every 0.5 seconds (full second and
> millisecond 500 via gettimeofday()) from a multimeter via USB-to-
> Serial Adapter,
> and another one which displays the graph of the data in NSTableView
> and with the Open-Source-Based
> SM2DGraphView.
...snip...
> Any suggestions are greatly appreciated.


500 milliseconds is 50 times larger then the current scheduling
quantum. I really don't think thread scheduling is an issue.... unless
you have to capture something in a relatively narrow time period (i.e.
500 ms +/- a few to 10s of milliseconds).


Are you sure you are not affected by clock skew introduced in the way
you are calculating times? Or by some contested lock you are using to
protect the data you are capturing and displaying?

Another possibility, not knowing how your capture thread is coded, is that your capture thread is chewing to much CPU time (polling to quickly) and as a result its priority gets suppressed due to fairness and every now and then due to it lower priority loses out to another thread with higher priority at just the wrong time.

-Shawn


_______________________________________________

Cocoa-dev mailing list (email@hidden)

Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: How to set scheduling in NSThread based application
      • From: "Shawn Erickson" <email@hidden>
References: 
 >How to set scheduling in NSThread based application (From: Gilles Celli <email@hidden>)
 >Re: How to set scheduling in NSThread based application (From: "Shawn Erickson" <email@hidden>)
 >Re: How to set scheduling in NSThread based application (From: "Shawn Erickson" <email@hidden>)

  • Prev by Date: Re: Very strange Cocoa application issue.
  • Next by Date: Re: Core Data, bindings and synchronizing.
  • Previous by thread: Re: How to set scheduling in NSThread based application
  • Next by thread: Re: How to set scheduling in NSThread based application
  • Index(es):
    • Date
    • Thread