Hi
I am working with a microsemi cortex M3 ARM with uVision and ulink2 mdk 5.12 and I am getting a PRECISERR bus fault from a memory read during initialization by the scatterloader decompress routine. It is definitely trying to read a bad address. This code is created by the linker to initialize my memory/variables so its not something I have direct control over.
Here is the goofy thing, I found that I could get around getting a hard fault 1 time if after hitting the hard fault I get out of the debugger and right back in. Then I can run as long as I don't try to restart by clicking the reset button on uVision.
I don't understand why this would make any difference but it does and allowed me to work for the past few weeks although its slow and awkward.
This weekend my luck ran out and now I get that hard fault every single time I trying to run. My trick no longer works. All I did just before this started was to add 1 line of code and recompile and reload.
Here is a interesting clue. Out of desperation I recompiled my entire project and reflashed and I was able to get to Main! All I did was recompile. I did some testing and had to make one minor change to a index and recompiled and now I am back to getting that hard fault every time. None of my tricks work either.
Its still coming from the same loop in the decompress routine where it reads a address that is just below my DDR memory. 0x9FFFFEFF
It really sounds like some kind of memory alignment issue or something like that. But the clues do not seem to be related.
Why would adding or removing a few bytes from my code cause the decompress routine to hard fault? Why did recompiling the project allow me to get past the decompress problem once? Why does clicking reset and trying to run the same code cause the decompress to suddenly not work? Why would getting out the debugger and back in allow it to do the decompression correctly one time?
Arrrgg.
I am totally stopped from doing any more development because the decompression code always causes a hard fault from the same address and memory access.
Has anyone experienced anything like this before?
Hmmm. After making that change to put everything into one region when I start the debugger and it downloads the symbols I get a Out Of Memory error.
I have never seen this before. It must be caused by my moving basically the heap and my variables into the same region. If I put the DDR section back into its own region the problem goes away.
The only thing I can think of that it is now trying to do is download the heap to DDR. Its very large and would probably cause a memory problem on the pc.
I don't know why it would want to do that. But this out of memory error cause the debugger to crash and close.
Have you ever seen that happen before?
The heap isn't downloaded anywhere.
The download only contains the code and the initial data.
It's only when the program starts to run, that the program will allocate any stack and heap and copy+zero-initialize global data.
But with a single download region, all nonvolatile data (code + initial variable values) must fit in your nonvolatile memory. By downloading the initialized variables directly into RAM, you cheat about the maximum program size supported by your processor. And you fail, because the program doesn't support a reset - all non-volatile information just has to fit in the available non-volatile memory.
If the program is too large, you have to consider if there are static information that doesn't need to be part of the program but that can instead be seen as "database content" that you can store in some EEPROM or on a SD-card or similar. Else, life will quickly get more interesting - you might have to create a loader and place the application directly to some memory card or serial flash and have the loader retrieve it directly into DDR memory on startup.
But whatever you do, you can not have a setup where the debugger places some of the nonvolatile data directly into RAM, since your RAM is not nonvolatile. You just get a situation where it "almost" works when running from the debugger. But that fails badly in real life.
I was able get around whatever the problem is by keeping just the heap in the ddr region and moving the RW and ZI into the load region. Now all global variables are being initialized correctly every time.
The out of memory crash does not happen now.
I don't know or understand why putting the heap in makes it run out of memory. I just know the scatter file below works now.
I allocated a part of the DDR to put the image from external flash that will be booted by the bootloader. As you suggested. No variables will get stepped on now.
FLASH_LOAD 0x00000000 0x00080000 ; load region size_region { ER_RO 0x00000000 0x40000 ; load address = execution address { *.o (RESET, +First) *(InRoot$$Sections) * (+RO) * (INITDATA) } ER_RW 0x20000000 0x100 { bootjump.o (.data) bootjump.o (.text) } ER_RW2 0x20000100 0xFE00 { startup_m2sxxx.o (STACK) } ER_BOOT 0xA0000000 0x40000 { ; reserved for boot loader to load image } ER_DDR 0xA0040000 0x10000 ; RW data DDR 256MB { * (+RW +ZI) } } MDDR_RAM 0xA0050000 0x9FFB0000 { ER_DDR2 0xA0050000 UNINIT 0x9FFB0000 ; RW data DDR { * (HEAP) } }