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

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



Joined: 21 Jul 2014
Posts: 35

View user's profile Send private message

global variables
PostPosted: Thu Sep 11, 2014 1:15 pm     Reply with quote

Hello,

I just encountered something strange with a variable defined outside of
main{}

Every compiler I have ever used made all storage and variables outside
of main GLOBAL.

I just caught this compiler failing to increment a fifo pointer:

Code:
unsigned char rx_fifo[32],*rx_ptr;

main{
      rx_ptr = &rx_fifo[0];

      for(;;){
      check_rx();
      }
}

void check_rx(void)
{
          if(rx_available())
          {
                ch = rxchar_get();
               *rx_ptr++ = ch;
           }
}

When running the debugger, rx_ptr stays at rx_fifo[0] each time I enter
the check_rx routine, and does get incremented to the next position while
I am in the check_rx routine.

Question: Do I have to declare all these variables outside main as static?

TIA

GlenB
gfbankston



Joined: 21 Jul 2014
Posts: 35

View user's profile Send private message

compiler
PostPosted: Thu Sep 11, 2014 1:16 pm     Reply with quote

Sorry, latest version of the compiler for a 18F45K50 chip
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 11, 2014 1:32 pm     Reply with quote

You didn't post a test program so I made one, and it works just fine.
This was tested in MPLAB (not MPLAB-X) simulator with vs. 5.026.
I don't have 5.027 installed on this PC.

This shows incrementing pointer values:
Quote:

0005 initial ptr value
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
0020
0021
0022
0023
.
.
.


Test program:
Code:

#include <18F45K50.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

void check_rx(void);

int8 rxchar_get(void)
{
return('A');
}

int8 rx_available(void)
{
return(TRUE);
}


unsigned char rx_fifo[32],*rx_ptr;

//==========================================
void main(void)
{


rx_ptr = &rx_fifo[0];

printf("%lx initial ptr value \r", rx_ptr);

for(;;){
   check_rx();
   printf("%lx \r", rx_ptr);
  }
 
}

void check_rx(void)
{
int8 ch;

if(rx_available())
  {
   ch = rxchar_get();
   *rx_ptr++ = ch;
  }
}
ronaldoklais



Joined: 18 Dec 2012
Posts: 13

View user's profile Send private message

PostPosted: Thu Sep 11, 2014 5:41 pm     Reply with quote

Try this:

ch = rxchar_get();
*rx_ptr = ch;
rx_ptr++;
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: global variables
PostPosted: Fri Sep 12, 2014 1:48 am     Reply with quote

gfbankston wrote:


Code:

unsigned char rx_fifo[32],*rx_ptr;

*rx_ptr++ = ch;



Just a couple of style points:

Its advised that such declarations are on separate lines:
Code:

unsigned char rx_fifo[32];
unsigned char *rx_ptr;


I can see that with buffers its tempting to declare both on one line to keep them together. The problem is that its not clear what is and what is not a pointer when both are declared in the same statement.

Consider this:

Code:

unsigned char *a, b;
unsigned char c, *d;


Is b a pointer? No it isn't, but it looks as though it should be. Its clearer that c is not a pointer - and this is the form you are using - but its still confusable. To fix this, simply split the declaration. It also makes assigning an initial value clearer.

Code:

*rx_ptr++ = ch;

// Actually means:
*(rx_ptr++) = ch;

// and not as some might expect:
(*rx_ptr)++ = ch;

// but
++*rx_ptr = ch;

// means
++(*rx_ptr) = ch;

// Or use ronaldoklais's suggestion of separating the two operations.


Here the point is that its better to clarify what's meant by adding the brackets than relying on the reader knowing C's at times rather non-intuitive rules of precedence.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Sep 12, 2014 2:52 am     Reply with quote

There is one thought that has not been made.

The original poster does not show a complete program.

As such there are other possibilities. For instance, the watchdog could be triggering, in which case every time the check_rx routine was called, the pointer could have been set back to the first address in the array, as the chip restarts....

This sort of thing is why a complete small compilable program, like PCM_programmer posted, is essential.
gfbankston



Joined: 21 Jul 2014
Posts: 35

View user's profile Send private message

global variables
PostPosted: Fri Sep 12, 2014 6:24 am     Reply with quote

Well taken, the point about the watchdog...but, I assume that when the watchdog fires, it resets the cpu. I would have seen repeated sign-on messages on the LCD.

Also, the code is over 4000 lines, so just tried to illustrate what the problem was. The code worked perfectly when compiled on the XC8 compiler. All my issues have cropped up when using the CCS compiler. I am hoping this is because I "do not understand the rules" of this compiler.

This project is (an attempt) to move a working project using Atmel AVR processor to a PIC45K50(25K50), primarily for cost savings and the fact that CCS usb code really works...

Here is some other code that worked fine under XC8 that did NOT work in CCS:

typedef unsigned int16 uint;
typedef unsigned int8 uchar;

uint read16_eeprom(uchar addr)
{
uint val,val1;

init_eeprom(addr);
MCU_RD =1;
val = MCU_EEDATA;
addr++;
MCU_EEADR = addr;
MCU_RD =1;

#if XC8_COMPILER
val += (MCU_EEDATA << 8);
#else //CCS compiler
val1 = (MCU_EEDATA << 8) ; //upper 8 bits
val += val1;
#endif

return(val);
}

I am wondering how many places in my code that need changes???

GlenB K4KV
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Sep 12, 2014 7:11 am     Reply with quote

After having discussed how important it is to post a complete program you still choose to post fragments...

Also, please use the 'code' buttons to preserve formatting.

If you don't want to be precise when asking your question, how can you expect us to spend our free time on your problem?

Now the fragment is useless without the declaration of MCU_EEDATA.

I don't have your compiler version and didn't want to waste time in creating my own test program, but I can just imagine the compiler doesn't know that MCU_EEDATA is a register and the optimizer is trying to be smart and re-uses the data from the previous access.
Is it wrong? Perhaps. But my guess is that you have forgotten to mark the register as 'volatile'.

As an extra not on coding style:
Code:
typedef unsigned int16 uint;
typedef unsigned int8 uchar;
Why????
the name int16 contains so much more information than uint. I have seen many different variations on the theme, like Uint16, Uint16_t, int16_t, U16, etc. But at least try to keep the size in the type definition, then other programmers reading your code don't have to find your type redefinition to know the byte size.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 12, 2014 8:10 am     Reply with quote

Also, CCS has helper routines to do all that stuff, such as r/w of 16-bit
values to eeprom. See this file:
Quote:
c:\program files\picc\drivers\internal_eeprom.c

Get rid of the low level code and write CCS programs they way they
are supposed to be written - at a higher level than XC8, etc.
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