CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Is interrupt disable safe?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

Is interrupt disable safe?
PostPosted: Mon Sep 22, 2008 3:37 am     Reply with quote

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







PostPosted: Tue Sep 23, 2008 1:56 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Sep 23, 2008 5:08 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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