Pumpkin, Inc.

Pumpkin User Forums

OS_WaitEFlag

If you can't make Salvo do what you want it to do, post it here.

OS_WaitEFlag

Postby aek » Thu Feb 23, 2006 3:07 am

See http://www.pumpkininc.com/ubb/Forum12/HTML/000014.html. This is a known problem in Salvo v3.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: OS_WaitEFlag

Postby jeffc » Thu Feb 23, 2006 12:46 pm

I'm seeing some odd behavior from OS_WaitEFlag in some test code I'm running. I'm developing test cases to verify that the OS calls I'm using in my application function as defined in the Salvo manual.

I've boiled my test app down to basically the following code. It's been cut-n-pasted from a couple of files, but should give an idea of what I'm trying to do.

The problem I'm seeing is in TestCase(). I expect the call to OS_WaitEFlag() to hang there forever as Task_A() doesn't set it's completion bit. However, that's not what happens. As soon as Task_B() runs and sets its completion bit, the wait expires and the test case finishes.

Any idea what I'm doing wrong?

thanks,
Jeff
jeffc@logicpd.com

code:

/*! Macro used to verify that an OS call succeeded. If it doesn't succeed,
* the current test fails.
* hideinitializer
*/
#define OS_VERIFY_VOID(ret,line)
do {
OStypeErr os_error = (ret);
DEBUG_OSVerify( os_error, __FILE__, (line) );
} while( 0 )

/*!
* Macro to be used in place of c OSSignalBinSem()
* hideinitializer
*/
#define OSSAFESignalBinSem(ecbp)
do {
OSProtect();
OS_VERIFY_VOID( OSSignalBinSem( ecbp )
,__LINE__
);
OSUnprotect();
} while (0)

/*!
* Macro to be used in place of c OSSetEFlag()
* hideinitializer
*/
#define OSSAFESetEFlag(ecbp,mask)
do {
OSProtect();
OS_VERIFY_VOID( OSSetEFlag( ecbp, mask )
,__LINE__
);
OSUnprotect();
} while (0)

/*!
* Macro to be used in place of c OSClrEFlag()
* hideinitializer
*/
#define OSSAFEClrEFlag(ecbp,mask)
do {
OSProtect();
OS_VERIFY_VOID( OSClrEFlag( ecbp, mask )
,__LINE__
);
OSUnprotect();
} while (0)

/*-------------------------------------------------------------------------- */

#define OSTEST_MONITOR_TCB_P TEST_TCBP_NUMBER_1
#define OSTEST_TEST_CASE_TCB_P TEST_TCBP_NUMBER_2
#define OSTEST_TASK_A_TCB_P TEST_TCBP_NUMBER_3
#define OSTEST_TASK_B_TCB_P TEST_TCBP_NUMBER_4

/* Binary Semaphores */
#define OSTEST_CASE_ECB_P TEST_ECBP_NUMBER_1

/* Event Flags */
#define OSTEST_RESULT_ECB_P TEST_ECBP_NUMBER_5
#define OSTEST_RESULT_EFCB_P TEST_EFCBP_NUMBER_1

#define OSTEST_FAILED 0x01
#define OSTEST_COMPLETE_A 0x02
#define OSTEST_COMPLETE_B 0x04

#define OSTEST_COMPLETED_2_TASKS (
OSTEST_COMPLETE_A
| OSTEST_COMPLETE_B
)

/*-------------------------------------------------------------------------- */

_OSLabel(OS_TEST_STOP);

_OSLabel(TEST_CASE_FINISH);

_OSLabel(TEST_CASE_1);
_OSLabel(TEST_CASE_STOP);

_OSLabel(TASK_A_STOP);
_OSLabel(TASK_B_STOP);

/*-------------------------------------------------------------------------- */

void TestMonitor( void );
void TestCase( void );
void Task_A( void );
void Task_B( void );
void DisplayResults( OStypeEFlag eFlag );

/*-------------------------------------------------------------------------- */

void TestMonitor( void )
{
DPRINTF(( "Begin...
" ));

/* Create event flag to indicate if a single test case passed or failed */
OS_VERIFY_VOID( OSCreateEFlag( OSTEST_RESULT_ECB_P
,OSTEST_RESULT_EFCB_P
,0
)
,__LINE__
);

/* Create a binary semaphore to indicate when a set of test cases are
* finished. */
OS_VERIFY_VOID( OSCreateBinSem( OSTEST_CASE_ECB_P, 0 )
,__LINE__
);

/*---------------------------------------------------------------------- */

OS_VERIFY_VOID( OSCreateTask( TestCase
,OSTEST_TEST_CASE_TCB_P
,PRIORITY_OSTEST_TASK_MONITOR
)
,__LINE__
);

OS_WaitBinSem( OSTEST_CASE_ECB_P, OSNO_TIMEOUT, TEST_CASE_FINISH );

/*---------------------------------------------------------------------- */

DPRINTF(( "Complete...
" ));

/* Terminate the test monitor */
OS_Destroy( OS_TEST_STOP );
}

void TestCase( void )
{
DPRINTF(( "Create two tasks
" ));

OS_VERIFY_VOID( OSCreateTask( Task_A
,OSTEST_TASK_A_TCB_P
,PRIORITY_OSTEST_TASK_HIGH
)
,__LINE__
);

OS_VERIFY_VOID( OSCreateTask( Task_B
,OSTEST_TASK_B_TCB_P
,PRIORITY_OSTEST_TASK_HIGH
)
,__LINE__
);

DPRINTF(( "Should hang here forever
" ));

OS_WaitEFlag( OSTEST_RESULT_ECB_P
,OSTEST_COMPLETED_2_TASKS
,OSALL_BITS
,OSNO_TIMEOUT
,TEST_CASE_1
);

DisplayResults( OSReadEFlag( OSTEST_RESULT_ECB_P ) );

/*---------------------------------------------------------------------- */

OSSAFESignalBinSem( OSTEST_CASE_ECB_P );

/* Terminate the task */
OS_Destroy( TEST_CASE_STOP );
}

void Task_A( void )
{
DPRINTF(( "Task A doesn't set its complete bit
" ));

/* Terminate the task */
OS_Destroy( TASK_A_STOP );
}

void Task_B( void )
{
DPRINTF(( "Task B is complete
" ));

OSSAFESetEFlag( OSTEST_RESULT_ECB_P, OSTEST_COMPLETE_B );

/* Terminate the task */
OS_Destroy( TASK_B_STOP );
}

/*-------------------------------------------------------------------------- */

void DisplayResults( OStypeEFlag eFlag )
{
/* We only flag if a test fails. If a test is completed and has not failed
* by definition it has passed.
*/
if( eFlag & OSTEST_FAILED )
{
DPRINTF(( "test failed
" ));
}
else
{
DPRINTF(( "test passed
" ));
}

/* Clear the flag */
OSSAFEClrEFlag( OSTEST_RESULT_ECB_P, 0xff );
}

void main(void)
{
/* Initialize Salvo */
OSInit();

/* Enable interrupts */
INTR_EnableInterrupts();

/* Enable watchdog */
WATCHDOG_Initialize();

/* Initialize debug channel */
DEBUG_Initialize();

OS_VERIFY_VOID( OSCreateTask( TestMonitor
,OSTEST_MONITOR_TCB_P
,PRIORITY_OSTEST_TASK_MONITOR
)
,__LINE__
);

DPRINTF(( "Salvo Test Framework
" ));

for( ;; )
{
OSSched();
}
}


jeffc
 
Posts: 8
Joined: Thu Oct 27, 2005 11:00 pm

Re: OS_WaitEFlag

Postby jeffc » Fri Feb 24, 2006 8:53 am

It seems that the problem I was having is due to the fact that the manual is a bit confusing on the topic of waiting on events flags.

For example, even though the caller of OS_WaitEFlag() can wait for OSANY_BITS, OSALL_BITS or OSEXACT_BITS, those combinations are only evaluated once when the call is made. Once that task switches to waiting they're not evaluated again. Once any bit is set in the event flag, all the tasks waiting on the event flag are woken up and will continue running whether or not the current state of the flag matches the mask that the task was waiting on.

If this is the desired behavior, it would be helpful for the manual to clearly state that in chapter 7.

I ended up creating a macro to make my tasks really wait until all bits where set:

code:

#define OS_WAIT_ALL_EVENTS_SET( flag, mask, label )
do {
OS_WaitEFlag( (flag)
,(mask)
,OSANY_BITS
,OSNO_TIMEOUT
,label
);
} while( !( OSReadEFlag( (flag) ) == (mask) ) )

Also, the existance of OSEXACT_BITS would seem to imply that tasks should be woken up when a bit is cleared in an EFlag as well as set.

Just some of my thoughts from using EFlags.

thanks,
Jeff
jeffc@logicpd.com

quote:
Originally posted by aek:
See http://www.pumpkininc.com/ubb/Forum12/HTML/000014.html. This is a known problem in Salvo v3.



jeffc
 
Posts: 8
Joined: Thu Oct 27, 2005 11:00 pm

Re: OS_WaitEFlag

Postby aek » Fri Feb 24, 2006 9:12 am

Hi Jeff.

The status of the event flag is evaluated in every OS_WaitEFlag() call. When a bit in the eFlag is set (via OSSignalEFlag()), as long as the eFlag has changed, all waiting tasks will be woken, all conditions will be re-evaluated, and any that do not match will go back to waiting.

Note that unlike the other Salvo events, eFlag bits are not "reset" by the successful waiting of an eFlag. That's why OSClrEFlag() exists. If you're not clearing the eFlag that "triggered" a particular task into waking up (and continuing), then said task will continue "through" its OS_WaitEflag() calls indefinitely until that bit is cleared via OSClrEFlag().

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: OS_WaitEFlag

Postby jeffc » Fri Feb 24, 2006 9:40 am

I want to make sure I'm following you correctly. If I have a task that makes the following sequence of calls:

code:

OSCreateEFlag( FLAG_A_ECB, FLAG_A_EFCB, 0x0 );
printf( "a" );
OS_WaitEFlag( FLAG_A_ECB, 0x03, OSALL_BITS, OSNO_TIMEOUT, LABEL_1);
printf( "b" );

Then the expected output should be:

a

Correct?

Now, what should happen if another task makes the following sequence of calls:

code:

OSProtect();
OSSignalEFlag( FLAG_A_ECB, 0x01 );
OSUnprotect();

What I would expect from your statement is that no new output should be printed since only one of the two flags required was set.

However, what I'm seeing in my test code is that once any bit is set (even though I specified OSALL_BITS), the task wakes up an continues.

Am I seeing the result you'd expect me to see?

If not, do you have an email address that I can send a MPLAB project and my test code to?

I'm using the HI-TECH PICC-18 compiler v8.35PL3.

thanks,
Jeff
jeffc@logicpd.com

quote:
Originally posted by aek:
Hi Jeff.

The status of the event flag is evaluated in every OS_WaitEFlag() call. When a bit in the eFlag is set (via OSSignalEFlag()), as long as the eFlag has changed, all waiting tasks will be woken, all conditions will be re-evaluated, and any that do not match will go back to waiting.

Note that unlike the other Salvo events, eFlag bits are not "reset" by the successful waiting of an eFlag. That's why OSClrEFlag() exists. If you're not clearing the eFlag that "triggered" a particular task into waking up (and continuing), then said task will continue "through" its OS_WaitEflag() calls indefinitely until that bit is cleared via OSClrEFlag().


jeffc
 
Posts: 8
Joined: Thu Oct 27, 2005 11:00 pm

Re: OS_WaitEFlag

Postby aek » Fri Feb 24, 2006 10:03 am

quote:
Am I seeing the result you'd expect me to see?
The first part ('a') -- yes. The second part ('b') -- no.

Send the project to support. Note that I we can only evaluate it only using direct Salvo calls, and not your macro wrappers.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: OS_WaitEFlag

Postby Salvo Tech Support » Tue Feb 28, 2006 11:16 am

Identified as a problem with eFlags and OSENABLE_FAST_SIGNALING. Please see SB-28.

------------------
--------
Salvo Technical Support
Please request all tech support through the Forums.

--------
Salvo Technical Support
Please request all tech support through the Forums.
Salvo Tech Support
 
Posts: 173
Joined: Sun Nov 19, 2000 12:00 am


Return to Coding

Who is online

Users browsing this forum: No registered users and 3 guests

cron