Perform a reset in an ISR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Perform a reset in an ISR

13,194 Views
byteybird
Contributor I
I'm using Codewarrior 5.0
I've installed interrupt handler for all unused vectors. I needs to force a reset (interrut 0) if any of these vectors are asserted. What instruction should I used to force a reset within the interrupt handler?

Thanks in advance
Barry
Labels (1)
0 Kudos
12 Replies

1,136 Views
al303576
Contributor I
AHH! ok.
I can't sleep with this question into my head.. 
Gracias
0 Kudos

1,136 Views
byteybird
Contributor I
Thanks for the feedback. Before I posted the question here, two days earlier I asked Freescale support the same question. After the issue was reassigned a number of time and 5-days latter they came back with an answer. The following is their response:

=================================================================

If you'd like to perform cold reset, it's not enough to jump to Reset
vector.
I guess there is your question concerning this issue in Freescale
discussion forum.
I have to agree with Alban Rampon.

First of all I would recommend to you to see "System Integration Module
(SIM) chapter - Reset and system initialization" for more details about
internal resets of your MCU.

You can chose between different sources of internal reset. If the reset
conditions are fulfilled reset arise (device registers and modules are
initialized), then all of the sources call same routine placed on reset
vector (0xFFFE - 0xFFFF). To distinguish between different sources of
internal reset you could check SRSR register.

Basically, there are three sources of internal reset which you can use
in your code:

- reset caused by watchdog overflow (COP)
- reset caused by fetching illegal instruction
- reset caused by illegal address operation

You would choose the most convenient one for you. In your C code you
could add :

#define ILOP_RESET asm DCB $32 // illegal operation example
#define ILAD_RESET asm JMP $xxxx // illegal address example
($xxxx address must not be implemented)
#define COP_RESET asm BRA 0 // Watchdog overflow (infinite loop)

interrupt 1 void ISR_SWI(void)
{
ILOP_RESET;
}

interrupt 2 void ISR_IRQ1(void)
{
ILOP_RESET;
}

Note: If you are going to use COP you have to setup and start watchdog
timer before (CONFIG1 register). COP is automatically disabled in
monitor mode.

If you'd like to assign same interrupt routine to several interrupt
vectors you can use #pragma TRAP_PROC:

#pragma TRAP_PROC
void isr(void)
{
ILOP_RESET;
}

In your project .prm file you can just set same address of service
routine to several interrupt vectors.

VECTOR 0 _Startup /* Reset vector: this is the default entry point for
an application. */ VECTOR 1 isr VECTOR 2 isr VECTOR 3 isr

I hope this will help you.

Should you need to contact us with regard to this message, please see
the notes below.

Best Regards,

Customer Engineering Support
0 Kudos

1,136 Views
al303576
Contributor I

Hi...
Sorry for de question but ..what is "DBC"? is a instruction where i can find .... in the data sheet?
 
 
 
 
0 Kudos

1,136 Views
peg
Senior Contributor IV
Hi al303576,
 
I presume you mean DCB???
 
DCB is an assembler pseudo-opcode or assembler directive otherwise known as DCB.B or FCB etc.
All it does is place the following value at the current address.
What they are doing here is putting the value $32 (which is an undefined or illegal opcode) at a location labelled as ILOP_RESET.
If the programme was to jump or branch to this location it would cause an illegal opcode reset.
 
Hope that helps
 
Regards
Peg
 
P.S. So you won't find it in the device datasheet but in the assembler manual, just type it into CW help index.
 

Message Edited by peg on 2006-12-2805:32 PM

0 Kudos

1,136 Views
byteybird
Contributor I
I'm writing in c.
What I tried to do is:

#define RESET asm(dc.b $32)
interrupt 1 void ISR_SWI(void) {RESET;}

The compiler complained about an invalid opcode on the interrupt 1 line.

What I need is "interrupt 1" to vecter into "interrupt 0", which is the reset vector.
0 Kudos

1,136 Views
Alban
Senior Contributor II
It's a good compiler if it flags you illegal opcode !
Try and de-activate this check in the compiler parameters.

Alban.
0 Kudos

1,136 Views
yb
Contributor IV
Hi,
 
In C, you can also write this :
asm
{
 ldhx $FFFE
 jmp ,x
}
 
You will jump directly to the same address than the power-on RESET.
 
Yvan
 
0 Kudos

1,136 Views
rocco
Senior Contributor II
Hmm . . . I haven't used CodeWarrior's version of C yet, and I don't know about the asm() syntax in CW, but I could see how this might get tricky.

Have you tried breaking it into pieces? Like:
void resetProc( void )
{
#asm
dc.b $32
#endasm
}

interrupt 1 void resetProc(void);
This syntax is what I use for one of my C compilers, but is probably not what CW expects.

Having the invalid interrupt jump through the reset vector will get you to the start of your code, but it won't be the same as an actual reset. Your stack, peripherals and I/O pins will not be re-initialized.

Here's another approach, one I used back on the HC05s. If you are using the COP watchdog, just spin in a loop with interrupts disabled. After a few milliseconds, the watchdog will force a reset.
0 Kudos

1,136 Views
bigmac
Specialist III
Hello Barry,
 
If you want to generate a reset should an unused interrupt occur, wouldn't the easiest approach be to simply point these vectors to the same location as the reset vector?
 
Regards,
Mac
 
0 Kudos

1,136 Views
peg
Senior Contributor IV

Hey Mac!

Just vectoring to the same place as the reset vector will won't *GENERATE* a reset, just cause a code branch to same place you would go after a reset.

ditto Yvan

I like Rocco's ideas better. How about just putting an illegal opcode in memory then point your unused vectors there. This will generate a reset. Generating an interrupt that your not supposed to is illegal, not for the chip but for your application! It will probably be caused by the same sort of problems as well!

Peg

0 Kudos

1,136 Views
Alban
Senior Contributor II
I actually love the idea of Rocco
 
In C you take either of the following code line and put only this in the ISR.
                                    
          /* Generate a RESET by Illegal Opcode */
    asm DCB 0x8D ;

          /* Generate a RESET by not feeding the COP */
    while (1) {}

Of course, you need COP enabled for the COP reset.
The good stuff with the first is you can know why you had a reset in the SRSR (see SIM Chapter of datasheet) and if you see an ILAD, chances are it was because of the unimplemented ISR.

The main point to consider here is time. Can you afford to wait the COP time out or do you need immediate reaction ?
The answer will give you which one to take :smileywink:
 
Cheers,
Alban.
0 Kudos

1,136 Views
rocco
Senior Contributor II
Barry, I defined a RESET instruction using a macro, assigning it a value of an illegal instruction, $32. On any reset, my code tests the reset register, and can tell if the reset was caused by this instruction (assuming there isn't another illegal instruction somewhere).

Here is the macro:
;
;
; This Macro defines an instruction to reset the CPU.
;
RESET: macro
dc.b $32 ; this is illegal operation code
endm
(darn, this board keeps blowing away my formatting. How do we who don't know HTML get code to format right?)

Message Edited by rocco on 02-16-200607:35 PM

0 Kudos