|
|
View previous topic :: View next topic |
Author |
Message |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
Is interrupt disable safe? |
Posted: Mon Sep 22, 2008 3:37 am |
|
|
Hello,
As often discussed in the forum, CCS C is automatically inserting interrupt disable code with functions, that are called from both, interrupt and main code, reported in warnings like below:
Quote: | >>> Warning 216 "ttp.c" Line 127(0,1): Interrupts disabled during call to prevent re-entrancy: (usb_cdc_flush_out_buffer) |
Most programmers know, that such techniques are generally necessary with interrupt programming. It has already been used with CCS C version 3 and is operating reliably, as far as I experienced.
Now I faced a problem with a PIC18F2455 CDC application similar to ex_usb_serial. Apparently the global interrupt is suddenly disabled during sending data to the host. I could trace the problem down to the interrupt lock in usb_cdc_putc_fast() around the call to usb_cdc_flush_out_buffer(), but I didn't yet understand, why the mechanism is failing at this point. I'm using, apart from modified descriptors, original cdc.h and usb driver code from V4.079. I'm not manipulating GIE in my code, but I have additional active interrupts (timer and serial).
Looking at the respective interrupt lock code, I wonder if there is a possibility, that an interrupt can occur between line 03 and line 04, which would leave GIE and GIE flag cleared afterwards.
Code: | 01: CLRF 18
02: BTFSC FF2.7 ; Bit Test File, Skip if Clear
03: BSF 18.7 ; Conditionally set GIE flag
; Can an interrupt occur at this point?
04: BCF FF2.7 ; Clear GIE
05: RCALL 0E98 ; call of non re-entrant function
06: BTFSC 18.7 ; Test GIE flag
07: BSF FF2.7 ; Conditionally set GIE |
Or is this code safe utilizing some special processor feature related to the GIE handling. I didn't yet find any, but I'm not very familiar to the PIC instruction set.
Regarding the original CDC application issue, it can be handled by permanently reenabling GIE in the main loop. A rough, but at least in this case effective method. Also extending the range of the additional interrupt lock in usb_cdc_putc_fast() by moving down INT_GIE=old_gie to the function end helps.
Regards,
Frank |
|
|
Ttelmah Guest
|
|
Posted: Tue Sep 23, 2008 1:56 pm |
|
|
Interrupts in the PIC, only occur in the first clock cycle of an instruction. Instructions that access GIE, disable interrupts during their execution.
Interrupts on earlier lines won't affect the GIE bit.
Your problem is not being caused at the line you are looking at.
There is a fault on (most) older chips, where an interrupt can occur in the instruction that disables the interrupts. This though results in the disable not happening, effectively the opposite of what you are seeing. This is why you will find the code on some chips loops, clearing the GIE bit, till it tests as clear.
Make sure your compiler (assuming you have the Windows version), does have the tick box to disable the use of RETFIE 1. There is bug with this on all versions of these chips.
There are several odd hardware problems on some other chips, that might cause this, and while 99% of faults are usually documented, it is possible that you have found a particular example that triggers something else...
If you are happy to patch the code yourself, then make a bit definition for the GIE bit (called GIE), and encapsulate the part requiring the disable, with something like:
Code: |
int1 old_GIE;
old_GIE=GIE;
while (GIE) disable_interrupts(GLOBAL);
//other code
if (old_GIE) {
while (GIE==0) enable_interrupts(GLOBAL);
}
|
This will make sure, both that the interrupt does disable, and enable again.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Sep 23, 2008 5:08 pm |
|
|
Thank you for your profound response.
If I didn't miss anything, the below section in PIC18 family reference is the only statement explicitely related to the GIE behaviour.
Quote: | 31.4.2 Bit Manipulation
...
Note: Status bits that are manipulated by the device (including the interrupt flag bits) are set or cleared in the Q1 cycle, so there is no issue with executing R-M-Winstructions on registers that contain these bits. |
The other possible issues don't apply, I think. The said silicon errata existed with revision A3, but I'm using an almost new B6, that has no known issues with interrupt processing. Im also using single priority scheme and definitely no fast RETFIE 1.
In the meantime, it seems to me, that my above interpretation of the possible failure mechanism has been inplausible anyway and can't explain the observations. I also consider a possible chip exemplar defect and will try by next occasion, if the issue is reproducable with a production board.
Best regards,
Frank |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|