arunkumar
arunkumar

Reputation: 34053

STM32F Discovery - Undefined reference to arm_sin_f32

I'm new to programming the STM32F Discovery board. I followed the instructions here and managed to get the blinky led light working.

But now I'm trying to play an audio tone for which I have borrowed code from here. In my Makefile I have included CFLAGS += -lm which is where I understand that arm_sin_f32 is defined.

This is the code for main.c:

#define USE_STDPERIPH_DRIVER
#include "stm32f4xx.h"
#define ARM_MATH_CM4
#include <arm_math.h> 
#include <math.h>
#include "speaker.h"

//Quick hack, approximately 1ms delay
void ms_delay(int ms)
{
    while (ms-- > 0) {
      volatile int x=5971;
      while (x-- > 0)
        __asm("nop");
   }
}

volatile uint32_t msTicks = 0;

// SysTick Handler (every time the interrupt occurs, this is called)
void SysTick_Handler(void){ msTicks++; }

// initialize the system tick 
void InitSystick(void){
   SystemCoreClockUpdate();
    // division occurs in terms of seconds... divide by 1000 to get ms, for example
   if (SysTick_Config(SystemCoreClock / 10000)) { while (1); } // 
update every 0.0001 s, aka 10kHz
}


//Flash orange LED at about 1hz
int main(void)
{
    SystemInit();
    InitSystick();
    init_speaker();
    int16_t audio_sample;
    int loudness = 250;
    float audio_freq = 440;
    audio_sample = (int16_t) (loudness * arm_sin_f32(audio_freq*msTicks/10000));
    send_to_speaker(audio_sample);
}

But when trying to run make I get the following error:

main.c:42: undefined reference to `arm_sin_f32'

Upvotes: 2

Views: 4999

Answers (2)

Lanting
Lanting

Reputation: 3068

By using -lm, you're linking to libc's math library, which for floating points provides you with

https://www.gnu.org/software/libc/manual/html_node/Trig-Functions.html

Function: double sin (double x)
Function: float sinf (float x)
Function: long double sinl (long double x)
Function: _FloatN sinfN (_FloatN x)
Function: _FloatNx sinfNx (_FloatNx x)
Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

These functions return the sine of x, where x is given in radians. The return value is in the range -1 to 1.

You'll want to use sinf as you're using a float.


If you'd like to use arm_sin_f32, then you should link to CMSIS's dsp library. https://www.keil.com/pack/doc/CMSIS/DSP/html/group__sin.html

float32_t   arm_sin_f32 (float32_t x)
    Fast approximation to the trigonometric sine function for floating-point 
    data.

You should link to the appropriate precompiled library as detailed in: CMSIS DSP Software Library


The latest version of CMSIS at this moment is available at: https://github.com/ARM-software/CMSIS_5 I don't think you should simply copy the c-files, as it will 'pollute' your own project and updating will be hard.

Simply download the latest release and to your makefile add:

CMSISPATH = "C:/path/to/cmsis/top/directory"
CFLAGS += -I$(CMSISPATH)/CMSIS/DSP/Include
LDFLAGS += -L$(CMSISPATH)/CMSIS/Lib/GCC/ -larm_cortexM4lf_math

Upvotes: 3

0___________
0___________

Reputation: 67546

First of all the arm_sin_32 does not exist. arm_sin_f32 for example yes. There are more different ones as well. You need to add the appropriate c file from the CMSIS to your project for example: CMSIS/DSP/Source/FastMathFunctions/arm_sin_f32.c

I would suggest to do not use the one from the keil as it probably outdated - just download the most current version of the CMSIS from github.

arm_.... functions are not the part of the m library.

Do not use nop-s for the delay as they are instantly flushed out from the pipeline without the execution. They are used only for padding

Upvotes: 1

Related Questions