RAM or ROM where is a #define stored?

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

RAM or ROM where is a #define stored?

Jump to solution
12,683 Views
ohanica
Contributor III
Hello everybody,

I've got a question on the constants I use in my C-program. I'm using a lot of constants in my program like

#define CONST_VAR  value

where value are signed/unsigned integers or floating points like pi.

My question is where are these constants stored in the memory of my HCS08DZ60 microcontroller, and how many bytes do they occupy? Are they stored in the same region as global variables, i.e. in the STACK? Wich region of the memory does the stack belong to? In the prm-file of my project I can modify its size, but I still don't know where all these variables/constants are stored (Z_RAM, RAM, ROM1, ROM) in the memory.

Could someone tell me the place and size of storage for the constants in the following lines:

//global variable
UINT32 my32BitVariable;
UINT8  my8BitVariable;

//definitions
#define MY_CONST_1   130
#define MY_CONST_2   -13
#define MY_CONST_3   0.884637
#define MY_CONST_4   600

The problem I have to deal with, is that some variables simply do not work correctly. And I think this is because they are stoerd in a memory region that is to small for all of the variables/constants  declared.

Many thanks,
Johannes
Labels (1)
Tags (1)
0 Kudos
Reply
1 Solution
5,639 Views
CompilerGuru
NXP Employee
NXP Employee
in C a #define is nothing else than a textual replacement.
Therefore a #define ONE 1
is nothing else as if you would write 1 at all the places you typed in ONE in your source code.

Therefore your question is basically where are all the numbers stored. Well, it depends on how you use the numbers. Most tipically they are causing specific code to be generated and therefore end up in the flash.

I would recomment to read a good C book, i think it will explain a lot of the strange things in the C language you have to learn, then a lot of the things will become clear.

About your actual problem, note that all computations in C are done with int unless some argument has already a larger type (check a good C book for the details...). For the HC08, an int has 16 bits.
Therefore "30000+30000+30000" wont get 90000, but instead "90000&65535" (=90000-65535, whatever that is :smileyhappy:.

If you need 32 bit calculation, use a L suffix ("30000L+30000L+30000L"), this will generate more code of course. If you want unsigned arithmetic, use a U suffix ("30000U+30000U").

Daniel


View solution in original post

0 Kudos
Reply
11 Replies
5,640 Views
CompilerGuru
NXP Employee
NXP Employee
in C a #define is nothing else than a textual replacement.
Therefore a #define ONE 1
is nothing else as if you would write 1 at all the places you typed in ONE in your source code.

Therefore your question is basically where are all the numbers stored. Well, it depends on how you use the numbers. Most tipically they are causing specific code to be generated and therefore end up in the flash.

I would recomment to read a good C book, i think it will explain a lot of the strange things in the C language you have to learn, then a lot of the things will become clear.

About your actual problem, note that all computations in C are done with int unless some argument has already a larger type (check a good C book for the details...). For the HC08, an int has 16 bits.
Therefore "30000+30000+30000" wont get 90000, but instead "90000&65535" (=90000-65535, whatever that is :smileyhappy:.

If you need 32 bit calculation, use a L suffix ("30000L+30000L+30000L"), this will generate more code of course. If you want unsigned arithmetic, use a U suffix ("30000U+30000U").

Daniel


0 Kudos
Reply
5,639 Views
ohanica
Contributor III
Hello,

oh, oh, oh... I remeber some C lessons. As you wrote down what a #define makes, I remebered it was only a replacement of text. I hae to admit it was a bad question.

In the meanwhile I found information on where global and local variables are stroed to and whats up with static local or static global variables...

In the DIRECT PAGE there are stored variables like the port I/O registers and so on... AND there is some place for global variables in the DIRECT PAGE page too (info from: http://www.freescale.com/files/microcontrollers/doc/app_note/AN2093.pdf). But how can I see how much space there is left in the DIRECT PAGE   for (my) global variables, and how can I assert  a global variable to DIRECT PAGE? How many Bytes/Variables can I assert to the DIRECT PAGE.

What is the HIGH PAGE for? is it useful to place variables in this memory area? what is the difference between HIGH PAGE memory and RAM?

best,
Johannes
0 Kudos
Reply
5,639 Views
Lundin
Senior Contributor IV
Direct page only applies to some microcontrollers, it is very much cpu-dependant. How large this area is would also be cpu-dependant, but it is typically the first 256 bytes.

To see how much space certain things take up, look at the .map file generated by the linker. It should be located in the bin directory of your project, and may also be included in it from the IDE.

To assign variables to a certain memory location in CW, you use #pragma DATA_SEG (global variables), #pragma CONST_SEG (global constants), #pragma CODE_SEG (code), and so on. See the manual for details.

---

Global variables, and those with the keyword static before them (both global and local statics) are stored in a certain part of the RAM that has a deterministic size at compile time (static memory allocation). The rest of the variables are stored in segments that have a variable size, either the stack (automatic memory allocation) or the heap (dynamic memory allocation).

ANSI C states that they must be initialized by the system before the execution of main(). This will happen even if the programmer didn't initialize them to a value explicitly, if he didn't, they will be set to zero. This is the only kind of variables you can count on having the value zero before you set them to anything, though good programming practice requires that you assign them a value still, and not rely on the fact that they are zero.

All of this make things tricky in NVM-based systems. CW has solved this by executing code from a file called "start08.c" or similar - this is a necessary evil to conform with ANSI C (which was designed for RAM-based systems). In a safety critical system, you will not run this initializing code, but rather set your static variables to a value in runtime, just before they are used, to prevent the RAM cells from being corrupted: there could in theory be years of execution in between the start of the program and the usage of a static variable.
0 Kudos
Reply
5,639 Views
ohanica
Contributor III
Hi Lundin,

thanks for the explanations.

What is the difference between Z_RAM and RAM segment? Why is the RAM split into this two segments? Does it make sense to place frequently used globals into Z_RAM?

many thanks,
Johannes
0 Kudos
Reply
5,639 Views
CrasyCat
Specialist III
Hello
 
Yes this is the idea.
ZRAM is located on the direct memory area. Placing frequently used variables in that memory area should optimize both code size and execution time.
 
The .map file generated by the linker tells you how many times each variable is referenced within the application.
 
This is indicated in the "OBJECT-ALLOCATION SECTION" in the column "Ref.".
 
CrasyCat
0 Kudos
Reply
5,639 Views
ohanica
Contributor III
Hello!

this is my prm-file
Code:
/* This is a linker parameter file for the mc9s08dz60 */NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */    ROM                      =  READ_ONLY    0x1900 TO 0xFFAD;    Z_RAM                    =  READ_WRITE   0x0080 TO 0x00FF;    RAM                      =  READ_WRITE   0x0100 TO 0x107F;    ROM1                     =  READ_ONLY    0x1080 TO 0x13FF;    EEPROM                   =  NO_INIT      0x1400 TO 0x17FF;ENDPLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */    DEFAULT_RAM                         INTO  RAM;    DEFAULT_ROM, ROM_VAR, STRINGS       INTO  ROM; /* ROM1 In case you want to use ROM1 as well, be sure the option -OnB=b is passed to the compiler. */    _DATA_ZEROPAGE, MY_ZEROPAGE         INTO  Z_RAM;ENDSTACKSIZE 0xF0  /* by default it's been 0x50 */VECTOR 0 _Startup  /* Reset vector: this is the default entry point for an application. */


If I want to place MyVar (44bytes) to Z_RAM, is it correct to do it as follows? This is what I understand from the CW-help.
Code:
...#pragma CODE_SEG Z_RAM///MyVariable, holding frequently used information (placed in direct memory area (Z_RAM))MyVariable_Type  myVar; #pragma CODE_SEG DEFAULT               ///Global time1 variable (inc = 100ms)UINT32    gTime1;....

 The result in the .map file is not changing compared to the situation when the two #pragma- lines are not used: In the object-allocation section the Variable myVar is allocated at the address 100(hex), which is outside the first 256 bytes, i.e. outside the zeropage.

How do I get this variable into Z-RAM (somewhere below the address 100(hex))?

best,
Johannes P.
0 Kudos
Reply
5,639 Views
CrasyCat
Specialist III
Hello
 
Check your reference manual or on line help system.
 
In order to define a user defined segment for a variable you need to write:
 
#pragma DATA_SEG MyData
///MyVariable, holding frequently used information (placed in direct memory area (Z_RAM))
MyVariable_Type  myVar;
#pragma DATA_SEG DEFAULT 
 
If you wish to place the variable on the direct page you need to write:
#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE
///MyVariable, holding frequently used information (placed in direct memory area (Z_RAM))
MyVariable_Type  myVar;
#pragma DATA_SEG DEFAULT 
 
Then you need to make sure the defined sections are placed accordingly in your .prm file  For example:
PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
    DEFAULT_RAM , MyData                        INTO  RAM;
    DEFAULT_ROM, ROM_VAR, STRINGS       INTO  ROM; 
    _DATA_ZEROPAGE, MY_ZEROPAGE         INTO  Z_RAM;
END
 
Check the Compiler_HC08.pdf file for more information on segmentation.

CrasyCat
0 Kudos
Reply
5,639 Views
ohanica
Contributor III
Thanks guys, this was really helpful!

The variable is now placed at the adress 80(hex).

best,
Johannes P.
0 Kudos
Reply
5,639 Views
Lundin
Senior Contributor IV
Use

#pragma DATA_SEG MY_ZEROPAGE

for RAM variables. #pragma CODE_SEG only applies to program code.
0 Kudos
Reply
5,639 Views
CompilerGuru
NXP Employee
NXP Employee
Just for completeness,
use

#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE

With "just" "#pragma DATA_SEG MY_ZEROPAGE" the compiler will place the variables at the expected addresses, but he wont take advantage of the more efficient zero page access. The __SHORT_SEG is especially for this purpose.

Daniel
0 Kudos
Reply
5,639 Views
ohanica
Contributor III
Hello,

an additional question:
what happens if I declare (global) variables as static?

(//global)
static UIN8 aStatic8BitVar;

where is this Variable stored?

greetx,
Johannes
0 Kudos
Reply