Interrupt handling pattern (OSIntEnter vs. OSIntEnterWAS)
Posted: Tue Nov 11, 2014 10:59 am
Hi,
I see that OSIntEnter( ) is still declared in <ucos.h>, but defined as OSIntEnterWAS( ) in ucos.c. Is there a reason for this mismatch? (I'm using NNDK 2.6.8 if that makes any difference.) The matching OSIntExit( ) is still declared and defined correctly.
From the uCOS documentation I understand that I should be wrapping my interrupt handler in an enter/exit pair to prevent a task waiting on a semaphore from inadvertently executing before the ISR returns. Is the following pattern correct to not execute system calls from the interrupt handler? What is the correct way to call OSIntEnter( )?
Also, is there a reason why SetPinIrq( ) doesn't take a context pointer of some sort (similar to OSTaskCreate( ) for example) so a single ISR can trampoline out to a bunch of different processing tasks?
Thanks!
I see that OSIntEnter( ) is still declared in <ucos.h>, but defined as OSIntEnterWAS( ) in ucos.c. Is there a reason for this mismatch? (I'm using NNDK 2.6.8 if that makes any difference.) The matching OSIntExit( ) is still declared and defined correctly.
From the uCOS documentation I understand that I should be wrapping my interrupt handler in an enter/exit pair to prevent a task waiting on a semaphore from inadvertently executing before the ISR returns. Is the following pattern correct to not execute system calls from the interrupt handler? What is the correct way to call OSIntEnter( )?
Also, is there a reason why SetPinIrq( ) doesn't take a context pointer of some sort (similar to OSTaskCreate( ) for example) so a single ISR can trampoline out to a bunch of different processing tasks?
Thanks!
Code: Select all
// need a singleton semaphore instance somewhere because we can't get a ctx pointer into the interrupt handler?
OS_SEM myObj::IRQ1OSSem;
void myObject::HandleInterrupt( /* no ctx ptr possible? */ ) {
OSIntEnter( ); // undefined, implemented in ucos.c as OSIntEnterWAS( )
OSSemPost( &IRQ1OSSem );
OSIntExit( );
}
// Make sure the stack is 4 byte aligned to keep the Coldfire happy
DWORD ProcessTaskStack[ USER_TASK_STK_SIZE ] __attribute__( ( aligned( 4 ) ) );
void myObject::ProcessTask( void *ctx ) {
myObject *obj = ( myObject * ) ctx;
while ( 1 ) {
uint8_t status = OSSemPend( &IRQ1OSSem, 0 /* wait forever */ );
if ( status == OS_NO_ERR ) {
obj->doStuff( ); // do some higher latency system calls here outside of the interrupt handler
} else {
iprintf("task: ERROR - OSSemPend() returned %d\n", status);
}
}
}
myObject::myObject( ) {
// set up processing task
OSTaskCreate( ProcessTask,
this,
&ProcessTaskStack[ USER_TASK_STK_SIZE ],
ProcessTaskStack,
MAIN_PRIO + 1 );
OSSemInit( &IRQ1OSSem, 0 );
// init interrupt
J2[ 45 ].function( PINJ2_45_IRQ1 ); // IRQ1 = pin 45
SetPinIrq( 45, -1, &HandleInterrupt ); // active low
}