This is probably a rookie question. Pure software engineer here with very little hardware experience.
My current mission is to set up a small chunk of uninitialised RAM for use as a 'What the hell happened' area after a watchdog failure. I want the majority of memory to be initialised in the normal way.
It works - after a fashion. I'm using an STML486VGTx, just with its 128K of internal memory.
The scatter file I've created (from the automatically generated one) looks like this:
===
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00100000 { ; load region size_region ER_IROM1 0x08000000 0x00100000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00017FE0 { ; RW data .ANY (+RW +ZI) } RW_NOINIT 0x20017FE0 ABSOLUTE NOCOMPRESS UNINIT 0x20 { .ANY (NHNOINIT, +RW) } RW_IRAM2 0x10000000 0x00008000 { .ANY (+RW +ZI) } }
=== and I've specified an array in the code that uses the NOINIT area...
uint8_t DataDump[32] __attribute__((section("NHNOINIT"),zero_init));
Having discovered that the 'zero_init' attribute is needed to... not zero init it.
My problem is one of confidence - With the UNINIT area tucked up right against one of my other areas of RAM, there's potential that I'll scrobble off the end of an array or something somewhere else and nix the data I want to keep.
Ideally, I'd like to create a separate 'address block' for the UNINIT section: Something like:
RW_IRAM1 0x20000000 0x00017FE0 { ; RW data .ANY (+RW +ZI) } RW_NOINIT 0x30000000 ABSOLUTE NOCOMPRESS UNINIT 0x20 { .ANY (NHNOINIT, +RW) }
So that it's off on its own with a big moat around it.
Is this possible?
The linker will happily do it, but it hard faults as soon as I try and access the memory.
What are the restrictions on creating mapped areas of memory? Is the internal memory of the STML486 restricted to those two sections at 0x10000000 and 0x20000000, or should I be able to branch them into other mapped areas?
Ta for any help.
Never mind - just found the data sheet. Internal memory fixed at 0x10000000 and 0x200000000
Result
If you need some of RAM to be untouched by program...why you cannot hide it from linker? You can set up begin address of RAM and it's size. So you can reduce size to separate some data at the end. In program you can place variable at specific address and it can be (theoretically) everywhere (like mapping of peripherals). It sould be easier to achieve than fighting with linker.
Basically - just miss out the UNINIT section in the scatter file entirely? It's possible. But now it's working, I don't want to play with it particularly :)
That said, I believe that's basically what's happening here anyway - the attributes for the section
ABSOLUTE NOCOMPRESS UNINIT
are saying to the linker "This bit here - don't touch it - AT ALL".
Also, by telling the linker about it, you can give it a name - in this case NHNOINIT. You can then use that as the section attribute for the variable in the code. If you ever need to change the location of the section in the scatter file, the variable automatically follows it without having to change the code.
Yes, you're right. I just wrote other way to achieve the same effect ;)