I hope Erich Styger will notice this post and help me out but all other experts in linkers and section attributes for data in flash memory are very welcome. Thanks.
This image shows the collage of the different screenshots of my situation.
* I split MKL28Z's 512KB flash memory into 508KB (code) + 4KB (read/write data non-volatile area).
* I got an example project code from NXP support, modified pflash imported SDK project, that defines a string, tt, in the .text / code area by using a sectioning macro from <cr_section_macros.h>
* Both our builds result in the warning: setting incorrect section attribute for .text.$Flash2
* show different files automatically created: linker description script, map, MCU settings memory map, snippet of code where tt is defined, build warning, manage linker script input section
QUESTIONS: What can I do to make this warning disappear? where should I do it? in linker section file? in manage linker script?... what "Input section description" (in place of *(.dummySectionName1) should I state on description column, in the Managed Linker Script shown on bottom right corner of image?
Thanks for all the help.
Hi again, thanks for your numbered response. They all help confirm my simple understanding & what I have learned.
I have follow-up question/comment on items #2 & #6 here:
2. so builder automatically put up ".rodata" in my Flash2 section. You know I only have 4KB assigned. Do you know how big this ".rodata" area is? and is it correct to say it is on the uppermost area of the 4KB starting at 0x7F000? I'm asking because the address mapping is not specified on any of the Debug & .map files.
6. I think I see what you mean... you are right, the linker script is always automatically generated everytime I make changes to the code, it "re-arranges" the memory mapping again & again but only if there are changes.
Also, since my debug configuration GUI tools tab is check on button: erase, blank check, program, verify, I've noticed that what's in my flash is not erased if I build without any code changes. But if alter a code line, it will rebuild & erase before flash programming, so basically resetting my Flash2 area to FF's (blank).
Thanks for your response & help.
2. DO NOT get hung up over .rodata in flash area 2 (Flash2). It is a placeholder for YOU to place data IF YOU EXPLICITLY PLACE IT THERE (using the macros defined in cr_macros.h). If you do not use it then it has ZERO size.
Thanks for your comment.
This is screen shot of automatically generated map files - I don't have any .text macros on this. I guess the MCUXpresso toolchain build/linker created the SECTIONS based on the "split" I did on the Flash 512KB memory.
Do you know why the builder put ".rodata." label within my 4KB Flash2?
And if I understood your statement above where application code will not go over or exceed 508KB, thanks to the split-up of Flash into 508KB and 4KB. Both are still labeled as "text_" though. Do you know if the builder will actually "complain" & post an error if the application code grew more than 508KB? Is that what you are saying is the ADVANTAGE of splitting it up in the project's MCU property/settings? But effective only within MCUXpresso IDE builds though, correct? Thanks for your response to my questions.
Here are the map files:
1. I guess the MCUXpresso toolchain build/linker created the SECTIONS based on the "split" I did on the Flash 512KB memory.
Correct. MCUXpresso automatically creates all the sections for you, based on your memory configuration
I asked this question on related thread>
(Please refer to the original post that shows the big picture --- see the topmost image that has MCU setting table of memory map > Flash, Flash2, RAM, RAM2)
As an aside, even though I'm not using any cr_macros… & now just using #defined direct address to Flash memory, do you know if the MCU setting splitting-up of Flash from full 512KB to 508KB Flash & 4KB Flash2, necessary?
Comments are welcome.
I've not seen a 'related thread'...
However, it is a good idea to split your flash. If you do not split it, there is a danger that your application code will grow (to larger than 508k) and so be placed into your storage area. By restricting it to 508k you can guarantee that it will never 'overflow' into your storage area. You may think it unlikely that your application will grow that large, but, it is good practice and what if somebody else takes over your project snd doesn't realise that the top 4k is used in this way...
Finally fixed all build errors and warnings.
All built clean as:
16:35:24 Build Finished. 0 errors, 0 warnings. (took 12s.6ms)
Sorry about the dumb question again... please allow me to blame it on lack of sleep & tiredness.
You are right, I'm in control & malloc() will be taken from SRAM, not Flash. I guess that example I saw before was from one of the imported SDK projects that was "programming"/writing allocating to flash memory also by direct-addressing so that's why it went WITHIN flash.
And the fix to build errors was my fault too, one reason was copy-paste-no-thinking-right... the error was:
Nothing wrong with your approach.
how do you think that Flash2 will be overwritten? It’s flash. Only you, using IAP calls are able to write to the flash in your code.
I stopped using any cr_macro_header.h macros in the code few days ago. No __TEXT, no __RODATA, etc.
I just keep my MCU settings in MCUXpresso as such, split-up Flash to Flash + Flash2.
In my code, I have made definitions of "hardcoded" direct address range that I know where Flash2 starts (0x7F000).
I have restructured all my planned data that will go in flash into 3 structures.
I'm currently building this "arrangement", cleaning up syntactical errors I'm fixing right now.
So far THAT warning about "attributes" has not come-up again. Unless maybe not because there are still other errors & other warnings I need to correct & clean-up.
We shall see.
What do you think? simply not using any of cr_macros_header.h macros is good programming practice? And simply just define FLASH2_START_ADDRESS... FLASH2_SIZE.... and use the Flash driver function calls to erase, program, read are ok to do?
My new concern which I shall test is Flash2 being overwritten - e.g. if part of my code allocates memory. Last time I was debugging, I noticed it allocated memory at the top of Flash block 0 (1st/lower 256KB), instad of block 1(2nd/upper 256KB) which is where Flash2 is located (top 4KB of 512KB total flash memory).
I'm sorry but I need to be able to read/write several data in flash.
The example project code has been able to do erase, program, readback well. It works.
My problem is "cleaning-up" build warnings.
This data in flash is just a small part of a big embedded system that has many different operations. We are putting data in flash non-volatile memory so in case of power outage, the data is retained. Besides regular data, RTC time, like days, hours, minutes elapsed need to be tracked. The system will have battery backup but to save that battery life, I'm only keeping the RTC on while I put the rest of the system modules to very low leakage stop mode (VLLS0) as possible to switch them off/ disable them.
Thanks for your comment though.
So, the warning is because you have defined a piece of data (that by definition is writable) into flash (which is not writable). There is a fundamental difference there that cannot be resolved and is correctly being reported by the linker.
As you know, you cannot write to random addresses in flash - you need to write pages, which need to be on page boundaries. The usual way to do this is to define a specific section in your code (not Text) and use the linker to place that into flash on a page boundary. You then use IAP functions to write to that location.
To answer the questions you originally posed:
Why is there .rodata?
- rodata is Read Only data. You can place text (code) or read-only data into your Flash2 section. I would suggest that you want to place your data into the rodata section (instead of text) using the appropriate cr_macros macro.
How to eliminate the warning?
- define your data as const. This informs the compiler that it is data and that it is constant (cannot be written to) and if you try to the compiler will issue an error. Yes, you are going to use IAP calls to write to this data, but that is not the same as just assigning it a value in C.
So, you need to define your data as:
__RODATA(Flash2) const char tt = "abcde" ;
As a minimum, you’ll need to define your data as const- if it is in flash it cannot be anything else. And if you define it as const, it will automatically be placed in flas anyway - without needing to use any macros