Integrate CMSIS library into Firmware

Hi
I am trying to integrate the CMSIS DSP liibrary into my application for photon. I am using the pre-built library shipped with the CMSIS archive : libarm_cortexM3l_math.a.
I have added a linker flag to use this library in the photon user-part makefile (modules/photon/user-part/makefile, in the firmware)in the archive.
+LDFLAGS += -L/path/to/my/lib/libarm_cortexM3l_math.a
However when I make a call to a routine the build breaks with an undefined reference error:
undefined reference to `arm_rfft_init_q31’

I have tried including a makefile in my APPDIR (build.mk):

INCLUDE_DIRS += $(SOURCE_PATH)/$(USRSRC)
CPPSRC += $(call target_files,$(USRSRC_SLASH),*.cpp)
CSRC += $(call target_files,$(USRSRC_SLASH),*.c)
APPSOURCES=$(call target_files,$(USRSRC_SLASH),*.cpp)
APPSOURCES+=$(call target_files,$(USRSRC_SLASH),*.c)

INCLUDE_DIRS += $(SOURCE_PATH)/inc
CMSIS_ROOT    := /u/susom/cmsis-integ/CMSIS/
CMSIS_M3_LIB  := $(CMSIS_ROOT)/Lib/libarm_cortexM3l_math.a

LIBS      += arm_cortexM3l_math
LIB_DEPS  += $(CMSIS_M3_LIB)
LIB_DIRS  += $(dir $(LIB_DEPS))
LDFLAGS   += -L$(CMSIS_M3_LIB)

$(info from test app makefile  LDFLAGS:$(LDFLAGS) LIBS:$(LIBS) LIB_DEPS:$(LIB_DEPS)  LIB_DIRS:$(LIB_DIRS))

And this is my application code:
    #define ARM_MATH_CM3

#include "arm_math.h"
#include "Particle.h"

arm_rfft_instance_q31 rfftStruct;
const uint32_t bufferlen = 256;

void setup(){
    Serial.begin(15200);
    arm_rfft_init_q31(&rfftStruct, bufferlen, 0, 1);
}

void loop(){
}

However nothing seems to work. Can any one suggest where I am going wrong or how to get this to build.

(I need to use the real fft functions and I tried including the individual source files from CMSIS into my application and build, however I have hit a dead end there as the complex fft routine depends upon a bit reversal code that is written in assembly which I am unable to inline due to it being in Intel Syntax fft-cmsis-photon )
I would really appreciate any help as I am badly stuck with this for quite some time now.
Thanks
Subhojit

1 Like

I don’t know much about this library but normally in C when you are using an assembly language library, you have to declare a function prototype for the things you want to call with the extern tag so the compiler knows it is a forward reference to something that will be filled in at link time. The arm_math.h file has a prototype for that function but it is not extern.

I read online here that passing -D ARM_MATH_CM4 to compiler (in CCFLAGS) is required to build with this library.

1 Like

I was unable to add a library from a build.mk in APPDIR. I think it has to do with the order things are called in the main modules make process; the problem is you need the updated LDFLAGS when the .elf file is built, and a LDFLAGS change made in the user make don’t seem to affect that.

However, when I just hacked the .elf file generation to include the CMSIS library .a file, it failed to link because it was too large to fit in flash. So that will be a problem as well.

I think there might be a reason why one of the posters in one of the other threads had to use a monolithic build.

1 Like

Hi @rickkas7
" I think it has to do with the order things are called in the main modules make process" - I guessed so . But it wud be very helpful if you could tell as to how you did this - “However, when I just hacked the .elf file generation to include the CMSIS library .a file”… And I guess a monolithic build should fix the Overflow problem.

Thanks well in advance.
Subhojit

In the firmware directory, in the build directory, you need to edit modules.mk.


$(TARGET_BASE).elf : build_dependencies $(ALLOBJ) $(LIB_DEPS) $(LINKER_DEPS)
        $(call echo,'Building target: $@')
        $(call echo,'Invoking: ARM GCC C++ Linker')
        $(VERBOSE)$(MKDIR) $(dir $@)
        $(VERBOSE)$(CPP) $(CFLAGS) $(ALLOBJ) --output $@ $(LDFLAGS) /path/to/libarm_cortexM3l_math.a
        $(call echo,)

This is a really hacky and not great way to set it, because it will be linked into every app, but it was the easiest way to get it to work.

1 Like

Thank you very much @rickkas7. Seems to work (my build went through). “This is a really hacky and not great way to set it” - I absolutely agree but I am working towards a Proof of concept so am focusing on putting things together at the moment.
Thanks once again.

1 Like

I am still facing a problem while using the actual fft routine.

arm_rfft_q31( &rfftStruct, buffer, buffer); 

Calling the actual fft function leads to the following undefined reference:

/u/susom/cmsis-integ/CMSIS/Lib/libarm_cortexM3l_math.a(arm_cfft_q31.o): In function `arm_cfft_q31':
/u/susom/cmsis-integ/CMSIS/DSP_Lib/TransformFunctions/arm_cfft_q31.c:139: undefined reference to `arm_bitreversal_32'

arm_bitreversal_32 happens to be defined in assembly code in the CMSIS library - arm_bitreversal2.S
Any idea on how to overcome this ?

Thanks
Subhojit

I was trying to compile my own library from the CMSIS pack and my makefile was not picking up the assembly code for the bit reversal. After using the library that ships with the CMSIS pack my build goes through fine. (I am able to use the real / complex fft routines) of CMSIS.
Thanks @rickkas7 , @bko for your inputs.
Looking forward to some experience of playing around with recorded audio samples ! :slight_smile: