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.

construct thumb function call



I use TI ARM C/C++ Compiler v5.0.4 to compile for TIVA TM4C1231PGE controller.

I need to "manually" construct a function call.

For example I have to call a funcion, and I have its entry point address: 0x0000e000.

typedef void (*my_pfunc)(void);

my_pfunc pfunc;
pfunc = (my_pfunc)0x0000e000;
pfunc();


running this code, an exeption is throwed.

This is because in the ESPR register the thumb bit must be 1, and this happens when the address in a branch has LSB 1.

How can I build the correct function call (avoiding the +1 workaround)?

best regards

max

  • Where is the function defined? Do you not have access to the symbol at link time? More details on why you are using a constant address would be helpful.

  • The actual use case is that a small piece of binary code is downloaded in SRAM from somewhere else (for example using UART).

    It must be executed in SRAM. I alloc memory where to place this code, then I branch to execute it.

    There is some built in function to call a thumb function or to get the right function address, from a generic address?

    best regards

    max

  • "I alloc memory where to place this code, then I branch to execute it."

    Are you allocating the memory at run time or link time? This distinction is important because if the address is not known until run time, the responsibility of providing the correct address for the function is the applications. 

    Do you have access to the object file that contains the function you are trying to call?

  • I alloc memory at runtime. I do not know in advance the address, but I can calculate it at run time.

    I have access to object file that contains the function.

    now I get the address in this way:

    typedef void (*my_pfunc)(void);
    
    my_pfunc pfunc;
    uint32_t pf;
    
    pf = (uint32_t)function_pointer_in_ram; // here I get the right function address (2 or 4 byte aligned)
    pf |= 1; // this is for thumb function call
    pfunc = (my_pfunc)pf;
    pfunc();

    I don not like much line 7, It is too triky for me.

    best regards

     

  • Function pointers are normally used to choose, at runtime, one of many functions.  These functions are all ordinary functions present in the system when execution begins.  This is not the case here.  The function called through a pointer is not present when execution begins.  Moreover ...

    mastupristi said:
    I alloc memory at runtime.

    These circumstances, combined together, mean your code has to attend to all the details of forming the address of the function.  This includes whether it is a Thumb function or an ARM function.  There is no compiler feature which helps.

    mastupristi said:
    I don not like much line 7, It is too triky for me.

    I understand.  But this entire scenario is unusual.  I'm not surprised some of the related source is a bit unusual.

    Thanks and regards,

    -George