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.

MCU hangs up when function code size goes beyond a certain length

Other Parts Discussed in Thread: MSP430G2553

Hello

I am having a peculiar issue where the MCU hangs up when the function code size goes beyond a certain length. Now if the function is split into multiple functions, the problem goes away. Hence the overall code size remains the same.

Any guidance is greatly appreciated.

Regards
Ashwin

  • Hi there, 

    this summer i got a similar problem. I was programming a FIR filter and when i tried to debbug the code, the CCS returned me an error. Most of the times the error was that a strange adress was charged in the PC register, so the program jumped to a almost random adress where it was an unknown code. 

    The error was finally in my code.  In some point i called a subroutine and the first time i returned from that subroutine with the assembler instruction RET. 

    This instruction can only managed 16-bit adress, but the adress where i had to return needed more than 20 bit to be accessed. Then the program failed. 

    I finally fixed the problem with the help from an answer from here, E2E and using the instruction RETA (that managed adress up to 20 bit), instead RET.

    So try to shrink your code ;)

    Regards

  • Alvaro is right, a large funciton size may cause teh flinker to arrange the functions differently than with smaller funcitons. It is possible that the caller moves to upper flash and when using the wrong return isntruction, the CPU will return to a wrong position.

    However, thsi only applies if mixing assembly and C functions. On plain C projects, the compiler should handle this properly. In a plain assembly project the coder should use matching instructions. However, the linker will not complain if a function in upper flash calls a function in lower flash with a 16bit call.

  • Hi Jeans-Michael,

    Thanks to Alvaro, I understand now why my program hangs up when getting bigger (>8K).

    I agree with you 200% about C funtions, but unfortunately it seems that in some cases, the CCS compiler (downloaded from TI) does place a RET in place of a RETA for some funcions. It causes me the crash. I will try to update the version to see if there is some enhancement in this behaviour of the program.

    Regards.

    Bruno.

  • Bruno Bruno said:
    it seems that in some cases, the CCS compiler (downloaded from TI) does place a RET in place of a RETA for some funcions.

    This should only happen when the code model is set to small code model. In this case, teh compiler (rightfully) assumes that all code is below 64k and therefore no return will ever have to return to a 20 bit address.

    The linker will detect whether different objec tifles use different code models and will complain.

    The only situation where this might slip through undetected, is when you use inline assembly or use assembly source files in your project. Then it is you (or whoever wrote them) whio has picked the instruction - and is responsible for using the right one.

    It's the first time I hear about this and so chances are that it is not CCS causing the problem. Else many others would have complained here too.

  • Hi Jens-Michael,

    Thanks for your reply. It is clear for me. As per I am using a MSP430G2553 in a Launchpad environnement, I cannot exeed 16K.

    The behaviour changed. The program enters now in an loop. I am not using any assembly code, only C code.

    The loop stands on this line of code :

    cs = fs->fptr >> 9; (a division by 512) with cs ans f->fptr as  unsigned longs.

    When debugging in assembly mode, the code is the following :

    cc3a:   481C 0016           MOV.W   0x0016(R8),R12
    cc3e:   481D 0018           MOV.W   0x0018(R8),R13
    cc42:   12B0 D794           CALL    #__mspabi_srll_9
    cc46:   4C09                MOV.W   R12,R9
    cc48:   4D0A                MOV.W   R13,R10
    cc4a:   485F 0002           MOV.B   0x0002(R8),R15
    cc4e:   831F                DEC.W   R15

    with :

          __mspabi_srll_9:
    d794:   C312                CLRC    
    d796:   100D                RRC     R13
    d798:   100C                RRC     R12
          __mspabi_srll_8:
    d79a:   C312                CLRC    
    d79c:   100D                RRC     R13
    d79e:   100C                RRC     R12
          __mspabi_srll_7:
    d7a0:   C312                CLRC    
    d7a2:   100D                RRC     R13
    d7a4:   100C                RRC     R12
          __mspabi_srll_6:
    d7a6:   C312                CLRC    
    d7a8:   100D                RRC     R13
    d7aa:   100C                RRC     R12
          __mspabi_srll_5:
    d7ac:   C312                CLRC    
    d7ae:   100D                RRC     R13
    d7b0:   100C                RRC     R12
          __mspabi_srll_4:
    d7b2:   C312                CLRC    
    d7b4:   100D                RRC     R13
    d7b6:   100C                RRC     R12
          __mspabi_srll_3:
    d7b8:   C312                CLRC    
    d7ba:   100D                RRC     R13
    d7bc:   100C                RRC     R12
          __mspabi_srll_2:
    d7be:   C312                CLRC    
    d7c0:   100D                RRC     R13
    d7c2:   100C                RRC     R12
          __mspabi_srll_1:
    d7c4:   C312                CLRC    
    d7c6:   100D                RRC     R13
    d7c8:   100C                RRC     R12
    d7ca:   4130                RET    

    The first time the program runs the part of the C code, the PC register takes the value CC46 after the RET of the call to #__mspabi_srll_9 and the second time, the PC register takes the value CC42... Unfortunately no changes when I tried to expend the stack.

    I do not have enough experience with assembly to understand fully the code.

    If you have any idea of what could be the reason of this behaviour, please let me know.

    Regards

    Bruno

  • That c library routine is correct but inefficient.
    __mspabi_srll_9:
      clrc
      rrc   R13
      rrc   R12
    __mspabi_srll_8:
      swpb  R12
      swpb  R13
      xor.b R13,R12
      xor   R13,R12
      and.b #0xFF,R13
      ret
    would be shorter and faster

  • Your problem is not cause by this library routine. It is caused by something you did not disclose.

  • old_cow_yellow said:
    would be shorter and faster

    Faster for sure, but not shorter, as the remaining code from srll_7 down is required anyway, for shifting 7 to 3 bits (for one or two, inlining is faster and smaller). Well, it's only 2 instrucitons/4 bytes difference :)
    Apparently, this code was designed for optimizing size, not speed (else the shift code could be inlined, saving the function call)

**Attention** This is a public forum