129 printf("%d %ld %u\n", 999, 9999, 99);
0xfe8a5b: 900063 LD D2,#99
0xfe8a5e: 0402 PSH D2
0xfe8a60: 90270F LD D2,#9999
0xfe8a63: 0402 PSH D2
0xfe8a65: 9003E7 LD D2,#999
0xfe8a68: 0402 PSH D2
0xfe8a6a: 98001217 LD X,#4631
0xfe8a6e: 0442 PSH X
0xfe8a70: BBFEF8F2 JSR 16709874 printf (0xfef8f2)
0xfe8a74: 0A69 LEA S,(9,S)
CodeWarrior for MCU
Version: 10.7
Build Id:160721
When compiled, the string "%d %ld %u\n" is located in flash. During startup, it will be copied from flash to RAM, so you can see a RAM address 4631 (0x1217) is set to X register. Is the copy operation required? If yes, there are many many printf functions in our code, they will consume many many RAM space.
Solved! Go to Solution.
Hi,
strings are considered as data by default.
To avoid copydown you can place pragma below:
#pragma readonly_strings on
e.g. add a prefix file (e.g. myPrefix.h):
#ifndef MYPREFIX_H_
#define MYPREFIX_H_
#pragma readonly_strings on
#endif /* MYPREFIX_H_ */
to include it to every source file in your project you add the prefix file here:
Now the object that represents strings (@148 in my example)is located at flash:
Hope it helps,
Stan
This code showcases a memory management process, illustrating how data is transferred from flash to RAM using printf. Interestingly, just like https://slope3dgame.com/ mastering the requires understanding optimal trajectories and resource allocation, effective memory handling ensures efficient performance in programming. The redundant copy operations could waste valuable RAM, just like time wasted in the game without sharp strategies.
Hi,
everything depends on your variable definition.
If it is RAM variable then it will be copied to the RAM and used as a RAM variable.
If it is defined as a volatile constant and placed into EEPROM space or any rom or const segment then it will be used from this space. You can create your special space for text constants (or not) in the PRM file ( can be found in the Linker Files folder of your project ) and then use it for constants placement.
Best regards,
Ladislav
Hi,
You may not know what I mean.
The format string "%d %ld %u\n" should be a constant, and it has been placed in the flash. During the startup, I mean in the initialization, or to be exact, in the function DoCopyDown(), (in the startup code, file starts12z.c) this string content is copied to RAM again. In the disassembly window, we can see this string is copied to memory address 4631 (0x1217), so 4631 is loaded to X pointer register.
Why not pass the flash address of this format string to printf, why we need the copy operation?
Hi,
it is not copy down function. I understood your issue wrong. It is just saving parameters onto stack for passing them to the function. It is standard parameters passing. Copy down function is a part of startup code - it is different story.
Of course, if you have repeating values and or strings you can create a set of outputs and send them all as a strings.
prm file>
* non-paged FLASHs */
ROM = READ_ONLY 0xFE0200 TO 0xFFFDFF;
ROM_STRINGS = READ_ONLY 0xFE0000 TO 0xFE01FF;
....
...
DEFAULT_RAM INTO RAM;
ROM_STRINGS INTO ROM_STRINGS;
....
main.c>
#pragma CONST_SEG ROM_STRINGS // part of the ROM stolen from entire ROM in the PRM file
unsigned char const s1[]="string1";
unsigned char const s2[]="string2";
unsigned char const s3[]="string3";
unsigned char const s4[]="string4";
unsigned char const s5[]="string5";
#pragma CONST_SEG DEFAULT
//**************************************
void main(void)
{
for(;;)
{
printf("s1 = %s\n", s1);
printf("s1 = %s\n", s2);
printf("s1 = %s\n", s3);
}
}
Best regard,
Ladislav
Hi,
It is copy down function. The evidences are listed below:
1. If we set a watchpoint at the RAM address (4631 (0x1217)), the program will stop there during DoCopyDown execution.
2. The string "%d %ld %u\n" is located at both RAM and flash:
3. The COPYDOWN section
Hi,
strings are considered as data by default.
To avoid copydown you can place pragma below:
#pragma readonly_strings on
e.g. add a prefix file (e.g. myPrefix.h):
#ifndef MYPREFIX_H_
#define MYPREFIX_H_
#pragma readonly_strings on
#endif /* MYPREFIX_H_ */
to include it to every source file in your project you add the prefix file here:
Now the object that represents strings (@148 in my example)is located at flash:
Hope it helps,
Stan