Interrupts Disabled After First Context Switch

Joel Sherrill <joel@OARcorp.com> joel.sherrill at OARcorp.com
Thu Jan 5 21:43:33 UTC 2006


Kirspel, Kevin {Engineering - Osmetech CCD} wrote:
> During _Thread_Dispatch() I was printing the state of the SR register. I
> found that by the third context switch the interrupts were disabled
> going into _Thread_Dispatch().  So when _ISR_Disable() is called it
> returns the SR register with interrupts disabled.  Since the
> _ISR_Enable() routine just sets the SR register with the given level,
> interrupts are disabled even after the _ISR_Enable() call.  Is it
> possible to enter the _Thread_Dispatch() routine while interrupts are
> disable ( i.e. _ISR_Disable() was called prior to _Thread_Dispatch() )?

Yes.  Interrupt level is maintained across context switches on a per 
thread basis.

I suspect that the third context switch you see is actually from 
__ISR_Dispatch and that the level is somehow not being maintained across 
a preemption from ISR.

The sequence should be something like this for your test:

   (1) 1st context switch (initialization to 1st thread)
   (2) 1st thread to IDLE (wake after)
     ... clock tick isrs
   (3) IDLE to 1st thread FROM ISR!!

The FROM ISR on (3) is critical.  That puts you through the tail of 
__ISR_Handler and possibly needing some magic.  On other CPUs, that
code is tricky.  The SH code is straightforward but might be missing
something on the SH3/4.


> Kevin Kirspel
> Osmetech 
> 235 Hembree Park Drive
> Roswell GA, 30076
> 770-510-4444 x4568
> 
> 
> -----Original Message-----
> From: Joel Sherrill <joel at OARcorp.com>
> [mailto:joel.sherrill at OARcorp.com] 
> Sent: Thursday, January 05, 2006 1:04 PM
> To: Kirspel, Kevin {Engineering - Osmetech CCD}
> Cc: rtems-users at rtems.com
> Subject: Re: Interrupts Disabled After First Context Switch
> 
> Kirspel, Kevin {Engineering - Osmetech CCD} wrote:
> 
>>1) Renesas SH-3 but it's pretty much the same as the SH-4.
>>
>>2) the rtems_interrupt_disable() routine returns the value in the SR
>>register of the sh-3/4.  The SR register contains a BL bit that masks
>>interrupts.  It also contains an interrupt level mask that prevents
> 
> any
> 
>>interrupt lower than the level in the SR register from executing.  The
>>SH4 port sets the interrupt level to 15 to mask all interrupts (
>>rtems_interrupt_disable ).  Upon the printf statement below, the
>>interrupt level in the SR register is set to 15 masking all
> 
> interrupts.
> 
>>3)Yes.
>>
>>Case 1: using interrupt mask level 15 to disable interrupts. (
> 
> interrupt
> 
>>masks bits are bits 4-7 which is 0 before and F after).
>>INT BEFORE: 0x40001000
>>INT AFTER:  0x400011F1
>>
>>Case 2: using interrupt BL bit to disable interrupts. ( interrupt BL
> 
> bit
> 
>>is bit 28 which is 0 before and 1 after).
>>INT BEFORE: 0x40001000
>>INT AFTER:  0x50001101
> 
> 
> Is BL implicitly modified by an interrupt?  I don't know the SH well 
> enough to trace the code in my head but since you are doing a 
> delaying/blocking wake_after, there will be a context switch to IDLE, 
> then some clock tick ISRs, then a preempt of IDLE via the __ISR_Handler
> routine in cpu_asm.c.  If the BL bit is not preserved across the (a) 
> context switch or (b) interrupt preemption, then it might be what you 
> are seeing.
> 
> I do not think it is (a) because that is a simple load/store of the sr.
> 
> The __ISR_Handler code is always tricky to get right but I don't see how
> 
> it could be messed up either.
> 
> To eliminate some possibilities and assuming this is a single task test,
> 
> change the wake after(100) to wake after(0).  And do not print until 
> after all of the interrupt level changes.  I suspect it is the interrupt
> 
> context switch somehow.  Just a guess.
> 
> 
> 
> 
>>Kevin Kirspel
>>Osmetech 
>>235 Hembree Park Drive
>>Roswell GA, 30076
>>770-510-4444 x4568
>>
>>
>>-----Original Message-----
>>From: Joel Sherrill <joel at OARcorp.com>
>>[mailto:joel.sherrill at OARcorp.com] 
>>Sent: Thursday, January 05, 2006 11:20 AM
>>To: Kirspel, Kevin {Engineering - Osmetech CCD}
>>Cc: rtems-users at rtems.com
>>Subject: Re: Interrupts Disabled After First Context Switch
>>
>>Kirspel, Kevin {Engineering - Osmetech CCD} wrote:
>>
>>
>>>Upon entering a task, the interrupts at the hardware level are
>>
>>enabled.
>>
>>
>>>After a call to rtems_task_wake_after() the interrupts are disabled
>>
>>and
>>
>>
>>>remain disabled while the task is running.  What part of the code
>>
>>should
>>
>>
>>>I look at to diagnose this issue? It seems that interrupts get
>>
>>disabled
>>
>>
>>>before the task switch is performed.
>>>
>>>The code sample below illustrates what I am doing. At the first
>>>printf(), the interrupts are enabled.  After the second printf(), the
>>>interrupts are disabled.
>>>
>>>rtems_task GUITask ( rtems_task_argument ignored )
>>>{
>>> //Local Varaibles
>>> rtems_interrupt_level level;
>>>
>>> /* Wait 100ms til everyone is up and running */
>>> rtems_interrupt_disable(level);
>>> rtems_interrupt_enable(level);
>>> printf( "\r\nINT BEFORE: %08lX", level );
>>> rtems_task_wake_after( 10 );
>>> rtems_interrupt_disable(level);
>>> rtems_interrupt_enable(level);
>>> printf ( "\r\nINT AFTER: %08lX", level );
>>>}
>>
>>
>>I have more questions than answers.
>>
>>rtems_interrupt_enable/disable are implemented as inline assembly 
>>language routines.  They are port specific which leads to
>>
>>(1) Which CPU are you using?
>>
>>There is no guarantee on the contents of level after calling enable
>>so
>>
>>(2) are you sure they are really off?
>>
>>(3) can you print out the status register or whatever it is on this
> 
> CPU 
> 
>>and we really check?
>>
>>
>>
>>>Kevin Kirspel
>>>Osmetech 
>>>235 Hembree Park Drive
>>>Roswell GA, 30076
>>>770-510-4444 x4568
>>>
>>>
>>
>>
>>
> 
> 


-- 
Joel Sherrill, Ph.D.             Director of Research & Development
joel at OARcorp.com                 On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
    Support Available             (256) 722-9985




More information about the users mailing list