Topic : Calling external functions symbolically from a .hex or .elf file

Forum : Ride IDE

Original Post
Post Information Post
July 5, 2011 - 6:02pm
Guest

We are working on a project within the Ride 7 environment and for the stm32f103 processor. Our customer is using IAR's development environment (http://www.iar.com/website1/1.0.1.0/658/1/?item=prod_prod-s1/225) along with a RTOS (from freeRTOS.com). Our goal is to provide the customer with some type of external functions that they can call symbolically within their own code. This way they can use our functions without seeing the actual code used in the functions. When our project is compiled in Ride7, a .elf and a .hex file is generated. I can view the symbol table in both the .hex and .elf files (using objdump [url]http://en.wikipedia.org/wiki/Objdump)[/url] and I've looked up each function I want to share it's unique symbol. Ultimately, the customer wants to prioritize and call our functions as tasks with his RTOS. My question is this, can we access and call our provided external functions from the .hex or .elf file (and if so, how this is done)?

Thanks in advance,
-Aaron

Replies
Post Information Post
+1
0
-1
July 5, 2011 - 6:32pm
Raisonance Support Team

Hi Aaron,

You can use some clunky cast and some preprocessor magic to explicitly call an absolute address as follows:

#define myfunction    (*(void (*)(int i))0x08001234)

... later:
myfunction(3);   // This will call the function at absolute address 0x08001234

You can change the pseudo-prototype of "myfunction". In this case I created a function taking one int argument (i) and returning void, but you can adapt it at wish.

Note that the absolute address of the functions must be known by advance however. It is better to place the functions at an absolute address (using linker magic) so that you can change your code on both sides in the future.

Another cleaner (is it?) way to do this is to have an array with function pointers. You pass the array address to the other side, and they can dereference the function pointers in order to call them.

I hope this helps,

+1
0
-1
July 5, 2011 - 10:26pm
Guest

First of all thanks for the quick response Bruno! I truly appreciate your help. I just tried this approach however with no avail. Let me talk you through my attempt:
==============================================================================
1. When compiling my project successfully (in Ride7), I'm given a .elf file. I can run "objdump -t myelf.elf" in cygwin to print out the symbol table from the .elf file generated. I can then find the function I want to reference, and it's entry in the symbol table:

08006129 g F.text 00000034 adc_enable

I believe that the fields are printed out as:

<"g" for global>

2. Now in my function, following your advice, I #define my function from it's absolute address. Take note that this function, adc_enable, returns void and has no arguments.

#define adc_enable_functptr (*(void(*)(void)) 0x08006129) //get ptr to adc_enable

3. Now in my code I call :
-------------------------------
adc_enable_functptr();
-------------------------------

but the adc is never being enabled telling me that my function isn't getting called.

==============================================================================

So, now I'm stuck because it seems as though this is the correct absolute address for my function. Is there something I'm missing?

Keep in mind we are trying to provide the customer with the use of our provided functions without giving them the ability to "see" our code. Therefore, we are only giving them a .elf file which they must take and (symbolically) reference our function from.

Thanks!
-Aaron

+1
0
-1
July 6, 2011 - 10:09am
Raisonance Support Team

Mmmh, difficult to say without the code.

The first thing to do is to flash the device, then switch to debug mode and check that the calling code is here, and that the called code is properly flashed at 0x08006129.
Once this is ok, run up to the adc_enable_functptr() call, swith to the disassembly debug and perform assembly-level debug steps. This should help you understand what's going wrong.

Let us know if you fixed this problem satisfactorily,

+1
0
-1
July 11, 2011 - 5:13pm
Guest

Your original solution worked. There was a typo within my address. Once I cast my function pointer to the appropriate addresss, my function was called.

Thanks again for the help!

+1
0
-1
July 12, 2011 - 12:00pm
Raisonance Support Team

Glad you got it!