|
|
View previous topic :: View next topic |
Author |
Message |
spilz
Joined: 30 Jan 2012 Posts: 218
|
extern variable, how to do ? |
Posted: Wed Oct 07, 2015 5:58 am |
|
|
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
thanks for your help
regards
Spilz |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Wed Oct 07, 2015 7:09 am |
|
|
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: 218
|
|
Posted: Wed Oct 07, 2015 7:17 am |
|
|
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: 19477
|
|
Posted: Wed Oct 07, 2015 7:35 am |
|
|
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: 218
|
|
Posted: Wed Oct 07, 2015 7:49 am |
|
|
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: 19477
|
|
Posted: Wed Oct 07, 2015 8:10 am |
|
|
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: 218
|
|
Posted: Wed Oct 07, 2015 8:16 am |
|
|
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: 19477
|
|
Posted: Wed Oct 07, 2015 8:20 am |
|
|
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: 218
|
|
Posted: Mon Oct 19, 2015 4:21 am |
|
|
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: 19477
|
|
Posted: Mon Oct 19, 2015 8:29 am |
|
|
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: 218
|
|
Posted: Tue Oct 20, 2015 7:51 am |
|
|
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
|
|
Posted: Thu Oct 22, 2015 6:27 pm |
|
|
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
|
|
Posted: Fri Oct 23, 2015 1:20 pm |
|
|
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
|
|
Posted: Fri Oct 23, 2015 3:52 pm |
|
|
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: 218
|
|
Posted: Mon Oct 26, 2015 3:03 am |
|
|
thanks for trying to solve my problem
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] |
|
|
|
|
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
|