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 CCS Technical Support

Global variables access issues

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



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

Global variables access issues
PostPosted: Tue Oct 10, 2006 9:47 pm     Reply with quote

I increment a global count variable in an ISR, and then print the result after the calculations are performed using the UART and this works correctly - I get what was expected. Unfortunately, when I try to access this variable in a function which is called in my main loop later on, it is not accessed period when I try to call it in a for loop inside this function. Do I need to disable the ISR where the global variable is incremented? Are there access issues with global variables that I am unaware of? Any help would be greatly appreciated! By the way I am using a PIC18F2580.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Oct 10, 2006 10:13 pm     Reply with quote

It depends. If the variable is a byte or a bit no, anything else yes.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Tue Oct 10, 2006 10:48 pm     Reply with quote

Could you be more specific? The variable I am incrementing is an int, but I am also having trouble accessing an array that is a global which is filled in in the ISR. I use my incrementing variable to fill in the array elements sequentially like the code below:

Code:

#device HIGH_INTS = TRUE
bitpos = 0;
data[88];

#int_ccp1 fast
void ccp_int()
{
    data[bitpos] = CCP_1;
    bitpos++;
}


I also used the preprocessor directive to set the compiler to be able to use high priority interrupts for the fast keyword and this helped significantly. Any ideas why when I try to access my array and bitpos in a function that is called within main, it cannot read them?
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Oct 10, 2006 11:57 pm     Reply with quote

There are 1 to 3 possible problems. It depends on your compiler version and you PIC rev.

1. Some versions of CCS save the interrupt context for the fast handler, some do not. There are pros and cons either way. For the sort of low latency critical high priority interrupts I usually use, the compiler is very inefficient and would prevent my code form operating correctly. For example I have two full duplex software UARTS running at 115Kbps which would not be possible with the compiler saving the context. Depending on the compiler version, the fast directive no only sets the interrupt as a high priority interrupt but also results in the fast return option being used where the PIC restores the BSR, WREG and STATUS registers from the shadow registers.

2. Some 18F series PIC (most) are broken with their fast interrupt handling. This is because the shadow registers for WREG, STATUS and BSR, may hold the incorrect entry if a movff instruction operating on any of the non shadowed versions of these registers was interrupted mid step. The result is the shadow versions are not correct and therefore when returning form interrupt the processor status was corrupted. So if you happen to have one of these PICs and the compiler does not have the context for you then your application can crash and burn. The work around is to save these registers yourself (using movff instructions) and exit the handler via your own _asm RETFIE 0 _endasm instruction.

3. In your example you use an array data[] inside the handler. Now the compiler might be using the FSR0 registers to do this but if the compiler is not saving the context, then these registers are being corrupted. Therefore, depending on point 1, you may also need to save the FSR registers. It is easy to tell just dump the listing. The compiler can (and often does) generate rather convoluted (inefficient and using more registers) for dealing with arrays. So, if your compiler version does not save context, here is a cleanish work around: inside the FAST interrupt handler

Code:

   // save FSR 0
   IH_FSR0L = FSR0L;     // the complier will use movff
   IH_FSR0H = FSR0H;    // the compiler will use movff
   _asm
   lfsr       0, data
   movff      bitpos, WREG       // deliberate use of movff
   movff      CCP_1, PLUSW0
   _endasm
   FSR0L = IH_FSR0L;
   FSR0H = IH_FSR0H;


What type of variables are data and bitpos?
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Wed Oct 11, 2006 12:38 am     Reply with quote

Thanks for the help! My bitpos is a simple int and the array data is an array of longs. The weird part with this is that if I read either bitpos or the various data locations in the array in main, everything seems to be consistent and ok. If I try to access either of these from a function that is defined outside of main and called within main, I run into problems.

Another strange problem I have is that when I try to disable my ccp interrupt after I have collected all of the data from the incoming signal (I am doing signal reading) I no longer get anything. This is strange because I know my disabling is happening after the data has come in and I have verified this. Any ideas why this might be the case?
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Oct 11, 2006 12:51 am     Reply with quote

Bryan wrote:
and the array data is an array of longs


This is why you need to disable interrupts in main.

Quote:
Another strange problem I have is that when I try to disable my ccp interrupt after I have collected all of the data from the incoming signal (I am doing signal reading) I no longer get anything.


I don't understand what you mean. You disabled the interrupt because you don't want it anymore but now you are no longer getting it? How would you get it if it is disabled?
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Wed Oct 11, 2006 2:26 am     Reply with quote

I disable the interrupt AFTER I collect the data.

The only reason I thought this would be needed was because when I print out my array, I am only expecting 49 pieces of data, but the array was still getting data even in the positions that weren't supposed to be filled (Since it is sized as 88 wide I checked all 88 and 50-88 are filled with junk data seemingly random numbers). Now that you have mentioned the shadow register corruption it would make sense that this is why the array is getting all the junk data in it.

What do you mean by:
Quote:
This is why you need to disable interrupts in main.


I think you might be using a different compiler than I because the _asm and _endasm directives don't work - I need to use #asm and #endasm to get it to compile.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Oct 11, 2006 2:40 am     Reply with quote

Bryan wrote:
I disable the interrupt AFTER I collect the data.

The only reason I thought this would be needed was because when I print out my array, I am only expecting 49 pieces of data, but the array was still getting data even in the positions that weren't supposed to be filled (Since it is sized as 88 wide I checked all 88 and 50-88 are filled with junk data seemingly random numbers).


If you have not prevoulsy initialized these location then they would contain junk anyway.

Quote:
I think you might be using a different compiler than I because the _asm and _endasm directives don't work - I need to use #asm and #endasm to get it to compile.


I do use different compilers, the C18 and the CCS and in one the _asm is the correct one and in the CCS its the #asm. I just forgot which one is which :-)
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Wed Oct 11, 2006 3:00 am     Reply with quote

Could you please describe in more detail what your ASM code does from a couple posts back as I am not familiar with some of the instructions you are using. Namely these lines:

Code:

lfsr       0, data
movff      bitpos, WREG       // deliberate use of movff
movff      CCP_1, PLUSW0


Is movff bitpos, WREG loading the value of WREG into bitpos? I have no clue what the lfsr instruction is doing, or what PLUSW0 is. Thanks for all of your help!
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Oct 11, 2006 3:15 am     Reply with quote

Code:

lfsr       0, data          // load the FSR0 with the address in RAM of the data array
movff      bitpos, WREG     // get the vaule of BITPOS into the WREG (work register)
movff      CCP_1, PLUSW0    // load the variable CCP_1 with the contents of the address data (in the FSR0) plus the offset held in WREG


this is equivalent to:

Code:
 data[bitpos] = CCP_1;


The difference you know explicitly what registers are used, what functions are called, and what you have to save in a handler that does not save context automatically.

My future in assembler was talked about and planned, but I gave it up for C and the CCS band.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

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

PostPosted: Wed Oct 11, 2006 8:23 am     Reply with quote

a poet as well ! Very Happy
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