CCS News

Using Overloading to Deal with Mixed ROM and RAM Data

Thursday 22 April, 2021

The CCS C Compiler supports C++ like function overloading. Function overloading allows the user to develop two functions with the same name, but have different parameters or return types. The CCS C Compiler can distinguish between RAM and ROM pointers when overloading. This is useful on the PIC® MCU which uses the Harvard architecture, meaning accessing the RAM and ROM is different. Since accessing RAM and ROM is different, the compiler needs to know which one the user is accessing so it can use the proper method.

Here is a simple example of function overloading using ROM and RAM pointers:

int Checksum(rom char * ptr) {

int cs;
while(*ptr!=0) // *ptr reads from ROM
cs += *ptr;

return cs;
}

int Checksum(char * ptr) {
int cs;
while(*ptr!=0) // *ptr reads from RAM
cs += *ptr;

return cs;
}

...
char data[10] = "Foo Bar";
const char hex[] = "0123456789ABCDEF";

label_cs = checksum("Hello World"); // Calls first funct
hex_cs = checksum(hex); // Calls first funct
data_cs = checksum(data); // Calls second funct

Checksum() has two functions, one for handling ROM pointers and one for handling RAM pointers. In the CCS C Compiler the 'rom' keyword specifies the ROM flash memory, if this is not specified the CCS C Compiler will use RAM. When Checksum() is called with the "Hello World" as a 'rom char *'

Some compiler built in functions deal with conversions from ROM to RAM pointers. For example strcpy() has two forms:
strcpy(ramstring, "Hello World");
strcpy(ramstring, buffer);

This is so the compiler can easily deal with awkward syntactical issues like this:
char string[] = "ABCDEFGHIJ";

ROM string moved to RAM and string is a RAM pointer. The CCS C Compiler also supports this syntax with all the appropriate conversions:
char string[10];
string = "Hello World";

Note that %s in a printf() is able to figure out if the string is in RAM or ROM however most string functions in string.h do not have overloaded versions for ROM data. For example if you want to do strcat(string,"...") then you must first make a function like this:

char *strcat(char *s1, rom char *s2)
{
unsigned char *s;

for (s = s1; *s != '\0'; ++s);
while(*s2 != '\0')
{
*s = *s2;
++s;
++s2;
}

*s = '\0';
return(s1);
}

Here is a more complex example of function overloading based on ROM and RAM pointers:

struct {
union {
rom char* pRom;
char* pRam;
};
int1 isRom;
} savedString;

void SetSavedString(rom char* pRom) {
savedString.pRom = pRom;
savedString.isRom = TRUE;
}

void SetSavedString(char* pRam) {
savedString.pRam = pRam;
savedString.isRom = FALSE;
}

void PrintSavedString(void) {
if(savedString.isRom)
printf("%s", savedString.pRom);
else
printf("%s", savedString.pRam);
}

SetSavedString((rom char*)"Hello World");
SetSavedString((char*) "foo bar");

SetSavedString() saves a (char*) or (rom char*) depending on what was passed in by the user to memory, and sets a flag denoting the type of pointer that is being used. The PrintSavedString() checks the flag to select the proper pointer, and prints the string.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.