Interrupts Disabled After First Context Switch
Kirspel, Kevin {Engineering - Osmetech CCD}
kevin.kirspel at osmetech.com
Fri Jan 6 15:01:20 UTC 2006
Actually I think it was 4.6.0pre4. I do have an SH-3 ( sh7727 ) port
with the DSP functionality disabled. When I added the SH-3 to the tree
I just cut and pasted the SH-4 port and made minor modifications. I
also changed the Makefile.am, Makefile.in, and configure files manually
in the tree. I don't know how to use the automake features so I just
modified the script files by cutting and pasting the sh-4 related lines
and modifying them. My code set is based off the 4.6.0pre4 and I have
now manually added some of the problem reports ( up to 4.6.5 ). So, my
code based is a combination of both releases. In the future I could
take the 4.6.5 release and add my SH-3 stuff to it but I would need help
on how to do this properly.
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: Friday, January 06, 2006 10:48 AM
To: Kirspel, Kevin {Engineering - Osmetech CCD}
Cc: Ian Caddy; rtems-users at rtems.com
Subject: Re: Interrupts Disabled After First Context Switch
Kirspel, Kevin {Engineering - Osmetech CCD} wrote:
> 4.6.0
>
> I see that the 4.6.5 version does not have the disable. I will upgrade
> my rtems today.
Checking cvsweb, I don't see two _ISR_Disable calls in the version
shipped. Are you sure you don't have some local modifications?
Also you are on an SH-3. Are there any CPU related patches that you
have that are not in the tree?
--joel
> 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: Friday, January 06, 2006 8:21 AM
> To: Ian Caddy
> Cc: Kirspel, Kevin {Engineering - Osmetech CCD}; rtems-users at rtems.com
> Subject: Re: Interrupts Disabled After First Context Switch
>
> Ian Caddy wrote:
>
>>Hi Kevin,
>>
>>Which version of RTEMS are you running. We have been looking through
>>watchdoginsert.c for another problem and in my version, which is from
>>4.6.5 there is no _ISR_Disable( level ) after the restart.
>
>
> Ditto for the code on the head of CVS. Which version of RTEMS is
this?
> Or which CVS Id is watchdoginsert.c?
>
>
>
>>That definitely looks wrong to me. You can not have 2 disables
>
> without
>
>>an enable in between them. In fact looking through that code, if the
>>restart is invoked, you will get more _ISR_Disable( level ) than just
>>the 2 as well.
>
>
> Right.
>
>
>
>>The cpukit/score/src/watchdoginsert.c in the 4.6.5 release is correct
>
> if
>
>>you want to have a look at that.
>>
>>regards,
>>
>>Ian Caddy
>>
>>
>>Kirspel, Kevin {Engineering - Osmetech CCD} wrote:
>>
>>
>>>I'm not sure this is a bug but I tracked down my problem to
>>>_Watchdog_Insert(). Below is the relevant code snippet. Upon
>
> entering
>
>>>watchdog insert the routine disables interrupts. This sets my
>
> interrupt
>
>>>level to 15 ( which blocks all interrupts ). The returned interrupt
>>>level from the _ISR_Disable() call shows that the previous interrupt
>>>level to be zero. This is correct. It then disables the interrupts
>>>again right after the restart label. Since the interrupt level is
>>>current 15 the returned interrupt level from the _ISR_Disable() is
>
> now
>
>>>15. When it finally enables interrupts at the end, the level is set
>
> to
>
>>>15 masking all interrupts. To fix the problem I commented out the
>>>_ISR_Disable() right below the restart label. Is this a bug or is
>
> rtems
>
>>>intended to work this way?
>>>
>>>void _Watchdog_Insert(
>>> Chain_Control *header,
>>> Watchdog_Control *the_watchdog
>>>)
>>>{
>>> ISR_Level level;
>>> Watchdog_Control *after;
>>> unsigned32 insert_isr_nest_level;
>>> Watchdog_Interval delta_interval;
>>>
>>>
>>> insert_isr_nest_level = _ISR_Nest_level;
>>>
>>> _ISR_Disable( level );
>>>
>>> /*
>>> * Check to see if the watchdog has just been inserted by a
>>> * higher priority interrupt. If so, abandon this insert.
>>> */
>>>
>>> if ( the_watchdog->state != WATCHDOG_INACTIVE ) {
>>> _ISR_Enable( level );
>>> return;
>>> }
>>>
>>> the_watchdog->state = WATCHDOG_BEING_INSERTED;
>>>
>>> _Watchdog_Sync_count++;
>>>
>>>restart:
>>> delta_interval = the_watchdog->initial;
>>>
>>> _ISR_Disable( level ); //I commented this Disable to fix problem
>>>
>>>for ( after = _Watchdog_First( header ) ;
>>> ;
>>> after = _Watchdog_Next( after ) ) {
>>>
>>> if ( delta_interval == 0 || !_Watchdog_Next( after ) )
>>> break;
>>>
>>> if ( delta_interval < after->delta_interval ) {
>>> after->delta_interval -= delta_interval;
>>> break;
>>> }
>>>
>>> delta_interval -= after->delta_interval;
>>>
>>> /*
>>> * If you experience problems comment out the _ISR_Flash line.
>>> * 3.2.0 was the first release with this critical section
>>>redesigned.
>>> * Under certain circumstances, the PREVIOUS critical section
>>>algorithm
>>> * used around this flash point allowed interrupts to execute
>>> * which violated the design assumptions. The critical section
>>> * mechanism used here WAS redesigned to address this.
>>> */
>>>
>>> _ISR_Flash( level );
>>>
>>> if ( the_watchdog->state != WATCHDOG_BEING_INSERTED ) {
>>> goto exit_insert;
>>> }
>>>
>>> if ( _Watchdog_Sync_level > insert_isr_nest_level ) {
>>> _Watchdog_Sync_level = insert_isr_nest_level;
>>> goto restart;
>>> }
>>> }
>>>
>>> _Watchdog_Activate( the_watchdog );
>>>
>>> the_watchdog->delta_interval = delta_interval;
>>>
>>> _Chain_Insert_unprotected( after->Node.previous,
>
> &the_watchdog->Node
>
>>>);
>>>
>>> the_watchdog->start_time = _Watchdog_Ticks_since_boot;
>>>
>>>exit_insert:
>>> _Watchdog_Sync_level = insert_isr_nest_level;
>>> _Watchdog_Sync_count--;
>>> _ISR_Enable( level );
>>>}
>>>
>>>
>>>
>>>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
>>>4:44 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:
>>>
>>>
>>>>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