This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LJMP in C?

What's the best way to do this in C?

#pragma ASM
LJMP APP_START; //Run app
#pragma ENDASM

..or, is that it?

APP_START does not exist. This is the launch point of an application loader. The actual app will be done as an entirely different project to be loaded higher in memory at a later time.

Thanks.

  • Assuming you know the fixed address of APP_START, just do this:

    ((void (*) (void))0xXXXX)();

    where 0xXXXX is the hex adress of the function you'd like to call. Note that this isn't EXACTLY what you're trying to do, as I believe the compiler has the liberty to decide whether to generate a JMP or CALL. Assuming that doesn't matter to you, it should work.

  • I would (and did) just write an assembler routine to start the application and call it from C.

    The language per se doesn't really have the notion of a call that doesn't return. "goto" is closer, but leaves you with the problem of declaring the label. Setjmp() / longjmp() could be worked into the scheme, but the environment context buffers are irrelevant here. A function call will most likely push a return address on the stack. If your app code is a completely independent program, it will probably reset the SP and so you won't really care.

    And so, since the problem itself is really much simpler than trying to deal with matching all the semantics of various high-level possibilities, I just go the low level route. There's nothing wrong with a little assembly here and there to supplement the C, particularly when it's used for this sort of low-level access and control.

    Jay's suggestion will work just fine, too, as long as the app startup code cleans up the stack.

  • I think I'll stick with the assembly. It doesn't bother me at all. Just wanted to know if there was a more embedded-C way of doing this.

    Yes, the app takes over, so nothing in the boot code is of any relevance once the app takes over.

    Thanks,

    -Martin

  • Martin,

    There's not really some better "embedded C" way to do something like this. In general, most everyone will tell you that if you have some code that requires you to generate a specific assembly instruction or do something specific with a register, then that routine belongs in assembly since C was made to abstract all that away. There are always work-arounds, but like my example, they're generally not pretty.

  • The language per se doesn't really have the notion of a call that doesn't return.

    ... with the possible exception of the standard library function exit() which does just that ;-)

    A return from the end of main would achieve the same thing, i.e. the "C way" of doing this would be to terminate the loader's main() like this:

    typedef void (*t_application)(void);
    
    t_application application = 0;
    
    void main() {
      /* do stuff here */
      /* ... */
    
      if (!application)
         while(1)
            ; /* endless loop */
      application();
    }

    The compiler may implement the call to application() either as a LCALL followed by a RET, or (if the relevant optimization flag is on) it'll condense those two into an LJMP. To the application code that cannot make a big difference: at most, its stack is a couple of bytes smaller than it could be.

  • I just bumped into this thread and noted there is a mistake in the C version of the call sugested by Jay.

    He wrote:
    ((void (*) (void))0xXXXX)();

    It should be:
    (*(void (*) (void))0xXXXX)();

    Where 0xXXXX is the fixed address where you want your code to go to.

    Hope that helps others.
    -Howard

  • noted there is a mistake in the C version of the call sugested by Jay

    There is no mistake. Jay's and your version should do exactly the same thing.
    In C, you don't have to, although are allowed to, dereference a pointer to a function before calling it using the parentheses operator.

    - mike