How to place a variable at the end of the data segment

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

In a program I'm working on we have exhausted close to all available RAM. I would like to check if the stack is eating into the data segment.

Of course I could fill the SRAM with a pattern with some .init code, but I would prefer to check the last variable in the data segment rather than an area of unused SRAM (which could be only 1 or 2 bytes, anyway).

I have a variable which is unused in a normal program flow. Now I'm trying to move this variable to the end of the data section.

Since I'm not extremely confident with linker scripts, I have a (stupid) question.

In the standard linker file (avr5.x) the section .noinit follows .bss. If my variable is the only one which is declared as .noinit, then this should be enough to ensure that my variable is linked as the last variable in SRAM. It works for me, but I'm not sure if it is a sound way of doing it.

Are there better ways of doing it, possibly without defining my own linker script?

Cheers
Thomas

I'm using avr-gcc (GCC) 4.2.2 (WinAVR 20071221)

pycrc -- a free CRC calculator and C source code generator

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

But it's the end of .bss, not the end of .data that will get hit first anyway?

A picture is worth 1,000 words - so here's 1,000 words:

http://www.nongnu.org/avr-libc/u...

Your best bet is to add a RAM based memory section after .bss in the .x file

Another technique is to set up a fast ticker interrupt and just have it sample SP each time it fires. If SP is lower than last time update the "low water mark" value. Either just run this for a while and inspect the low water mark or even add code to monitor how close the value is getting to __bss_end and abort into an infinte (breakpointable) while(1) loop when disaster seems imminent. Then look for the breakpoint being hit in your debugger. Alternatively it could flash a light or output a warning to UART or LCD or similar.

Cliff

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

clawson wrote:
But it's the end of .bss, not the end of .data that will get hit first anyway?

Sorry, I was a bit sloppy with the term "data". I meant the data region (the "{...} > data" one), which contains the .data, .bss and .noinit sections.

clawson wrote:
Your best bet is to add a RAM based memory section after .bss in the .x file

Hmm probably it is the safest bet.

I like the idea of periodically checking the SP in an ISR. Since I have one ISR which uses more RAM than all others it might be enough to check it at the beginning of that ISR.

Cheers
Thomas

pycrc -- a free CRC calculator and C source code generator

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

.noinit will always be after .bss, so

#include 
uint16_t data_boundary __attribute__((section(".noinit")));
int main(){
    //init var
    data_boundary=0xAAAA;
}

you could even give yourself a buffer of whatever you want, like data_boundary[16], and fill it up to see how much is touched or just use the highest address with the all the lower bytes as a safety zone buffer. Then you can catch it without the stack descending into bss. Maybe.