How To Access Beyond 64K Memory in a Small Memory Model Project

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How To Access Beyond 64K Memory in a Small Memory Model Project

Jump to solution
1,309 Views
zegeyealemu
Contributor III

Hello All,

 

On the HCS12x platform, working on a Small Memory model project, I was unable to access memory locations beyond the 64K range reach event though I used Pragma Statements and far qualifiers. I am wondering what I am missing here.

 

Thank you in advance for your support.

 

Best regards,

Ziggy

Labels (1)
0 Kudos
1 Solution
1,056 Views
kef2
Senior Contributor IV

Hi Ziggy

First of all, if you are going to use paged RAM in small memory model, then you need to add -D__FAR_DATA to compiler command line. This is needed for proper variable initialization in paged RAM.

far keywords are needed only for pointer operations, they are optional. But #pragma's with proper __GPAGE_SEG / __RPAGE_SEG / __PPAGE_SEG around your paged data declarations / definitions are a must.

This works well with S12XE and small memory model

// paged RAM
#pragma DATA_SEG __GPAGE_SEG PAGED_RAM
int dt[] = {
   1,2,3,4,5
};
#pragma DATA_SEG DEFAULT

// paged flash ROM
#pragma CONST_SEG __PPAGE_SEG OTHER_ROM
const int dtc[] = {
   11,12,13,14,15
};
#pragma CONST_SEG DEFAULT

void main(void) {
  /* put your own code here */

   int i;
   volatile int j;

   for(i = 0; i < sizeof(dt)/sizeof(dt[0]); i++) {
         j += dt[i];
   }

   for(i = 0; i < sizeof(dtc)/sizeof(dtc[0]); i++) {
         j += dtc[i];
   }

View solution in original post

0 Kudos
8 Replies
1,056 Views
zegeyealemu
Contributor III

Good Morning All,

Thank you very much for your valuable solutions. I appreciate it very much.

Thanks again and best regards,

Ziggy

0 Kudos
1,057 Views
kef2
Senior Contributor IV

Hi Ziggy

First of all, if you are going to use paged RAM in small memory model, then you need to add -D__FAR_DATA to compiler command line. This is needed for proper variable initialization in paged RAM.

far keywords are needed only for pointer operations, they are optional. But #pragma's with proper __GPAGE_SEG / __RPAGE_SEG / __PPAGE_SEG around your paged data declarations / definitions are a must.

This works well with S12XE and small memory model

// paged RAM
#pragma DATA_SEG __GPAGE_SEG PAGED_RAM
int dt[] = {
   1,2,3,4,5
};
#pragma DATA_SEG DEFAULT

// paged flash ROM
#pragma CONST_SEG __PPAGE_SEG OTHER_ROM
const int dtc[] = {
   11,12,13,14,15
};
#pragma CONST_SEG DEFAULT

void main(void) {
  /* put your own code here */

   int i;
   volatile int j;

   for(i = 0; i < sizeof(dt)/sizeof(dt[0]); i++) {
         j += dt[i];
   }

   for(i = 0; i < sizeof(dtc)/sizeof(dtc[0]); i++) {
         j += dtc[i];
   }

0 Kudos
1,056 Views
zegeyealemu
Contributor III

Hi,

I think there is a bug within the datapage.c program that is responsible for the conversion of NEAR to GLOBAL. Can you please confirm if this is a bug or not?

Thanks and best regards,

Ziggy

0 Kudos
1,056 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi,

I just made a quick test. in small memory model project, declare a constant string "mystr" beyond 64K in paged flash. it can be accessed. can you please check attached demo code. can it help you solve your problem?


Have a great day,
Jennie Zhang

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,056 Views
zegeyealemu
Contributor III

Hi,

Thank you very much.

I realized that my pointer declaration was wrong. Correcting the declaration fixed the issue I was having. It was an error from my side.

I declared a pointer:

UINT16 far * pwFar;

when I should have done

UINT16 * far pwFar;

The compiler was ignoring the far key word due to a syntax error.

Thanks again and best regards,

Ziggy

0 Kudos
1,056 Views
iggi
NXP Employee
NXP Employee

Hi Ziggy,

I am responding little bit late as i was on a vacation. I kindly asked Jennie to provide a feedback on this thread in the meanwhile. Anyway we are glad you have sorted it out.

Cheers,

iggi

0 Kudos
1,056 Views
zegeyealemu
Contributor III

Good Morning Iggi,

Thanks for the response and info. Yes, I agree with what you have said that the memory mode only affects the default code gen output to generate the right opcode that is optimal to your chosen option.

I am modifying your sample HCS12x boot loader firmware. It is designed to be small in size not only in footprint but also in memory usage. The project is not created using Processor Expert and has a small startup code that is not fully fledged.

Once the boot loader has programmed application code I want to access part of the content of the application memory residing at a location above the 64K bytes range from the boot code prior to relinquishing control. In order to accomplish this I have tried creating pointers and variables like for e.g. byte far *byFarPtr and when attempting to load this pointer with 23 bits address value only the bottom 16-bits are loaded. My understanding is that the compiler was supposed to recognize the far qualifier and generate the appropriate op code that would load the 23-bits value but it is not doing it.

I am wondering as to what I am missing.

Thanks again and look forward to your response.

Best regards,

Ziggy

0 Kudos
1,056 Views
iggi
NXP Employee
NXP Employee

Hi Ziggy,

How do you exactly access those memory locations? Are you trying to place, code, variables, constants there?

Briefly:

Small memory model: Both your code and variables are put by default in non-banked locations.

The compiler will not insert any instructions to handle any page register. Variables will be accessed directly in non-banked locations and your code will be executed using JSR/RTS instructions.
Banked memory model: Your code is put by default in a banked location, but your variables are
put by default in non-banked locations.

The compiler will use instructions that handle the PPAGE register when accessing your code. The CALL instruction will be used when calling a function. This CALL instruction takes care of writing your function's page number to the PPAGE register prior to executing it. By default, the variables continue to be accessed as if they were in non-banked locations.

Regarding the linker parameter files (*.prm), what changes basically between the small and banked memory models parameter files is the location of the DEFAULT_ROM label.
The small memory model parameter file does not use the paged Flash locations. The label OTHER_ROM
is pointing to paged locations, but is not used by the wizard-created project. OTHER_ROM is only there for
the programmer to use it if needed.
It is important to understand that you can work with paged or non-paged objects in any memory model.
The memory model only affects the default location and the default compiler behavior.

For detailed information please see following appnote AN3784 (section 5, page 11):

Understanding the Memory Scheme in the S12(X) Architecture

Some additional information and examples, you can find in CodeWarrior Technical Note TN238 and TN240 located in CW installation folder which is by default - c:\Program Files (x86)\Freescale\CWS12v5.1\Help\PDF\

Have a great day,
iggi

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos