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

extern variable, how to do ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
spilz



Joined: 30 Jan 2012
Posts: 220

View user's profile Send private message

extern variable, how to do ?
PostPosted: Wed Oct 07, 2015 5:58 am     Reply with quote

hello everybody

I know it's basic stuff in C, but I don't know what is the good way to do that :

I have :
Code:
char at_received[200];

at_received is global in AT.h , it is used to save data received through uart (AT command for GSM).
In AT.c, I use at_received in function.
what is the good way to specify the extern variable ?
Code:
void test(void){
   extern char at_received[200];
   
   bla, bla, bla;
}

or
Code:
void test(void){
   extern char* at_received;
   
   bla, bla, bla;
}

or
Code:
 something else...

thanks for your help

regards

Spilz
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Oct 07, 2015 7:09 am     Reply with quote

It's not external.

External would imply a variable being created and used by some external code, that is then being accessed in your code.
What you have is a simple global variable. Your AT.h is still being run on the same processor, so declare it as global (outside the code, before the first routine), and everything can access it as a global variable.

Generally always better to compile the code together (CCS optimises better when this is done), so extern's don't really apply.
spilz



Joined: 30 Jan 2012
Posts: 220

View user's profile Send private message

PostPosted: Wed Oct 07, 2015 7:17 am     Reply with quote

thanks Ttelmah for your reply

I use actually the v5.045, and when my code is close to 95% of rom, I have issues with this string: sometimes something else seems written on it. I tried to do the same thing with:
Code:

char* at_received;

void main(){
   at_received = malloc(200);
   bla,bla,bla; 
}

But I still have issue when my code is big.

That's why I'm trying to help the compiler to secure this string and be sure nothing else write on it.

Sorry for my bad english.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Oct 07, 2015 7:35 am     Reply with quote

Seriously, using malloc, is a waste of space.....

Just declare the variable as:

char at_received[200];

Malloc because it is a dynamic allocation, implies an extra overhead. Just what you don't want, and extra code as well to do the allocation....
If you are using malloc/calloc elsewhere, this could be the cause of your problem. Especially if you are using it as shown, without testing the return. Malloc returns a null pointer if it can't allocate the memory. The very first thing you must do if using malloc, is check that the returned value is not null.
Generally, malloc/calloc, are not ideal on the PIC. They are great on C's with a chip using a memory management chip, or a dynamic stack, but the PIC does not have these. To use malloc, the compiler has to add extra variables and code. It is more efficient to just declare global variables once, and assign the space permanently (since the are global), and only allocate local variables as needed in the routines. the compiler can then re-use the memory in other routines.


The only thing you can do is write your other code to ensure that all things using pointers etc, are tested for size before they are used. Huge overhead.
The chip itself contains no form of memory protection, and C in general does no form of bounds checking.
spilz



Joined: 30 Jan 2012
Posts: 220

View user's profile Send private message

PostPosted: Wed Oct 07, 2015 7:49 am     Reply with quote

I understand what you say, but it's not what I observe with the compiler :
using malloc as I explained :
at_received = malloc(400);
on my 18F2550, I have :
RAM : 15%
ROM : 77%

but using char at_received[400];
I have
RAM : 61%
ROM : 80%

I understand the RAM, but the ROM is in opposite with your explanation, isn't it?
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Oct 07, 2015 8:10 am     Reply with quote

I'd guess, you are still using malloc somewhere?.
The routines are then still being loaded, and the allocation table still has to exist.
Sit down and draw out your memory. Work out what has to be global and allocate the space for all these not using malloc. Then remember that the compiler will already dynamically allocate RAM as it is used inside subroutines, so declare local variables as needed. Get rid of malloc completely. Actually _design_ your memory layout, then you know where things are, and what might be overwriting other areas.
spilz



Joined: 30 Jan 2012
Posts: 220

View user's profile Send private message

PostPosted: Wed Oct 07, 2015 8:16 am     Reply with quote

I don't use malloc function somewhere else, and I comment :
Code:
// #include <stdlibm.h>


I don't know how to _design_ my memory layout, and how to do it with the compiler
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Oct 07, 2015 8:20 am     Reply with quote

That makes no sense then. It'd tend to imply that something in the code is actually not using the table access functions, or is cutting a corner when the pointer has been generated by malloc in your case. This may well suggest the reason things are going wrong....
spilz



Joined: 30 Jan 2012
Posts: 220

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 4:21 am     Reply with quote

hello,
I'm still trying to find a solution, or at least a reason so, I did some test :

with a very small program, using malloc takes more ROM than using char[].
But bigger my program is, often I call "at_received" and using char[] starts to use more ROM.

It looks like calling "at_received" as char[] takes more ROM than calling it as pointer.

I don't understand why ...
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 8:29 am     Reply with quote

More to the point, it suggests that malloc, is _not_ actually allocating the space needed. Test the value of the returned pointer from the malloc call. If it is NULL, then malloc cannot find enough space (or not enough in a single 'entity'), to actually allocate the storage. Would explain your problems....
spilz



Joined: 30 Jan 2012
Posts: 220

View user's profile Send private message

PostPosted: Tue Oct 20, 2015 7:51 am     Reply with quote

I did the test, malloc return 146, so allocate the storage well.

I did other test by changing at_received size, the effect is always the same...
ronaldoklais



Joined: 18 Dec 2012
Posts: 13

View user's profile Send private message

PostPosted: Thu Oct 22, 2015 6:27 pm     Reply with quote

Dynamic allocation work with the space not allocated in compilation time.

Try it:
Code:

char* var1;
char* var2;
char* var3;
char* var4;
char* var5;

void main(){
   var1 = malloc(200);
   var2 = malloc(200);
   var3 = malloc(200);
   var4 = malloc(200);
   var5 = malloc(200);
}

Now see if all the variables are allocated. If true, duplicate more variables and then try again.
ckielstra



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

View user's profile Send private message

PostPosted: Fri Oct 23, 2015 1:20 pm     Reply with quote

spilz wrote:
I understand what you say, but it's not what I observe with the compiler :
using malloc as I explained :
at_received = malloc(400);
on my 18F2550, I have :
RAM : 15%
ROM : 77%

but using char at_received[400];
I have
RAM : 61%
ROM : 80%

I understand the RAM, but the ROM is in opposite with your explanation, isn't it?
We haven't seen your code, so all we can do is guessing.
Just a few notes:
1) Your 18F2550 has 2048 bytes of RAM. Allocating 400 bytes is 19%. When you use malloc(400) and it is reported as only 15% then something is very wrong with the malloc.
2) My suggestion is to never use malloc in an embedded system. Malloc is great for dynamic memory management but your embedded device should be designed to never fail, this means you don't want dynamic behaviour. You have to design for maximum configuration, meaning the use of hard coded array sizes.

Other possible problems with malloc are:
- Extra program space for the malloc function, for checking the return value and for code to handle a possible error return.
- Chance of memory fragmentation when you allocate and free the memory multiple times.

In my opinion, the only reason malloc is supported by the CCS compiler is because this functionality is in the C standard.

I'm curious to see more of your program. I suspect you are accessing the character array in an inefficient way that requires a lot of code.
guy



Joined: 21 Oct 2005
Posts: 297

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

PostPosted: Fri Oct 23, 2015 3:52 pm     Reply with quote

just a thought - could it have to do with Debug mode and/or restricted RAM memory? Are you compiling in Debug or Release mode?
spilz



Joined: 30 Jan 2012
Posts: 220

View user's profile Send private message

PostPosted: Mon Oct 26, 2015 3:03 am     Reply with quote

thanks for trying to solve my problem Smile

my code is too big to be post here :(

some parts :
Code:
#include <18F2550.h>
#fuses NOWDT,PROTECT,NOLVP,NODEBUG,VREGEN,MCLR,XT
#use delay(clock=4MHz,crystal=4MHz,restart_wdt)

#use rs232(baud4800,parity=N,xmit=pin_c6,rcv=pin-c7,bits=8,TIMEOUT=200,STREAM=rs232_AT,BRGH1OK,DISABLE_INTS)

receiving UART data :
Code:
#define size_string_AT 400
char* string_AT; // if I use malloc(size_string_AT+2)
or
char string_AT[size_string_AT+2];// if I don't use malloc(size_string_AT+2)

int16 cmp_AT = 0;
int line_AT = 0;

#int_RDA
void RDA_isr(void){
   char c;
   if(kbhit(rs232_AT)){
      c = fgetc(rs232_AT);
      string_AT[cmpAT++] = c;
      if(cmp_AT >= size_string_AT)
         cmp_AT = size_string_AT-1;
      if(c == 0x0D)
         line_AT++;
   }
   string_AT[cmp_AT] = 0;
}

main :
Code:
void main(){
   ...
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   ...
   string_AT = malloc(size_string_AT+2); // only when I try to use malloc, string_AT != 0 after testing
   ...
   while(true){
      ...
   }
   reset_cpu();
}

how I use the array after :
Code:

char OK[3] = "OK";
if(strstr(string_AT,OK)!=0){

}

or

char* c;
c = strchr(string_AT,':');
...

So,
I don't have Debug mode I guess,
I don't know how to know about restricted RAM memory
what ever how big is size_string_AT, using malloc, RAM doesnt change, so I guess, it's not include in the calcul.
I never free the memory, as I use it only one time at the biggining (i know it's not beautifull ...)
malloc never return 0

feel free if you any question about my code or suggestions

thanks

Spilz[/code]
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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