Hi all, please help me understand data compressor.
I do not understand, why compressor compress the constants in flash. I believed that only compressed are the data in flash, that are used to initialised variables in ram with a given value. Why even the data in ram are compressed? But what I do not understand in all, what are my data in flash (const volatile - because can be changed by programing flash from the code in run time).
C++ code: #define SECTOR_ADDR_for_Config 0x080E0000 const volatile DISTA_konfigurace_flash_typ F __attribute__((at(SECTOR_ADDR_for_Config)))= { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ..... up to 1024 bytes
MAPFILE: Load Region LR$$.ARM.__AT_0x080E0000 (Base: 0x080e0000, Size: 0x00000400, Max: 0x00000400, ABSOLUTE, COMPRESSED[0x00000190])
Execution Region ER$$.ARM.__AT_0x080E0000 (Base: 0x080e0000, Size: 0x00000400, Max: 0x00000400, ABSOLUTE, UNINIT, COMPRESSED[0x00000190])
Base Addr Size Type Attr Idx E Section Name Object
0x080e0000 0x00000400 Data RW 311 .ARM.__AT_0x080E0000 dista_konfigurace.o
Can anyone help? Thank you, Ludek
Thank you for so clearly describing which processor you are using, and which memory address ranges that represents flash and RAM. That really did help a lot when trying to understand your post...
I am using STM32F407 RAM start at 0x2000 0000 Flash start at 0x0800 0000 , size 1MB
I could see, that writing const only, shows that section has attribute RO. Adding const volatile the section is market as RW and compression on the data is applied. What I do not understand, why are data, that are already on its place compressed. The structure that varible represent does not fit any more and its members contain incorrect data, since the decompression is not performed and even has no sense to be performed.
thank you for help.
Ludek
So maybe you could explain the concept of having volatile (asynchronously changeable) data in a non-modifyable flash address?
I think you are tricking yourself when you play with const volatile and then gives an absolute address in flash.
To do advanced stuff, it's better to use the scatter file and specify that a segment or object file should have data stored using a specific policy. And then make sure you give good load and execution regions to use.
I will give explanation. I am using const in order to preven accidental write to the variables. I use const in order to be able to initialise variable. Because it is configuration that had to be present everytime, even without power.
I need to exchange this configuration via Ethernet. So if it is not volatile, some optimalisation can take place and use variable values as direct operands and the effect of configuration exchange will not take place.
That is why const volatile. And it has to be on a given address, because, it is in different flash bank allowing me to erase this part no affecting the program code. And finally, I am changing also firware remotely and configuration stay untouched.
I can live with compress off solution, but I am courious, why the data are compresed in this flash region. I gives me no sense, and even do not understand what linker planed to do with this compressed data in this place.
thank you for your patience, Ludek
You are tricking the linker into thinking it is RAM data - because normal flash data isn't volatile, except when the flash block gets an erase command.
So the linker thinks it should have a compressed copy in flash (to save space) and extract to RAM on each reboot.
Next thing: volatile is about asynchronous changes. The compiler has access to very few registers. So just calling normal functions (assuming you don't inline them or bend your back backwards to get maximum global optimization) would normally be enough to avoid issues with caching. And many processors have dedicated instructions to force barriers.
Once more: consider using a scatter file.
It might depend how the load regions are nested, you'd need to show the scatter file.
Compression suggests it is being moved, I'd review the table Region$$Table$$Base to see what it is doing with the statics.
It would only need to be volatile if changed outside of normal program flow, ie interrupt, or hw changing registers in a peripheral. If you call another function to write flash that doesn't count, and it also won't save you from the flash being cached, as volatile will still read the stale content, at least potentially.
My system reboot after changing the flash configuration. I need that no information from the configuration is stored as direct operands instead of using changed data from updated flash. So the volatile is I think appropriate. Is there any other method preventing it?
I still do not understand what compiler and linker plan to do with the compressed data. Where do they plan to decompress it. To the RAM? where. Or to the same location the compressed data are now, in Flash? From Flash to Flash in the same location?
I would like to learn how to use Scatter File, can you recommend me some good link?
thank you. Ludek
The linker is the thing that uses it, so it is surely obvious that the linker manual would be a sensible starting point.
www.keil.com/.../armlink_pge1362065968963.htm
Thanks for all suggestions, Ok,
If I accept that compiler/linker behaviour is senseless because it does not know what to do with RW constant in flash, what can I do in order to meet my needs:
- I need the data to be constant - not changeable by standard code - I need it to be placed in flash - in order to store configuration of the device - I need to place it to a given address - so that it is in next erasable flash sector that main program - I need it not to be optimized as I experienced once - I need that all the data of the big struct can be found at the given address and all its members. - And even more, I need some starting values in my configuration stored.
During using it (over a year or two), I faced only two problems: - once some data were stored to registers, so I added "volatile" - some time the default data were compressed in my struct so I set "--compress off" I did not needed scatter file or another approach to reach it. But now, I am facing problem (described in other thread), so I started to ask "why" some things happen (compression of const data and so on) in order to more understand and probably to solve my issue (described in other thread).
I found, that this only fullfils "const volatile _AT_ = {default data}" . But it confuses a linker a bit... so I would like to do it really correct and clean.
Can scatter file help me with this? How?
thank you, Ludek
You can slice the flash into an arbitrary number of individual address ranges with the scatter file.
So you can create a specific flash region that corresponds with a specific flash sector.
And you can configure in the scatter file that the RO data from a specific object file should be stored in this specific flash region.
Whe the scatter file has the same load and execution address range for this flash region, then the startup file will not contain any code to try to copy the data on boot - the loader knows the data is already at the correct location.
You want the data to be const - but it's being stored in flash that really makes the data write-protected.
I would like to see the code construct where the compiler did ignore reading the const data and instead hard-coded the values when generating the code. That should normally not happen, since the compiler doesn't even know the value of variables from a different object file, unless you really go all-out with global optimization.
Per,
thank you for clear explanation. This could help I think. Regarding the const... The flash does not mean it is write protect from definition. Simple write to the flash write to the flash, once it is unlocked and prepared for write.
And second, the write to the const variable is prevented by the compiler that stops you doing it.
Regarding the construct that fills the flash with something else I will write tomorrow my case.
have a nice evening.
View all questions in Keil forum