static declaration and the clobbering

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

Hello all,

I'm currently going through some old code for a system here and a small change to the USART driver, I noticed that the array being used as a FIFO buffer for the USART started clobbering other variables. These arrays are declared outside all methods as

static char uartRxFIFOSpace[UART_RX_FIFO_LENGTH]; 
static char uartTxFIFOSpace[UART_TX_FIFO_LENGTH]; 

where UART_RX_FIFO_LENGTH and UART_TX_FIFO_LENGTH is #defined a few lines before as, in this case, 0x80.
In an attempt to check which variables this array was likely to clobber, I checked the .map file generated but there wasn't a listing for these variables at all. Removing the static keyword not only made the variable appear in the .map file but also fixed the problem.

I thought I knew what the static keyword did but I didn't think it would change anything in this situation, especially not whether the symbol would appear in the .map file! Any more info on what exactly the static keyword does and why it would change things in this situation would be great, cheers!

Oh yeah, the thing I changed in order to get the code to stop working in the first place was to change the #define of UART_RX_FIFO_LENGTH from 0x3f to 0x80.

Regards,
S.

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

> I thought I knew what the static keyword did but I didn't think it
> would change anything in this situation, especially not whether the
> symbol would appear in the .map file!

The compiler generates file-local assembler labels for static objects
with file (or function) scope that won't be seen by the linker. That
way, no conflict will be seen by the linker if two (or more) source
modules use the same local name.

There should be debugging symbols available still, that's why
debuggers can tell you the addresses of such variables.

By omitting the "static" keyword, you'll simply cause a completely
different memory layout for these objects, so other parts of memory
will be clobbered (which you probably don't notice then immediately).

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

squidgit,

Just a thought but if you have two 0x80 arrays, that's 256 bytes - does the AVR you are putting this on have that much RAM? Or is it that the increase from 0x3F to 0x80 (times 2) has just "pushed it over the edge" along with all the other RAM usage?

(as the stack (with automatic variables) grows down and the fixed BSS is defined from the bottom up - it's possible one may be "bumping into" the other and these arrays are over-laying your stack.

Cliff

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

Could the 0x3f be used to "and" the bufferpointers , and create a wrap ??
If so then 0x80 might have to be 0x7f.

And make sure to read what clawson says also ??

/Bingo

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

It's going in to a mega128 with very little other stuff in RAM, using the standard makefile from the latest version of avr-gcc it reports the RAM to be 60% full. I don't have any recursive functions (at least none that are supposed to be recursive) so I'm hoping the stack doesn't grow too big.

What dl8dtl says makes sense, is there any way of checking where the variables have been placed by reading them from the debug file without using something like the JTAG interface to actually run the file? Unfortunately for this project I need all the ADC inputs and therefore can't (easily) use the JTAG.

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

You can run GDB just on the file, it ought to be able to
tell you the memory addresses of the variables.

I'm afraid there's no way around JTAG though. Maybe
consider using an ATmega1280 for development in the
long run?

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.