This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Does "__delay_cycles()" rely on interrupts? ... would there be a problem if I disabled interrupts before this function is called?
If you look at the generated assembly code, a call to for example __delay_cycles(1000) becomes
JMP ??main_1
??main_1:
MOV.W #0x14b, R15
??main_0:
ADD.W #0xffff, R15
JC ??main_0
in other words, it decomposes into a series of adds and compares, which clearly does not rely on interrupts.
Tony
old_cow_yellow said:Actually, if interrupt is enabled, the interrupts will add more delays.
Unless an interrupt happens that has no ISR, then lim delay -> inf.
It is a good practice to provide interrupt handlers for every interrupt vector (especially unused ones) when you enable interrupts and need to go to the last bit of security.
Indeed. However, this is not trivial. Unless you indeed write several independent ISRs.Jan said:It is a good practice to provide interrupt handlers for every interrupt vector (especially unused ones) when you enable interrupts and need to go to the last bit of security.
Jens-Michael Gross said:Indeed. However, this is not trivial. Unless you indeed write several independent ISRs.
Actually it's quite possible to provide multiple interrupt vectors with dummy ISR, if you're willing to use some vendor extensions (yeah yeah, hope you appreciate the irony ;)
See the following example for the MSP430G2553 on IAR Embedded
typedef void (*pointer_to_ISR)();
__interrupt void fillerISR(void) {
}
__interrupt void nmi_ (void)
{
// some code
IFG1 &= ~NMIIFG; // Reclear NMI flag in case bounce
IE1 |= NMIIE; // Enable NMI
}
#ifdef __ICC430__
#pragma location=0xffe4
#endif
extern const pointer_to_ISR isr[]= {
(pointer_to_ISR)fillerISR, // PORT1_VECTOR
(pointer_to_ISR)fillerISR, // PORT2_VECTOR
(pointer_to_ISR)fillerISR, // UNUSED
(pointer_to_ISR)fillerISR, // ADC10_VECTOR
(pointer_to_ISR)fillerISR, // USCIAB0TX_VECTOR
(pointer_to_ISR)fillerISR, // USCIAB0RX_VECTOR
(pointer_to_ISR)fillerISR, // TIMER0_A1_VECTOR
(pointer_to_ISR)fillerISR, // TIMER0_A0_VECTOR
(pointer_to_ISR)fillerISR, // WDT_VECTOR
(pointer_to_ISR)fillerISR, // COMPARATORA_VECTOR
(pointer_to_ISR)fillerISR, // TIMER1_A1_VECTOR
(pointer_to_ISR)fillerISR, // TIMER1_A0_VECTOR
(pointer_to_ISR)nmi_ // NMI_VECTOR
};
Of course this gets a wee bit problematic on CPUX what with the 20-bit function pointers an' all.
What do you guys think?
Tony
Well, (pointer_to_ISR) should take care of the 16 bit address, and the __interrupt should tell the linker to place the ISR into lower mem, so this won't be a problem.TonyKao said:Of course this gets a wee bit problematic on CPUX what with the 20-bit function pointers an' all.
The main problem with such a dummy ISR is that it won't help much. Unless the ISR clears all IFG bits, it will exit and then immediately re-enter in an endless loop. So without debugger and breakpoint on it, it won't help fixing anything.
Jens-Michael Gross said:The main problem with such a dummy ISR is that it won't help much. Unless the ISR clears all IFG bits, it will exit and then immediately re-enter in an endless loop. So without debugger and breakpoint on it, it won't help fixing anything.
You can do something like this
__interrupt void fillerISR(void) {
if(IFG2)
__no_operation();
else if(P1IFG)
__no_operation();
else if(P2IFG)
__no_operation();
else if(TA0CTL & TAIFG)
__no_operation();
//etc etc
else {
__no_operation();
}
}
Which would help you to find out where the spurious interrupt came from instead of hunting through all the peripheral registers.
Also it's just a more organized way of making sure you have all your necessary interrupt vectors (IMO anyway :).
Tony
Edit: gah the forum format is messed up for code snippets...
Well, this isn't far from writing an ISR for each vector - which wouldn't need messing with the vector table then :)TonyKao said:You can do something like this
However, unwanted interrupts shouldn't appear at all in proper code. :)
You could write a library with ISRs for each and every interrupt which handles all IFG bits. If you declare them as weak references, any ISR you write in your project should then replace the 'default one'. However, the names must be identicval, and the #pragma is in the library, not in the application code then.
"However, unwanted interrupts shouldn't appear at all in proper code. :)"
I'd just like to point out that the code could be perfect and well tested however if an EMC event occurs it may cause hardware to the micro to act abnormally. We saw our micro become susceptible to Burst testing which then cause our pour little micro to reset for many reasons: brown out, watchdog time outs, etc.
Without an approach like Jens mentioned we wouldn't be able to:
1) Know an event outside of our normal operation occured.
2) Know where it came from.
**Attention** This is a public forum