Hey all,
I have an array in global space such as: const char myArray[] = "Hello World"
Codewarrior(10.5) stores this data somewhere in RAM. How do I force this into flash with minimum effort? Most other IDEs/Compilers i've worked with have had very simple compiler directives to do this such as __Flash ..ect. I can't seem to figure it out for code warrior. I know I can modify the linker to allocate a region in flash but that seems abit silly that I would have to do that to simply store a given variable in flash. Is there any practical solution?
已解决! 转到解答。
Hi Nathan,
which compiler/toolchain are you using? I quickly tried your example with CW for MCU10.6 (that's the latest version/release), and for Kinetis-L using GNU gcc it allocates the const variable in FLASH, as expected:
And I assume that you are not using a RAM target (but FLASH):
This let my believe that you are not using gcc (means: the Freescale ARM compiler)?
So I tried the same with a K20 (M4) using the Freescale ARM compiler with MCU10.6, and here it is in FLASH too:
There is a setting you might try:
But in my little test that constant array was in FLASH for me.
I have attached my project (just in case).
So it works for me out of the box, and I'm wondering what might be different in your setup?
Erich
Hello all,
How about writing a run - time calculated value in flash to retrieve at next boot?
With codewarrior, I was following a tutorial that created user areas in the flash and hence gave me some space. However Kinetis does not seem to let me do this on my M0 board. I only seem to find about 16 free words after address 0x410.
Has anyone got any such experience?
Many thanks,
Nikos
Hi Nathan,
which compiler/toolchain are you using? I quickly tried your example with CW for MCU10.6 (that's the latest version/release), and for Kinetis-L using GNU gcc it allocates the const variable in FLASH, as expected:
And I assume that you are not using a RAM target (but FLASH):
This let my believe that you are not using gcc (means: the Freescale ARM compiler)?
So I tried the same with a K20 (M4) using the Freescale ARM compiler with MCU10.6, and here it is in FLASH too:
There is a setting you might try:
But in my little test that constant array was in FLASH for me.
I have attached my project (just in case).
So it works for me out of the box, and I'm wondering what might be different in your setup?
Erich
Hi Erich,
I am using frdm-kl25z128 . I created a bareboard project in the CW 10.7. But I didn't got the flash address of a constant as you said in above post. I declared as const char test[]="hello"; but I didn't got the internal flash address, I got the address as "0x20002FF0" . Could you please help me...
Thanks,
Yadu
Hey Erich Styger,
Huge fan of your work and many thanks for your reply! I checked my example again and the "hello world" was stored in Flash. I must have been going crazy. Not sure what was going on yesterday. The only case i'm able to replicate was a non initialized const gets stuck in RAM which to be fair, isn't too odd. The compiler was whatever the default is. The ARM Ltd Windows GCC C Compiler? I must have missed that it was in flash until after I added the __inline(which isn't normally added for variables...)? Anyhow, thanks again.
Hi Nathan,
no worries. I have chased such kind of ghosts many times myself too.
And yes, __inline does not make any sense for variables. Maybe just some weird things were going on with the compiler.
As an additional hint: sometimes the make files do not recompile all the touched files. Doing a 'clean' or deleting the output folder for a 'tabula rasa' usually helps to remove such coding ghosts.
Erich
I have figured it out after some painful waste of time. (I figured out I was being stupid, see Erich's post below)
In global space, const char myArray[] = "Hello World" will be placed in RAM. You can see this by its address when debugging and using the Expressions window to view its location. You will see this location switch from RAM to ROM/FLASH once you add __inline. However, you must initialize it. For example: __inline const char Test[10]={}; will go into ROM but __inline const char Test[10]; will go into RAM.
Furthermore, if you wish to write to a variable in global space stored in ROM/FLASH, it must be in its own sector else you will create an exception once you attempt to write to it (because once a flash erase is performed, it will erase the data along with program code). The sector size on kinetis MCUs is 0x400 or 1024 or 1kB. Consequently, you must ensure your variable is sector aligned and takes up an entire sector. To do this you must use the align attribute. For example:
__attribute__ ((aligned(0x400)))
const myArray[0x400]={};
In my application, this data was stored at 0x8C00 which is indeed divisible by 0x400 or 1024 which is proof that the alignment was a success. Also, if you look at the datasheet you will see that 0x8C00 is within program space.
You can now use the PE component IntFlashLdd to write to this sector during program time. Or you can write to it using your own Flash driver for the Kinetis MCUs.
Look Mom, no linker file modification required!
Edit: Tried it again today and "const char myArray[] = "Hello World" " was in flash. Must have been missing something. Anyhow, atleast what I said about alignment and initialization appears to be repeatable.