Linker does not find definitions in CMIS-DSP library

I have used three different methods to tell the pio system where to find library dependencies, for example by specifying the package framework CM

  1. specifying the framework -cmsis package in the env section of platformio.ini
[env]
test_framework = unity
platform = https://github.com/platformio/platform-atmelsam.git
platform_packages = framework-cmsis
board = due
framework = arduino 
  1. by adding a library dependency to the the current configuration (note that the library is slightly different, but it does not matter as the linker cannot find anything!)
[env:...]
...
 lib_deps = mbed-xorjoep/CMSIS_DSP_5@0.0.0+sha.4098b9d3d571
  1. a combination of any and all of these
  2. by copying just the source code for the required functions arm_mean_q15 to a folder under /lib, but the compiler does not even compile these files! However, when navigating through the code the defined functions are shown in the editor. So the system must know these dependencies!
  3. by copying the appropriate libsam…a library to the /lib folder.

Please help!!
This should be really straight forward, and I followed all instructions but I just cannot understand how pio “thinks”, and where and how it looks for header files. Do packages have a priority or libraries? Does the library has to be explicitely specified in the build flags?

Note that I have also specified the build_flags = -D ARM_MATH_CM3 to specify the M3 architecture, so at least that aspect should be sorted.

Many thanks

Weird. The precompiled CMSIS-DSP library is present in the framework folder, but not linked by default.

You can link against by adding a little extra_script.

[env:due]
platform = atmelsam
board = due
framework = arduino
extra_scripts = pre:link_cmsis_dsp.py

with link_cmsis_dsp.py in the same folder as the platformio.ini and content

import os
Import("env")

platform = env.PioPlatform()
FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-sam")

env.Append(
    CPPDEFINES=["ARM_MATH_CM3"],
    LIBPATH=[os.path.join(FRAMEWORK_DIR, "system", "CMSIS", "CMSIS", "Lib", "GCC")],
    LIBS=["arm_cortexM3l_math"]
)

then a src/main.cpp of

#include <Arduino.h>
#include <arm_math.h>

void setup() {
    Serial.begin(115200);
}

void loop() {
    // these q15 values are probably equivalent to only 1 = 1 / (2^15) or something, not sure
    q15_t values[] = {1, 2, 3, 4};
    q15_t mean = 0;
    arm_mean_q15(values, 4, &mean);
    float mean_f = 0.0f; 
    arm_q15_to_float(&mean, &mean_f, 1);
    Serial.println("Mean: " + String(mean_f));
}

compiles normally.

1 Like

So actually, GitHub - arduino/ArduinoCore-sam also doesn’t link with the CMSIS-DSP library, which on top is known as outdated since over 7 years…

Of course, if you have a precompiled CMSIS-DSP library for a Cortex-M3, you can also copy that into your project and link it as normal

build_flags =
  -I<path to where include folder for CMSIS-DSP is>
  -DARM_MATH_CM3
  -L<path to where libarm_cortexM3l_math.a is>
  -larm_cortexM3l_math

E.g. from https://github.com/ARM-software/CMSIS_5/tree/5.7.0/CMSIS/DSP/Lib/GCC (slightly older version) or by building the latest version from source.

1 Like

Thank you, but unfortunately it still does not work. I seem to have a problem with the Import(“env”) command, which is underlined (see screenshot). It seems that the “env” variable is not known to the system. Is it an accident that 'Import(“env”) ’ is in capital letters, import os is in small letters?

The squiggly yellow lines have not disturbed me that far, maybe the extra script that I have now ammended was not necessary after all, but if the env variable isn’t known, how should the .Append command work? I coudl use your second suggestion and link the library directly, but it would be nice to have an alternative to work with.
Many thanks


import os
from os import path

Import(“env”)

platform = env.PioPlatform()
FRAMEWORK_DIR = platform.get_package_dir(“framework-arduino-sam”)

env.Prepend(
UPLOADERFLAGS=[“-s”, path.join(platform.get_package_dir(“tool-openocd”), “scripts”) or “”,
“-f”, “interface/cmsis-dap.cfg”,
“-c”, ‘set CHIPNAME at91sam3X8E’,
‘-c’, ‘source [find target/at91sam3ax_8x.cfg]’]
)
env.Append(
CPPDEFINES = [“ARM_MATH_CM3”],
LIBPATH=[os.path.join(FRAMEWORK_DIR, “system”, “CMSIS”, “CMSIS”, “Lib”, “GCC”)],
UPLOADERFLAGS=[“-c”, “telnet_port disabled; program {$SOURCE} 0x80000 verify reset; shutdown”]
)
env.Replace(
UPLOADER=“openocd”,
UPLOADCMD=“$UPLOADER $UPLOADERFLAGS”
)

Completely irrelevant. VSCode Python intellisense doesn’t work in SCons exta_scripts files because it does not know about the dynamic functions injected into the SCons script at runtime. The script will work normally.

You also have to be carefull that, if you just copy paste my script contents into your script, that the entire script is executed as pre:.

In your script, you also neglect to actually add the

env.Append(
  LIBS=["arm_cortexM3l_math"]
)

part.

Try following the example above exactly. It works.

You can also reference multiple scripts, so you can leave your script alone.

extra_scripts = 
  pre:link_cmsis_dsp.py
  your_script.py

Thank you, both methods work now! I have mainainted the original script, it makes sense to make it modular. I really have to stop ignoring Python, as I am struggeling with the syntax, although a lot of it seems custom defined. I guess that the pre:xxxx.py is something that is defined by PlatformIO and not Python, and the same is true for env?

Yes, see docs.

https://docs.platformio.org/en/latest/scripting/index.html