Asynchronously turning off and on interrupts in the main body of your
code is problematic. Instead of tempting fate; I decided to play the
overly-cautious role. It is the following excerpt from the Philips
User Manual that gave me pause:
"Although the example shows both IRQ and FIQ interrupts being
disabled, similar behavior occurs when only one of the two
interrupt types is being disabled. The fact that the core processes
the IRQ after completion of the MSR instruction which disables
IRQs does not normally cause a problem, since an interrupt arriving
just one cycle earlier would be expected to be taken. When
the interrupt routine returns with an instruction like:
SUBS pc, lr, #4
the SPSR_IRQ is restored to the CPSR. The CPSR will now have the I bit
and F bit set, and therefore execution will continue
with all interrupts disabled."
So....instead of taking the 'easy way' I decided to create a system
where I had a reasonable, (probably overkill), that the system would
work under all circumstances.
I really hate debugging spurious stuff. I have done this too many
times on those fully pipelined DSP architectures...and did not want to
tempt it this time with the ARM7TDMI.
I am sure, that over time, doing the simple turning interrupts on and
off at will may work, with little detrimental effect...however, from
what I read in the ARM website, and the Philips User Manual...
Let us say, I am pretty sure that the methods I proposed...albeit a
bit more long-winded and non-trivial; are assured to work in all
cases.
So far; I have not been called in on any suspected crashes, system
glitches, and intermittent Watchdogs...and this on equipment that is
operating 24x7 with full status monitoring for DOG events.
Ken Wada
--- In lpc2000@yahoogroups.com, "brendanmurphy37" <brendan.murphy@i...
> wrote:
>
>
> Ken,
>
> If you follow workaround 1 in the ATMEL app note (and some of the
> examples in some of the ARM documentation) referred to in the other
> response to this, you can simplify greatly the code for what you're
> trying to achieve in relation to locking out both IRQ and FIQ
> interrupts.
>
> As I mentioned in my previous response to this, we spent a lot of
> time looking into this whole area. We ended up writing our own IRQ
> pre-amble and post-amble code to ensure we had the correct
> environment i.e. no modification of the SPSR, interrupts disabled
> for the minimum length of time, ability to call standard 'C'
> function as the main body of the interrupt handler (i.e. no need for
> special __interrupt modifier of any kind etc. etc.)
>
> I say "writing our own", but it was pretty much a copy of an ARM
> example, which we modified to load the 'C' handler from the VIC. I
> don't have the particular document to hand, but it's available from
> the ARM Web site.
>
> As you say, it was all a lot easier in the 8-bit world, but given
> the choice, I know which I'd take....
>
> Brendan
>
> --- In lpc2000@yahoogroups.com, "Ken Wada" <kwada@a...> wrote:
> >
> > --- In lpc2000@yahoogroups.com, "brendanmurphy37"
> <brendan.murphy@i...
> > > wrote:
> > >
> > >
> > > Ken,
> > >
> > > Can you explain why you think there's a problem with an
> interrupt
> > > between the two writes?
> > >
> > > According to the User Manual: "Once 0xAA is written to
> > > the WDFEED register the next operation in the Watchdog register
> > space
> > > should be a WRITE (0x55) to the WDFFED register otherwise the
> > > watchdog is triggered."
> > >
> > > I take this to mean that the next write to the WDFEED register
> has
> > to
> > > be 0x55 following the 0xaa: why should it matter if this is one
> > cycle
> > > on, or 1000 cycles on (e.g. to take account of any interrupt)?
> I'm
> > > assuming here that the interrupt itself doesn't go near the
> > watchdog.
> > It makes a bit difference! If you WRITE (0x55), the processor
> expects
> > a WRITE(0xAA) on the very next cycle. If this is done outside an
> > interrupt context, the interrupt service routine will pretty much
> > guarantee that this condition is violated!
> >
> > >
> > > Also, for disabling interrupts, why not just disable IRQ and FIQ
> in
> > > the same write to the CPSR? Is there some problem with this?
> > Yep...huge problem. Actually, you will see this type of problem
> with
> > many processors/especially DSP's with fully pipelined
> architecture.
> > The Philips User manual calls this the spurious interrupt problem.
> > Actually, Philips basically took their cautionary note directly
> from
> > the ARM users guide.
> >
> > Gone are the good-old days of doing something like EA=0, as per
> 8051..
> > .these pipelined architectures are a bit different when it comes
> to
> > instruction processing.
> >
> > Fortunately, all of these modern architectures give you a way to
> do
> > these types of operations, (albeit with a bit more effort), via
> some
> > software interrupt (SWI) instruction.
> >
> > My 1st encounter with this was with the Intel 80386 chip. This
> chip
> > had an instruction pipeline, and I had to use the int86() SWI
> command
> > in order to properly code up the atomic sections.
> >
> > Ken Wada
> > >
> > > regards
> > > Brendan
> > >
> > >
> > > --- In lpc2000@yahoogroups.com, "Ken Wada" <kwada@a...> wrote:
> > > >
> > > > Basically, your method works fine...
> > > > UNTIL: you start adding interrupt service routines!
> > > >
> > > > This is why:
> > > > void WDOG_pet()
> > > > {
> > > > WDFEED = 0xAA;
> > > > /* Interrupt occurs here...> dog will NOT pet
> > > properly!!!
> > > > ***/
> > > > WDFEED = 0x55;
> > > > }
> > > >
> > > > /**** example uses Keil compiler directives ***/
> > > > /********** The following is what I wound up doing, (gotta
> avoid
> > > that
> > > > spurious interrupt issue with the ARM also!!! ***/
> > > >
> > > > /**** The actual interface that everybody uses ***/
> > > > void WDOG_pet (void)
> > > > {
> > > > SYSSWI_service (12,0,0,0);
> > > > }
> > > >
> > > > /***** How the SYSSWI_service works, (based on SWI) ***/
> > > > unsigned SYSSWI_service (SYSSWI opcode, int id, void *pObj,
> > > unsigned
> > > > _user1) __swi(12)
> > > > {
> > > > switch (opcode)
> > > > {
> > > > case SYSSWI_WDOGPET:
> > > > SYSSWI_watchDogPet ();
> > > > break;
> > > > ...
> > > > }
> > > > return (0);
> > > > }
> > > >
> > > > /***** How the SYSSWI_watchDogPet () works ***/
> > > > static void SYSSWI_watchDogPet (void)
> > > > {
> > > > ARM_disableFIQ (); /* make sure FIQ is
> > > disabled
> > > > */
> > > > WDFEED = 0xAA;
> > > > WDFEED = 0x55;
> > > > ARM_enableFIQ (); /* re-enable the
> > > FIQ
> > > > */
> > > > }
> > > >
> > > > /***** The IRQ is automatically disabled by vectoring to the
> SWI..
> > .
> > > > however, you need to make the operation atomic with respect to
> > FIQ,
> > > > which is NOT disabled ***/
> > > >
> > > > PUBLIC ARM_disableFIQ?A ; interface is ARM mode
> > > >
> > > > ARM_disableFIQ?A PROC CODE32
> > > > MRS R0,CPSR
> > > > ORR R0,R0,#0x0040 ; Mask just the
FIQ
> > > > MSR CPSR_c,R0
> > > > BX R14
> > > >
> > > > ENDP
> > > >
> > > > PUBLIC ARM_enableFIQ?A ; interface is ARM mode
> > > >
> > > > ARM_enableFIQ?A PROC CODE32
> > > > MRS R0,CPSR
> > > > BIC R0,R0,#0x0040 ; Enable just the
> FIQ
> > > > MSR CPSR_c,R0
> > > > BX R14
> > > >
> > > > ENDP
> > > > END
> > > >
> > > >
> > > > --- In lpc2000@yahoogroups.com, "Ake Hedman, eurosource"
> > > <akhe@b...>
> > > > wrote:
> > > > >
> > > > > Hi all.
> > > > >
> > > > > I am trying to enable the watchdog but the result is a total
> > hang
> > > of
> > > > the
> > > > > board. Not even the bootloader is possible to reach after
> the
> > > crash
> > > > and
> > > > > I have to reapply power with P0.14 low to get access to the
> > > > botloader
> > > > > again. Reset is not enough.
> > > > >
> > > > > The code to initialize the watchdog is
> > > > >
> > > > > // initialize the watchdog timer
> > > > > WDTC = 0xffffffff; //
> 15000000; //
> > One
> > > > second
> > > > > = 15000000
> > > > > WDMOD = WDEN | WDRESET; // Activate
> > > watchdog
> > > > > WDFEED = 0xAA; WDFEED = 0x55;
> > > > >
> > > > > I must have misunderstood the WD functionality. What am I
> doing
> > > > wrong?
> > > > > In the above code the watchdog should not trigger until 5
> > minutes
> > > > > elapsed so even if a vector should be wrong the code that
> follow
> > > > should
> > > > > run for a while but as soon as I write to the WDMOD register
> I
> > > get a
> > > > hang.
> > > > >
> > > > > /Ake
> > > > >
> > > > > --
> > > > > ---
> > > > > Ake Hedman (YAP - Yet Another Programmer)
> > > > > eurosource, Brattbergavägen 17, 820 50 LOS, Sweden
> > > > > Phone: (46) 657 413430 Cellular: (46) 73 84 84 102
> > > > > Company home: http://www.eurosource.se
> > > > > Kryddor/Te/Kaffe: http://www.brattberg.com
> > > > > Personal homepage: http://www.eurosource.se/akhe
> > > > > Automated home: http://www.vscp.org
> > > > >
> > > >
> > >
> >
>Message
Re: Problem with watchdog
2005-12-09 by Ken Wada
Attachments
- No local attachments were found for this message.