AnsweredAssumed Answered

Accessing more than 8kB RAM with object oriented C code for S12XE

Question asked by Szymon Mroczek on Dec 3, 2014
Latest reply on Dec 5, 2014 by Edward Karpicz

Hi All,

 

We write C code in an object oriented manner for our S12XE-based units.

This means that all the functions take pointers to data as arguments.

This way we produce nice, portable, reusable and testable code. And we have a lot of it.

 

We recently needed to create a multi-CAN router capability.

That meant that we needed to have a lot of message buffers of considerable size.

So we ended up having around 10kB of RAM consumed.

By default, only 8kB of non-paged RAM is available in the CodeWarrior project.

I added page FC to get additional 4kB of RAM (additionally to already available 8kB of non-paged area between 0x2000 and 0x4000 address space).

In linker file (.prm) this page is assigned to DEFAULT_RAM segment, so we have it like this:

 

SEGMENTS  /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */       RAM           = READ_WRITE    0x2000 TO   0x3FFF;       ROM_C000      = READ_ONLY     0xC000 TO   0xFEFF;       PAGE_E0       = READ_ONLY   0xE08000 TO 0xE0BFFF;       PAGE_E1       = READ_ONLY   0xE18000 TO 0xE1BFFF;       PAGE_E2       = READ_ONLY   0xE28000 TO 0xE2BFFF;       PAGE_E3       = READ_ONLY   0xE38000 TO 0xE3BFFF;       PAGE_E4       = READ_ONLY   0xE48000 TO 0xE4BFFF;       PAGE_E5       = READ_ONLY   0xE58000 TO 0xE5BFFF;       PAGE_E6       = READ_ONLY   0xE68000 TO 0xE6BFFF;       PAGE_E7       = READ_ONLY   0xE78000 TO 0xE7BFFF;       PAGE_F8       = READ_ONLY   0xF88000 TO 0xF8BFFF;       PAGE_F9       = READ_ONLY   0xF98000 TO 0xF9BFFF;       PAGE_FA       = READ_ONLY   0xFA8000 TO 0xFABFFF;       PAGE_FB       = READ_ONLY   0xFB8000 TO 0xFBBFFF;       PAGE_FC       = READ_ONLY   0xFC8000 TO 0xFCBFFF;       PAGE_FE       = READ_ONLY   0xFE8000 TO 0xFEBFFF;       RAM_FC        = READ_WRITE  0xFC1000 TO 0xFC1FFF; END  PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */     _PRESTART,     STARTUP,     ROM_VAR,     STRINGS,     NON_BANKED,     COPY                INTO   ROM_C000;     DEFAULT_ROM         INTO   PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8, PAGE_E7, PAGE_E6,                                PAGE_E5, PAGE_E4, PAGE_E3, PAGE_E2, PAGE_E1, PAGE_E0;     DEFAULT_RAM         INTO   RAM, RAM_FC; END

 

I got linked warning L1128: Cutting value _Range beg data member from 0xFC1000 to 0x1000.

This means that linker placed some RAM data into address 0x1000 instead of 0xFC1000 because no __FAR_DATA compilation macro has been added to compilation command.

Anyway this will work now because page FC is mapped to 0x1000 address so refering to data at address 0x1000 actually refers to data at address 0xFC1000.

But this will not work when we need more pages (FD and so on).

 

According to Technical Note TN 238 to use more RAM pages I should mark my data (variables) with special pragma like:

#pragma DATA_SEG __RPAGE_SEG PAGED_RAM unsigned char rub_far_var; #pragma DATA_SEG DEFAULT 

or

#pragma DATA_SEG __GPAGE_SEG PAGED_RAM  unsigned char rub_far_var; #pragma DATA_SEG DEFAULT

 

to tell compiler/linker to place that data into RAM pages.

This is not nice (portability) but acceptable.

What is not acceptable is that to reffer to this data with a pointer, that pointer has to be specially qualified like:

unsigned char * __rptr ptr_on_far_var;

or

unsigned char *__far ptr_on_far_var;

 

This means that all our libraries that use non-qualified ("normal") pointers will not work with data allocated to paged RAM.

I checked that and this is true, for data allocated to address 0xFC1020 its pointer inside one of our libraries will show address 0x1020...

 

So effectively for us we can only reach 12kB of RAM memory even if we use S12XEP that has 64kB of RAM...

Otherwise our libraries won't work.

It is not possible to rewrite those libraries to have (for example) far pointers because they will stop compiling on other targets (windows, linux, other MCUs)...

 

Did anyone of you faced this kind of problem?

Do you have any idea what to do now?

We are lucky we needed "only" 10kB.

I don't know what would happen if we needed more than 12kB of RAM...

But I know I need to figure something out because some new projects will require lot more RAM...

Should we start to think about looking for another MCU?

 

Waiting for your ideas.

Szymon

Outcomes