2
votes

I am having trouble calling a c function from arm assembly. Vice versa works fine. Arch is cortex-m3 and the board is due. Compiler is gcc.

Here's the assembly code:

.syntax unified
.section .text
.thumb_func
.cpu cortex-m3
.extern my_c_add
.global call_my_c_add

call_my_c_add:                    @ r0 - x, r1 - y
    bl my_c_add
    bx  lr                 @ return

And here's the c code:

#include <Arduino.h>
#include <SPI.h>
#include <Ethernet.h>

extern "C" unsigned int call_my_c_add (unsigned int, unsigned int);

unsigned int my_c_add(unsigned int, unsigned int);

unsigned int x=20;
unsigned int y = 15;

void setup()
{
    Serial.begin(115200);
    Serial.println("exiting setup");
}
void loop()
{
        unsigned int z = 0;

        z = call_my_c_add (x, y);
        Serial.print("c calling asm calling c, addition is - ");
        Serial.println(z);
}
unsigned int my_c_add(unsigned int x, unsigned int y)
{
    return (x+y);
}

The error I get is -

small_sample.S.o: In function call_my_c_add': small_sample.S:12: undefined reference tomy_c_add' collect2: ld returned 1 exit status

Here's the command I use for linking -

arm-none-eabi-g++ -O3 -Wl,--gc-sections -mcpu=cortex-m3 -T flash.ld -Wl,-Map,mapfile -o elffile -L somefile -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group some.c.o some2.cpp.o assembly.S.o somelib.a -Wl,--end-group

1
extern shouldn't be needed with as (sourceware.org/binutils/docs/as/Extern.html) how do you invoke toolchain?auselen
arm-none-eabi-g++ -O3 -Wl,--gc-sections -mcpu=cortex-m3 mthumbdoors666
that doesn't look like how you link.auselen
i didnt post the whole thing as its quite large, only the relevant things. it works as i have compiled other c and assembly code with this makefile successfully. I will update the main post with the command.doors666

1 Answers

0
votes

g++ compiler does some name mangling. You probably need to add extern "C" also on the my_c_add, to disable it for that function.

Try to run arm-none-eabi-nm on the two object files, and check that the name of the symbol defined in the object compiled from C/C++ is the same as the symbol in the object compiled from assembly.