View previous topic :: View next topic |
Author |
Message |
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
Interrupt re-entrancy problems |
Posted: Mon Sep 05, 2005 1:22 am |
|
|
The compiler turns off the interrupt in some cases to prevent re-entrancy. First of all is there any way to disable this since I know it will not happen? Also if I set the int flag directly after the int is disabled, will the ISR be called right after it returns from the function that was disabled to re-entrancy? |
|
|
Ttelmah Guest
|
|
Posted: Mon Sep 05, 2005 2:51 am |
|
|
The interrupts are only turned off this way, where re-entrancy _can_ happen. ie. the same routine is called both inside and outside an interrupt. If you are calling such a routine, and interrupts are not disabled, then re-entrancy _can_ take place. How do you think you are stopping this?...
Yes.
There are three things needed for an interrupt event to occur:
1) The interrupt flag is set.
2) The global interrupt is enabled.
3) The specific interrupt is enabled.
The interrupt flag, remains set, till it is cleared in the handler. Hence if an interrupt event happens immediately after the global interrupt is disabled, the event will be serviced, when the global interrupt enable is reset at the end of the protcted routine.
You an always 'duplicate' code, to prevent re-entrancy applying. Wasteful of code space, and you will then have to be careful of modifying the same global variables in both routines (bracket these operations with interrupt disable/enable).
Remember also, that interrupts are disabled in some other places, not related to re-entrancy.
Best Wishes |
|
|
Guest
|
|
Posted: Mon Sep 05, 2005 2:09 pm |
|
|
Thanks for that very helpful bit of information. You said the interrupt is also disabled in other situations. What would some examples of that be? |
|
|
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
Re: Interrupt re-entrancy problems |
Posted: Mon Sep 05, 2005 2:24 pm |
|
|
Eugeneo wrote: | The compiler turns off the interrupt in some cases to prevent re-entrancy. First of all is there any way to disable this since I know it will not happen? Also if I set the int flag directly after the int is disabled, will the ISR be called right after it returns from the function that was disabled to re-entrancy? |
Let me guess, are you calling "delay_ms()" or "delay_us" from an ISR? This is a sure way to get the reentrancy/interrupt warning. If you refrain from using either of those function calls from any ISR, then you won't get that warning.
If you must use those function calls in an ISR, then do as Ttelmah says and just make duplicate code. For example,you should create your own my_delayms(). However, you really shouldn't be doing delays in an ISR anyways, since you should get out of an isr as quick as you can. |
|
|
Ttelmah Guest
|
|
Posted: Mon Sep 05, 2005 2:42 pm |
|
|
There are a couple of parts of some long 'jump' operations, which need to remove a value from the stack. In some compiler versions this is done using the TOS registers, and interrupts are disabled during this. Some versions also disable the interrupts during flash program memory writes (on the versions that don't, you need to do this yourself, or the writes may not work correctly...).
Best Wishes |
|
|
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
|
Posted: Mon Sep 05, 2005 2:47 pm |
|
|
Ok. I'm being silly. I just need 1 clock cycle delay to refresh my 74hc574 so how do I do a nop instead of delay_us(1)? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Sep 05, 2005 3:32 pm |
|
|
Code: | //#define NOP() { #asm nop #endasm }
|
You should be able to use this inside and outside an interrupt since the code is placed inline |
|
|
Ttelmah Guest
|
|
Posted: Tue Sep 06, 2005 1:55 am |
|
|
Or just use 'delay_cycles(1);'.
Best Wishes |
|
|
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
|
Posted: Tue Sep 06, 2005 3:06 pm |
|
|
As you can see below, Mark's or Ttelmah's suggestions essentially compile to the exact same assembly code. Mark's method may be more portable across different compilers.
Code: |
.................... #define NOP() { #asm nop #endasm }
.................... void main(void)
.................... {
0004: CLRF FF8
0006: BCF FD0.7
0008: CLRF FEA
000A: CLRF FE9
000C: BSF FC1.0
000E: BSF FC1.1
0010: BSF FC1.2
0012: BCF FC1.3
0014: MOVLW 07
0016: MOVWF FB4
0018: MOVF F96,W
001A: MOVF FB4,W
001C: BCF FA1.6
.................... delay_cycles(2);
001E: NOP
0020: NOP
....................
.................... NOP();
0022: NOP
....................
....................
.................... }
....................
....................
0024: SLEEP
|
|
|
|
|