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

Running Low On RAM!

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



Joined: 09 Mar 2015
Posts: 10

View user's profile Send private message

Running Low On RAM!
PostPosted: Wed Mar 25, 2015 5:05 pm     Reply with quote

Hi,

i have been silent on here using this fantastic forum as reference for sometime now. Anyway i am new ish to pic c programming. i am having an issue with RAM running low and would appreciate some help. my application is a pic 18F4520 accepting commands via the serial port and then performing some routine based on the command received. the problem is i have just over 100 commands, this is how i have been handling it so far.

Code:

void actioncmd(char cmd[20]){

char XXXXXXXXX[10] = "XXXXXXXXX";   //Define the string (100 lines of commands like this where XXXXXXXX is a different command)

clean_up_str(cmd); // this removes white space from cmd

IF (strcmp (cmd, XXXXXXXXX) == 0) // 100 more if statements similar to this where XXXXXXXXX is a different command
      {
       run_some_function();
      }
}



i feel i don't need to put all the code here but basicly main is responsible for getting the cmd in via the serial port and passing to this function.

i understand i can't use a constant in the strcmd() which is why i have done it like this. but this method, when i have all 100 sections of code in place is using up 77% of RAM and i still have a few more functions to write. if i comment the above code out it falls right down to 13%.

so the big question is can i optimise this code in any way?

because i am unsure on how the code relates to RAM i wasn't sure what to search for on this forum to see if this sort of question has been asked before, so apologise if it has.

just in case if helps i am using 5.044

thanks in advance
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Mar 25, 2015 5:35 pm     Reply with quote

have you read about
Code:

CONST char XXXXXXXXX[10] = "XXXXXXXXX";


if the VARs in question are static in their content - this will place them in PROGRAM memory - of which you have quite a lot more
and use no static ram which is precious.
AArdvark



Joined: 09 Mar 2015
Posts: 10

View user's profile Send private message

PostPosted: Wed Mar 25, 2015 5:47 pm     Reply with quote

thanks for your reply, i tried this before thinking that's what it will do but it came up with errors all over the place.

i have just tried it again now and it seems to work i will test it out on the whole code and see what happens.

thanks again.
AArdvark



Joined: 09 Mar 2015
Posts: 10

View user's profile Send private message

PostPosted: Wed Mar 25, 2015 6:03 pm     Reply with quote

unfortunately that made no difference Confused
i don't think its these taking up the memory.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 25, 2015 7:40 pm     Reply with quote

You save RAM by putting your strings in flash memory with the 'const'
qualifier. You can pass a 'const' string to a function (without a compiler
error) if you add a #device statement. See the lines shown in bold below:

Quote:
#include <18F4520.h>
#device PASS_STRINGS=IN_RAM
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

#include <string.h>

void actioncmd(char cmd[20])
{
const char X_data[10] = "XXX";

if(strcmp (cmd, X_data) == 0)
{
printf("run_some_function \n\r");
}
else
{
printf("Invalid command \n\r");
}

}


//===================================
void main()
{
actioncmd("XXX");

while(TRUE);
}
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Mar 26, 2015 3:05 am     Reply with quote

EDIT: PCM posted while I was writing, but here it is anyway:

Quote:
You save RAM by putting your strings in flash memory with the 'const'
qualifier.


Hmm, not really. Its all about lifetime - i.e. how long variables have to exist in RAM. Const variables (and yes, in C that's how they are considered, as variables which are read-only - const is a qualifier) are like all varaibles, and in important respects are treated just the same as normal read-write varaibles. C doesn't have any mechanism for coping with actual read-only memories. Const wasn't in early Cs, it was added to the language later. Before that, #define was used to implement similar functionality. Const is a hint to compilers that the varaible is read-only and can be treated as appropriately as the underlying hardware allows. In most Cs I've encountered, that means that, just like "normal" variables, consts exist in RAM at all times, but is loaded at program start up from some outside storage. In systems without ROM, that means that consts are loaded from the program image on disc, or other backing store, in PICs, which don't have such storage, it means they are loaded from a value held as part of the program image in program memory.

All this means that consts, in a sense, take up twice as much room as normal variable and have two copies, one in program memory, one in RAM.

It would be possible to not have the RAM version. In other words const means "this is a special data thingy that never exosts in RAM, generate code that always gets it from program memory". That, though, means that any accesses to consts would be much slower and generate much longer code. Hence the treatment of consts with a RAM shadow - using a const is just the quick and code efficient as any other variable.

So, this means that consts use the same RAM as is they were normal initialised variables that you happen never to write to, which in C is what they conceptually are. Their RAM life time is for all the program scope.

How to reduce RAM usage? You need to reduce the effective scope of the data. One way of doing this is to explicitly store such stuff in program memory say with #rom, and then to read them into a some scratchpad in RAM when required. You manage this yourself. That way, you only need to have one scratchpad in RAM big enough to hold the longest constant, such as strings. I tend do this explicitly with strcpy() and other related routines. Here's a snippet from a command interpreter:

Code:

      // Compare_string is a scratchpad used to temporarily hold the string to compare with.
      strcpy (compare_string, "*IDN?");
      if(strncmp(single_cmd_array, compare_string, 5) == 0)
      {
         command_number = 71;
      }


Another way of doing this is to use #device PASS_STRINGS=IN_RAM, which automates this process, i.e. the compiler does the same thing for you - it makes a temporary copy of a in RAM of a string literal, e.g. "This is a string literal", in program memory. That only works for strings however, and not, for example, with numerical menu tables.

A thing to remember is that the compiler cannot tell how long you need a varaible to exist and be accessible. The scope rules tell it some basic stuff - i.e. local variables in routines only exist while that rountine is running. So if you want to be clever about data lifetime, and save RAM by resuing RAM wher possible, generally you have to do it yourself.[/quote]
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Thu Mar 26, 2015 4:51 am     Reply with quote

From RF_Developer:
"All this means that consts, in a sense, take up twice as much room as normal variable and have two copies, one in program memory, one in RAM. "

Like all things, stuff is not simple.

In fact a _RAM_ variable that is declared as initialised, so:

char XXXXXXXXX[10] = "XXXXXXXXX"

Has two copies, one in the ROM (containing the values to initialise with), and one in RAM.

#device PASS_STRINGS=IN_RAM

Does _not_ create a complete RAM copy, it only uses a tiny RAM buffer, and passes the variable 'through' this buffer. So PCM_programmers comments are exactly right.
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