Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Synchronization Problem in Serial Com??

14 views
Skip to first unread message

fulltime

unread,
Oct 24, 2009, 11:07:07 AM10/24/09
to
I wud like to seek advice from fellow experts in this forum. The
description of the prob i face is as follows:

Objective:
1. to send data from 2 tasks, task A and B to the SAME serial port
2. task A sends data with even parity @ 5ms
3. task B sends data with odd parity @ 20ms
4. task A has a higher priority than task B, hence whenever task A
wants to send data, it pre-empts task B

Extract of my code

//taskA invokes this function if timer indicates 5ms is up
fiveMilliSec()
{
char data[10];
//codes to initialise data[10];

semTake(semSerial, WAIT_FOREVER); //mutex semaphore
taskAInvokedPrev = true;
if( taskBInvokedPrev )
{
taskDelay(1); //delay 1ms to allow time for prev taskB data in
output to send out
taskBInvokedPrev = false;
FD_ZERO (&writeFds);
FD_SET (fd, &writeFds);

tmo.tv_sec = 0; /* pend, waiting for fd to become ready */
tmo.tv_usec = 100;
if (select (fd+1, NULL, &writeFds, NULL, &tmo) == ERROR) {return
(ERROR); }

//codes to config to serial port even priority
}
nb = write (fd, data, 10); //send 10bytes at 1 shot
semGive(semSerial);
} //end fiveMilliSec()

//taskB invokes this function if timer indicates 20ms is up
twentyMilliSec()
{
char data[50];
//codes to initialise data[50];

semTake(semSerial, WAIT_FOREVER); //mutex semaphore
taskBInvokedPrev = true;
if( taskAInvokedPrev )
{
taskDelay(1); //delay 1ms to allow time for taskA data to send
out
taskAInvokedPrev = false;
FD_ZERO (&writeFds);
FD_SET (fd, &writeFds);

tmo.tv_sec = 0; /* pend, waiting for fd to become ready */
tmo.tv_usec = 100;
if (select (fd+1, NULL, &writeFds, NULL, &tmo) == ERROR) {return
(ERROR); }

//codes to config to serial port odd priority
}
semGive(semSerial);
while(i<50)
{
semTake(semSerial, WAIT_FOREVER); //hangs here
taskBInvoked = true;
nb = write (fd, data+i, 1); //send 1byte at a time
semGive(semSerial);
}
} //end twentyMilliSec()


main()
{
// codes to config port to odd parity (both tasks share the fd
returned by open port API)
//codes to spawn task A
//codes to spawn task B
//codes to start timers
}

Problem I faced:
1. codes hang after executing for some time(duration varies from 1min
to 30mins), it hangs at 2nd semTake() for twentyMilliSec()
2. the taskDelay() has no effect--> when i scope the output, there is
no 1ms delay (as stated in my taskDelay(1)) before sending out the
newly configured parity setting

I wonder why the codes always hangs at twentyMilliSec() semTake() when
taskA wants to send data. Isit possible that the write function in
twentyMilliSec() never return?

Would appreciate any advice given. Thanks a million!

Zac

unread,
Oct 29, 2009, 4:46:11 PM10/29/09
to
I see several problems here that may be causing you grief:

1) If the select() function call in fiveMilliSec() times out for some
reason (100 uSec is not a terribly long timeout) then the semaphore is
not given and neither of the tasks may send data again.
2) When sending data 1 byte at a time during the twentyMilliSec()
function, you may possibly be interrupted in between bytes by the
other task. This may be what you want, but you will still need to
reset the parity to odd on the serial port for each byte sent because
you don't know whether or not you were interrupted since the last time
you gave the semaphore.
3) I didn't study too closely, but I don't understand the purpose of
the taskAInvokedPrev and taskBInvokedPrev flags you are using. It
seems like the semaphore should be doing all of the synchronization
work for you.

0 new messages