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