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.

CCS6: How to generate a starting reset function without saving registers in stack

Hi,


I have a start function link to the reset vector table:

 void __interrupt start(void)
{
   __asm("\t   MOV.W\t    #__STACK_END,SP");
   main(0);
   exit(0);

}

but the compiler generate saving register before initialization of stack pointer:

     
    PUSH.W    r15                   ; []        => unexpected line
    PUSH.W    r14                   ; []       => unexpected line 
    PUSH.W    r13                   ; []       => unexpected line    
    PUSH.W    r12                   ; []       => unexpected line     
    PUSH.W    r11                   ; []       => unexpected line    

       MOV.W            #__STACK_END,SP         
                                                
    MOV.W     #0,r12                ; [] |74|   

    CALL      #main                 ; [] |74|   
                                                
    MOV.W     #0,r12                ; [] |75|   

    CALL      #exit                 ; [] |75|   
                                                
    POP       r11                   ; []           => unexpected line
    POP       r12                   ; []           => unexpected line
    POP       r13                   ; []           => unexpected line
    POP       r14                   ; []           => unexpected line
    POP       r15                   ; []           => unexpected line
    RETI      ; []    

 

Thank you for your help  

  • What you are looking for is not supported by the TI compiler. The GCC compiler calls this a "naked" function. You'll need to write it in assembly code.
  • Hi,

    It is better for you to write the RESET routine in assembly. But it should be OK for you to use a normal function without the __interrupt keyword. The most important thing is you must know how to initialise the stack memory and global variables in the start() function. And then, make the start() function's address be placed on the vector table.
  • Any plans that naked functions will be supported by the TI compiler?
  • A request has been filed for this feature.  See this forum thread.  I will let the development team know about this additional interest in naked functions. That said, I cannot extend any promises.

    Thanks and regards,

    -George

  • Wow, the request is 3.5 years old.
    The SDOWP shows the request for the TMS470 compiler. Could you please ask the C2000 compiler, too?

    Thanks,
    Stephan
  • I added a note to the SDOWP entry.  

    Thanks and regards,

    -George

  • I suspect that the reason this is backlogged is that the TI compiler does not support GCC-style inline assembly, and thus naked functions are of very limited use. A naked function has no prolog or epilog; the return statement is in the epilog, so you cannot return from such a function without adding assembly code of your own. This is fine if the body of the function tail-calls a function which does not return, but that's about it. Sure, you could use a naked function to implement the boot routine (_c_int00), but you could also just take the assembly code output of the compiler and delete the prolog and epilog by hand. You could also make a naked function and make a body consisting of only TI-style inline assembly, but then why not just put that assembly code in an assembly file? If you have a compelling use case for the naked function attribute, I'm sure this could be elevated in priority.
  • Regarding the original post: rename your function to _c_int00 and try again
  • Okay, here is our use case:

    We use very small, well tested and effective "functions" for our control loops. These "functions" may only do an add, a pi-filter or a lowpass-filter, nothing else.
    They are combined to form the control loop.
    Since they are very small, function call and return would take a relatively big amount of time (compared to the real work that the "function" performs).
    So actually we are writing these "functions" in assembly, without a call and return, but with a branch as entry and branch to next "function" as exit (this already works as entry for the next "function").
    This effectively saves 8 cycles for the return - in a routine that may only take 10..20 cycles.

    Being able to write these small "functions" in C rather than in assembly would make things much easier to write and maintain.
    For this, we would need naked functions - and computed gotos to branch to a computed next "function".

  • Well, I would say that's more compelling than the use cases we'd considered, so I'll make note it in the enhancement request.

    I'm concerned by your statement that you'd need computed gotos, because the TI compiler does not support the GCC C extension computed gotos, and implementing them would be significantly more effort. Besides, even GCC computed gotos only apply within a function. Perhaps you don't mean what I think of when I hear "computed goto" ?
  • StephanS said:
    Since they are very small, function call and return would take a relatively big amount of time (compared to the real work that the "function" performs).
    So actually we are writing these "functions" in assembly, without a call and return, but with a branch as entry and branch to next "function" as exit (this already works as entry for the next "function").

    If you declare the small C functions as inline does that allow the compiler to remove the overhead of the function call and return?

    [The FUNC_ALWAYS_INLINE Pragma may be required to override the compiler's inlining decision]

    Another possibility is to set the optimization level to "4 Whole Program Optimizations", as I have seen that cause the compiler to automatically inline small functions. e.g. the MSPware driverlib functions.

  • Chester,

    that's a good point we have not thought about yet. I will check if this is an option.

  • Regarding "computed gotos", I mean a goto to a variable address (instead of a label), provided via pointer.
    This is supported via GCC.
  • Hi,


    Thanks for your answers.


    I found a solution by removing interrupt keyword in my startup function and then the compiler remove registers saving instruction.