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

Warning for FAST Interrupt and Shadow Registers

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



Joined: 18 Oct 2018
Posts: 4

View user's profile Send private message

Warning for FAST Interrupt and Shadow Registers
PostPosted: Thu Oct 18, 2018 2:48 pm     Reply with quote

Just wanted to share something I recently got hung up on for a while. I recently completed a project for a PIC24FJ64GA002 though I am sure this applies to a much broader range of parts. The device performed as an I2C slave. I found that setting the I2C interrupt as FAST was required to meet timing.

The project worked well for the most part. But every once and a while I got an error I could not explain. Really weird stuff, like if(0){} where the stuff in the brackets would execute. So I figured ok, register corruption from the interrupt. But how could that be? The FAST interrupt swaps out working register with shadow registers it should be totally safe.... right...

First error I made was to assume it swapped out all working registers. It is easy to miss in the data sheet that it only actually working registers 0-3. Secondly, as a C programmer, I typically do not concern myself with working registers too often. After examining the assembly I found that the compiler makes no effort to restrict it's register usage to working register 0-3. The interrupt code was complying to assembly that used register 0-6 or greater.

So it is important that when using the FAST interrupt, to check your out LST file to confirm that the interrupt does not use working registers beyond number 3. If it does, in our case, we resolved by adding inline ASM code to backup and restore additional working registers. You can reference the LST file for non-FAST registers to see how the compiler does this and use it as reference.

It was a real pain to figure out. I hope this helps someone else out and prevents the anguish I had to endure.
guy



Joined: 21 Oct 2005
Posts: 291

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 18, 2018 8:40 pm     Reply with quote

Thanks Glen! Please send an email to CCS support. They will take care of it in future versions and help us all. I hope you didn't spend too much time on this bug.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Oct 19, 2018 12:30 am     Reply with quote

This is not an bug.

Case of reading the manual, and understanding your chip..... Sad

From the manual:
Quote:

An interrupt marked FAST is performed without saving or restoring any registers. This should be used as little as possible and save any registers that need to be saved manually.


The way to get an interrupt to interrupt other interrupts on the PIC24, would be to use the interrupt levels, not FAST. Assign the interrupt with a lower priority number (they work backwards - lower number == higher priority).
GlenED7



Joined: 18 Oct 2018
Posts: 4

View user's profile Send private message

PostPosted: Fri Oct 19, 2018 7:13 am     Reply with quote

I agree that it is not a bug, but something to watch out for. However, it is unrelated to interrupt nesting or interrupt priority. For example, your "Main Loop" code can suffer from corrupted registers if the FAST interrupt is the only interrupt you are using.
GlenED7



Joined: 18 Oct 2018
Posts: 4

View user's profile Send private message

PostPosted: Fri Oct 19, 2018 7:24 am     Reply with quote

Furthermore it would be a nice feature of the compiler if it made an attempt to restrict its register usage in the FAST interrupt to just those registers that are swapped out with shadow registers, IE W0-W3. Or at least note in the manual that the ASM output for the FAST interrupt should be manually checked for register usage beyond W3.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Oct 19, 2018 7:40 am     Reply with quote

Changing register usage because you are in a fast handler would be very complex. It is a case of you having to do the 'high efficiency' code yourself.

Register use in interrupts is a general area that there could be a lot of things done. For example, if the compiler actually tracked what registers were being used inside the interrupts, then the register save and restore could be reduced to just saving these. However though 'nice', such complexity would be a lot of work, and 99% of users would not even know that the compiler was being this useful, so probably not worth the effort....
jeremiah



Joined: 20 Jul 2010
Posts: 1314

View user's profile Send private message

PostPosted: Fri Oct 19, 2018 6:12 pm     Reply with quote

GlenED7 wrote:
I agree that it is not a bug, but something to watch out for. However, it is unrelated to interrupt nesting or interrupt priority. For example, your "Main Loop" code can suffer from corrupted registers if the FAST interrupt is the only interrupt you are using.


Just because you are learning about the FAST aspect of interrupt handlers, I wanted to toss this extra info in. Interrupt nesting is an important feature that can interact with FAST. In the case of the PIC24 family, the chip itself is saving the shadow registers to a 1 level deep hardware stack (1 level in terms of the number of unique copies of each of the affected registers). So if you ever do use interrupt nesting, be aware that the FAST feature can hose you if used incorrectly. In particular, if you go against the manual's warning of only use it on one interrupt and instead use it on multiple ones, then if you happen to enable nesting and a higher priority interrupt marked as FAST interrupts another interrupt marked as FAST, you will corrupt data as well.

I know this isn't the issue you faced, but wanted to highlight it for you in case you ever decide to use the feature in more complex setups.

From my perspective, I would not like the CCS compiler to do anything more than it already does for FAST. The whole point of it is to get as fast a handler as possible and it is the programmers responsibility to manage the registers. I use it a lot for trap debugging and some really fast audio DAC applications. Any additions of extra stuff to save would either hose those or make them much harder to attempt.

And actually, I would prefer to have the CCS compiler do less than it does currently with FAST. I have interrupt handlers that don't really need the shadow register stack push/pops but the compiler still inserts those for FAST interrupts. It's a wasted instruction cycle for those interrupts.
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