This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: Re: ECOS: fatal error!
- From: Iztok Zupet <iz at vsr dot si>
- To: zhlg_shuhan <zhlg_shuhan at sina dot com>,ecos-discuss at sources dot redhat dot com
- Date: Wed, 26 Jun 2002 14:57:20 +0200
- Subject: Re: Re: [ECOS] ECOS: fatal error!
- Organization: VSR d.o.o.
- References: <20020626103346.20814.qmail@sina.com>
- Reply-to: iz at vsr dot si
On Wednesday 26 June 2002 12:33, zhlg_shuhan wrote:
> >Iztok zupet wrote :
> >Hi
> >
> > I think, that You just can't access the scheduler queue from an
> > interrupt (ISR) routine! No way. What you need to do is to write a DSR
> > for Your ISR and in that DSR You can only set up a driver condition to
> > notify a normal thread waiting for it, which can access the scheduler
> > queue after the condition becomes true.
> >Only a normal thread can access the scheduler queue, if You want to be
> > safe, not the ISR (interrupt service routine) or DSR (deferred service
> > routine).
> >
> >Regards
> >iz
>
> hello!
> Can I call bin_sem::post() in a interrupt routine(ISR/DSR)?
No You can't call semaphore::post from ISR/DSR directly. ! In fact, You can't
call kernel from there directly.
Instead You can do:
// counter I/O - low level interrupt handler (ISR)
static cyg_uint32 eop_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
_eop_int_info *intinfo = (_eop_int_info *) data;
cyg_drv_interrupt_mask(intinfo->int_num);
cyg_drv_interrupt_acknowledge(intinfo->int_num);
return CYG_ISR_CALL_DSR; // Cause DSR to be run
}
>>> In the ISR you Call the DSR (like in example).
// counter I/O - high level interrupt handler (DSR)
static void eop_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t
data)
{
_eop_int_info *intinfo = (_eop_int_info *) data;
cntdata *c = intinfo->eopdat;
pc_outb(c->port+3,0x34); // cnt0 to mode 2, still waiting for time constant
pc_outb(c->port+3,0x70); // cnt1 to mode 0, out to low, still waiting for
time constant
if (intinfo->drvcond) {
intinfo->drvcond->cond=true; // set variable also
cyg_drv_cond_broadcast(intinfo->drvcond->cnt_condition); /// set the
condition!!!
}
cyg_drv_interrupt_unmask(intinfo->int_num); // enable interrupts to happen
again
}
>>> In the DSR You just set the condition.
While in normal thread, you don' use semaphore to syncronize, but
cyg_drv_cond_wait.., which doesnt't wait for semaphore but for the condition,
you can set in the DSR.
Please read in the eCos manual more about ISR/DSR and about cyg_drv_cond...
> if I can ,you see,
> void Cyg_Binary_Semaphore::post()
> {
> // Prevent preemption
> Cyg_Scheduler::lock();
>
> CYG_INSTRUMENT_BINSEM( POST, this, 0 );
>
> state = true;
>
> if( !queue.empty() ) {
>
> // The queue is non-empty, so grab the next
> // thread from it and wake it up. The waiter
> // will clear the flag.
>
> Cyg_Thread *thread = queue.dequeue();
>
> thread->set_wake_reason( Cyg_Thread::DONE );
>
> thread->wake();
>
> CYG_INSTRUMENT_BINSEM( WAKE, this, thread );
> }
>
> // Unlock the scheduler and maybe switch threads
> Cyg_Scheduler::unlock();
>
> }
>
>
> so thread->wake() was called,which was listed:
>
>
> void
> Cyg_Thread::wake()
> {
> CYG_REPORT_FUNCTION();
>
> CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
>
> // Prevent preemption
> Cyg_Scheduler::lock();
>
> if( 0 != (state & SLEEPSET) )
> {
> // Set the state
> state &= ~SLEEPSET;
>
> // remove from any queue we were on
> remove();
>
> // If the thread is now runnable, return it to run queue
> if( state == RUNNING )
> Cyg_Scheduler::scheduler.add_thread(this);
>
> }
>
> // Unlock the scheduler and maybe switch threads
> Cyg_Scheduler::unlock();
>
> CYG_REPORT_RETURN();
> }
>
>
> remove()was called,so threadQueue race conditions occur!!!
>
> Right?
>
> zhlg
> ______________________________________
>
>
> ______________________________________
>
> ===================================================================
> 新浪免费电子邮箱 (http://mail.sina.com.cn)
> 新浪分类信息:二手市场走一走,该出手时就出手!
> (http://classad.sina.com.cn/2shou/)
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss