This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F169 - Variables change value randomly



Hi

I have several .c files linked in a project, and there some variables that sometimes change value at random to arbitrary huge values. These variables are used by all the .c files.

This project uses the flash , the I/O,  the ADC, and timers A and B.  I've kind of been beating my head against a wall trying to figure out why the values change at random to numbers that have nothing to do with my code.  Could I be experiencing a stack overflow somewhere? 

I'm kind of at a loss so any insight would help. Thanks.

  • Hello Maz,

    Just as a thought, since you are sharing the variables between all the files, make sure you are declaring them the same in all the files.

    I have seen similar behavior when you would declare a variable an unsigned int foo, but would reference it as an extern int foo.

    As I said, just a quick suggestion.

    -Jason

     

  • Thanks for the suggestion Jason.  I reference the unsigned int foo as extern unsigned int foo, but will be weary of that in the future just in case,  thanks.

  • It is possible that you run out of memory. MSPs have only a very limited amount of ram. This ram does not only hold your variables, but also the stack, and if you're not careful, it will also hold your tables, constants and more.

    The stack begins at the top of the ram, your data and variabels lay on the bottom. If you use 'malloc' r such, the data begins to grow from botton up. And ewach time you call a subfunction, the stack will grow from top down (and shrink again once a subfunction is left). It is easily possible (especially if you use printf with many parameters) that the stack grows so large that it won't fit into the unused ram above your variables. Then it will continue to grow and overwrite your variables with function parameters and return addresses for function calls.

    Not that the stack will grow and grow unlimited. It will shrink and release the used memory once you return from a subfunction, but overwritten memory is overwritten memory.

    Each time you call a subfunction, the processor will store the return address onto stack (2 bytes, on later MSPs 4 bytes). Also, the compiler lets the processor store all processor registers onto stack which are required for calculations inside the called function. When you return form this function, all this is removed from stack again and the stack shrinks. But it can easily by that you call a subfunction from this function, then the stack will grow more before shrinking. And when you call another subfunction and from withing this another one...

    Also, you can make recursions, a function that calls itself recursively. Mathematical functions often do so. But each recursion lets the stack grow.

    Also, function an arbitrary number of parameters (such as printf/sprintf) require their parameters passed on the stack. Each and every parameter lets the stack grow, and the printf function itself adds even more tho this.

    This kind of 'stack overflow' is not easily detected but is the reason for the majority of cases where untouched variables sudenly change their value. THe rest is usually caused by accessing arrays with an index that is larger than their size. (array index out of bounds).

  • Thanks Jen. I'm pretty sure you hit the problem with RAM being overwritten since I'm declaring many many variables in C and have quite a few subfunction calls. 

    Is the remedy for this to just declare less variables and not use so many function calls?  I know it's such a small amount of RAM, so I'm pretty sure you hit the problem dead on.

    I was going to try combining all the .c files into one massive file with less calls.  It's an approach that's very much not elegant, but I'm kind of low on options.  Thanks again.

  • Maybe it helps to declare some variables as CONST, if you don't need to change them (such as precalculated tables). This way they should stay in flash and do not use any ram at all. Also, use the smallest possible size for your global variables. Where possible, use char instead of int. And do not define many local variables. If you have two loops in a function, do not use different loop variables unless absolutely necessary. It maybe makes code less readable, but saves space on the stack for this function. Local variables (other than global ones) always use 2 bytes on stack (or more) even if char only.Because of alignment issues. Also, create your structs so that you get a good alignment. A struct with char-int.int-char will be 8 bytes as the ints need to be word-alinged (on even addresses), so padding bytes are inserted. If you use char-char-int-int, the same struct will only take 6 bytes of ram. Maybe the compiler will do this reordering for you, but if YOU do it, you at least know how your struct is reordered (important if you convert the date to a stream for sending later etc.)

    I also noticed on the MSPGCC compiler, that when code optimisation is on and I use lots of SPRINTF calls, the compiler will not remove the parameters it pushed on stack after each call, but only all together at the end of a code block. This saves some instructions each time, but will let the stack grow more than required. I too encountered stack overflows on the MSP1232 with only 256 bytes ram. The solution was to put each sprintf call (or any other function that passes parameters on stack) in its own do{sprintf...}while(0); block, so the compiler cleaned-up the stack after each call.

**Attention** This is a public forum