stblib srand() corrupts data in .noinit

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I set up some values in the .noinit section but when I call srand() they are overwritten. The disassembly and memory map shows why:

00007BDA  LDI R26,0x00		Load immediate 

00007BDB  LDI R27,0x00		Load immediate 

00007BDC  STS 0x2009,R24		Store direct to data space 
00007BDE  STS 0x200A,R25		Store direct to data space 

00007BE0  STS 0x200B,R26		Store direct to data space 
00007BE2  STS 0x200C,R27		Store direct to data space 
00007BE4  RET 		Subroutine return 

Map:

.noinit         0x00802008        0x6
                0x00802008                PROVIDE (__noinit_start, .)
 *(.noinit*)
 .noinit        0x00802008        0x6 rtc.o
                0x00802008                RTC_valid
                0x00802009                rtc_time_AT
                0x0080200e                PROVIDE (__noinit_end, .)
                0x0080200e                _end = .

Note that I forced .noinit to address 0x2008 because I also have a bootloader that needs to run without trashing that section, and if you just leave the compiler to assign it then it ends up at some random position that can't be replicated.

Is there any way to fix this? The only thing I can think of is to relocate .noinit to somewhere else, perhaps the top of SRAM, but that could cause other problems. Actually there is another way; write my own rand() and srand() functions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why not simply shuffle the start of .data/.bss up a bit? I think a simple -Tdata=0xNNNN will shuffle the whole of .data and .bss.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks clawson, moving .data fixed it. I had in fact already moved .bss to 0x2010, but apparently that isn't enough. The linker was still storing stuff from 0x2000 onwards.

My understanding was that moving .bss should have been enough, but I guess not.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you are talking about 0x2000 I guess this is Xmega? In RAM GCC always stores .data at the start of RAM and then follows this with .bss so moving .bss alone will not stop whatever is being stored at the start of RAM. However my guess and your experiment seem to prove that the converse is not true. If you move .data it moves .bss as well. The diagram in the user manual helps to clarify things:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arrrgh... forum keeps eating my replies when I don't noticed that it logged me out.

Anyway, I did look at that graph but for some reason only moved .bss originally. .data must have been empty because things only broke after I added some static in-RAM stuff, including rand()/srand().

Out of habit I tend to use init() functions to set initial values of non-local variables, so unwittingly shielded myself from the problem :-)