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.

MSP430 - Unintentional Function Call

Other Parts Discussed in Thread: MSP430FG4618

Hi, I am working with some legacy code at the moment on a MSP430FG4618 and I am changing several features. Up until now I haven't had any problems. Recently however I am encountering a very strange issue. When the code is running I am seeing an unintentional function call. The function in question loads default values into all of the register of the register map with hard coded values, and as you can guess this is a major problem. This function can be called intentionally if the user goes into the default page and selects this option. It can also be called intentionally if the uC boots up and there are no values already in the register map i.e. boot up after first time it has been programmed. My issue is that it appears  that this function is being called unintentionally. I left a unit in a locked location (to rule out tampering by another user) and when I returned the default values were loaded somehow. Given that I left this unit on and the registers had data already in them, and it wasn't on the default page this function call can't have been caused by either of the intentional methods. Somehow the default function has been called unexpectedly.

My colleagues suggest that I place advanced trigger points at the locations in memory where this function resides along with the locations in memory from where it can be called and wait for a break to happen, which I have done. The problem is that it can take a while for this to happen so I have to sit here at my computer waiting for a break at which point I could analyse the stack to see where this was called from.

In the meantime does anyone have any suggestions as what is likely to be the cause of this? Are there any particular things I should be looking at in my code i.e. stack problems or memory overflows? Also, are there any better ways of debugging this issue rather than waiting for a break from the advanced triggers?

Any help would be appreciated and if you require anymore information please ask away. I am new to this so I may not have included the necessary information needed to answer this question.

  • Hi David,

    It is not easy to give you useful advice according to your description. You need to provide more information. For example, the work flow of your program. Do you use watchdog? How about the platform, TI-RTOS or just use main/ISR?
  • Hi Rcfocus

    First of all the watchdog is disabled. As for the platform I'm not sure how ro answer that question. I really am a beginner to all of this. I know the basics of C and how to write a good function but the other stuff isn't there yet and wont be for some time. I am using IAR to write and amend the code that is all I can really tell you. Sorry for the lack of information. I think I have an idea what is causing this now and I am going to be testing it over the coming days. Hopefully I can solve this on my own.
  • Just in case people are interested we managed to track down the problem. I copied this project over from another locations and made a local copy. At some point, all of the project settings in my new version have defaulted. This included the stack size. Teh stack size of the original project was 1000 bytes. This defaulted to 80 bytes in my project.

    This had the unintended consequence of causing random function calls.

    If you have random unexplained issues with your code I urge you to double check the stack. Beginners mistake!

  • David French35 said:
    ... This included the stack size. Teh stack size of the original project was 1000 bytes. This defaulted to 80 bytes in my project. ...

    The "stack size" setting has nothing to do with the real stack size at run-time. At best, the linker can give you a warning when there is less than 1000 bytes for stack before run-time.

  • >The "stack size" setting has nothing to do with the real stack size at run-time.

    Define "real stack size" then :) Depending on compiler and library stack size setting can actually change stack overrun behavior. While giving more RAM for stack (segment), you are leaving less memory for heap, thus in result you have better chances to get failed malloc() call than stack overrun.

  • Ilmars,
    I agree; this is compiler dependent. But I think both CCS and IAR will not change the RAM usage according to the setting of stack-size. This topic was also discussed in the thread:
    e2e.ti.com/.../479416

    David,
    I am glad that you have solved your problem. But I do not think the stack-size setting was the problem. If you try your project once more with only the stack-size changed back to 80, it will still work. With this change alone, both the memory allocation and the object code will stay the same.

    --OCY
  • old_cow_yellow said:
    I agree; this is compiler dependent. But I think both CCS and IAR will not change the RAM usage according to the setting of stack-size.

    Just checked that IAR (v6.30) does change RAM usage depending on stack and data heap size settins. 1) it gives error during compile time when stack+heap size exceeds available RAM 2) during runtime it's malloc() does return (void *)0 in case available heap is less than requested.

    So if you allocate 100 bytes stack on 512 byte msp430 but it's actual usage is 200 bytes, you can trash stack with malloc(400) while using allocated memory. However when you allocate 200 bytes stack, malloc(400) will return (void *)0. If you obey this error then your stack is safe. P.S. I never use malloc() on such a small chips anyway..

  • Thanks for correcting me. I did not pay attention to how the heap (free store) is handled.
  • old_cow_yellow, you are right, I can run this project if I have the stack set to 80 bytes or 1000 bytes. I haven't run my project long enough to know if changing the stack setting to 1000 bytes has fixed it. I spoke to a senior engineer here and he said that he also had similarly strange consequences on a project he was recently working on when he didn't increase the stack size. He said my unintended function call is likely to be a result of exceeding the stack size.

    Can I ask, if the stack size setting doesn't change the stack size then what is it for? It is very misleading.

    I must also explain at this point how I tested this. I came across a test desscribed as the watermark test. In it, the user explains how you can set all the memory locations from the stack downwards with the same value, "ADDE" in my case as it reads as DEAD when looking in the memory window during debug. It then tells you to leave the code running for a while then create a breakpoint to view the memory contents. From 0x3100 downwards you can then track where your "DEAD" value stops. For me, it was about 0x2FF0, which I worked out to be about 272 bytes. I also could see the debug log displaying a message every time it exceeded 0x3100 to 0x30B0. Something along the lines of " Stack outside of stack range 0x30B0 to 0x3100". Now as I said, I am new to IAR and I am kind of teaching myself so forgive me if I have misunderstood. But I have come across several articles about strange behaviour, such as unintended function calls, can occur as a result of exceeding the stack. Are there any definitive tests I can run in IAR to see if I have indeed exceeded the stack? Obviously I'll put my stack size back to 80 bytes first

  • A bit of extra info. The excat message I get in the debug log is "stack pointer for stack 'STACK' (currently 0xXXXX) is outside the stack range (0xXXXX to 0xXXXX)". I am currently looking for answers in forums for this issue but they all seem to give different answers
  • David,

    My thoughts below may not be factual; I am just an old hobbyist. Perhaps   can help you to clarify it. Also,  (the author of the MSP430 IAR compiler) is an community member. I hope he might answer your questions even though he is not representing IAR officially here.

    My thoughts are: you probably are not using the heap (free store) and you are using the standard (default) link command file that came with the IDE package without an OS or RTOS.

    Given that, I think IAR will allocate some of the RAM at the low-address end for static/global variables. The map file generate by the linker will clearly indicate where and how much RAM are used that way. The rest of the 4KB of RAM on the chip can and will be used for the (assumed non-existing) heap and the stack. The stack will start from the high-address end and grow toward the low-address end of RAM. At run-time, if and when the top of the stack grows and overlaps with (non-existing) heap and the static/global variables, you will have a problem. If the top of stack grows beyond the low-address end of the RAM, you will have an even worse problem. The real limit of your stack size is = 4KB-(size of your static/global variables)-(size of our heap, which is 0). I think when you tell IAR stack-size = 80, you are only asking IAR if 80 is within that real limit or not. You are not asking it to shrink the real limit when the real limit is more than 80 bytes. You are not asking it to expand the real limit to 80 when the real limit is less than 80.bytes.

  • I'm going to book myslef on an IAR course as I don't have sufficent knowledge to explain this probelm well enough. I am just starting out in IAR and some of the things which have been discussed between yourself and Ilmars are above me quite frankly. This problem may not be related to the stack at all. But it seems the only thing which can explain the unintended function call at the moment. Thanks for the information in the mean time as it as highlighted my short comings. Perhaps it'll turn out to be something else completely :)
  • This message tells that actual stack usage takes more ram than allocated. Thing is that setting stack size does limit remaining memory like heap size, not actual stack used by cpu.

  • First, it would be a good idea to figure out from where the call originated. I guess you can do this with advanced breakpoints, but you can also use a low-tech solution like passing as extra parameter and set it to different values depending on if it came from the startup code or the user interface. You would have to save the parameter in some location in memory in order to tell where the call came from.

    A third location it can come from is if the processor, somehow, got into a "free run" and fell into your code from above. One way to detect this is to pass values unlikely to occur in the wild as the parameter, rather than simply 0 and 1.

    One theory is that the system, somehow, has done a "full reset" (including erasing the memory) and restarted. In this has happened, your routine is called as part of the normal startup, if I understand correctly. Unfortunately, I have no idea what could cause this.

        -- Anders Lindgren, IAR Systems, Author of the IAR compiler for MSP430

  • Hi Anders,

    I actually had training with a gentleman called Andreas from IAR yesterday. He went through the basics of IAR but he also went through the stack issue. He said that the problem I am seeing could very well be caused by unsufficient space in the stack. He also went through some techniques of how to view the satck size and it's usage. I was also talking with a senior engineer where I work and he had a similar issue last month, when a function was being called somehow. It turns out he too had not declared a big enough stack size. He has since fixed this problem by increasing the stack via the options in IAR.

    One of the things Andreas mentioned was that the stack overflow can often cause a failure, or reset, of the code. But he said he often deals with situations where the stack overflow doesn't cause a crash, but instead limps along with exactly the kind of issue I was witnessing. The only way I can test if this stack resizing has fixed my problem is to leave my product running for a few weeks to see if it reoccurs. If it does, then it is obviously not the stack causing this, but based on the info i have recievd from colleagues and IAR it does seem that this is the likely cause.

    I have done the tests you suggested, advanced breakpoints in all locations where the function is being called etc.. but because it happens every couple of weeks (on average) I have not see a break yet. I could write something to place an extra variable to some location as you suggested. Cheers

     

    Dave

**Attention** This is a public forum