Interrupts Disabled After First Context Switch

Kirspel, Kevin {Engineering - Osmetech CCD} kevin.kirspel at osmetech.com
Thu Jan 5 17:55:19 UTC 2006


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() )?

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