Pages: [1] 2   Go Down
Author Topic: linking with libarm_cortexM3l_math.a ?  (Read 6646 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 2
Posts: 109
ArduiYES!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I was trying to use CMSIS DSP library on the DUE.
this library is the file libarm_cortexM3l_math.a (instead of in .cpp source code, like the
run-of-the-mill arduino (user)libraries)

the headers for this library are available by including
Code:
#define ARM_MATH_CM3
#include <arm_math.h>
in your sketch.

this gives the error (in an example sketch, seen here : http://arduino.cc/forum/index.php/topic,131777.msg1051678.html#msg1051678)
Code:
dsptest_due.cpp.o: In function `loop':
/home/raalst/arduino-1.5.1/dsptest_due.ino:51: warning: undefined reference to `arm_cfft_radix4_init_q31'
/home/raalst/arduino-1.5.1/dsptest_due.ino:54: warning: undefined reference to `arm_cfft_radix4_q31'
/home/raalst/arduino-1.5.1/dsptest_due.ino:59: warning: undefined reference to `arm_cmplx_mag_q31'
/home/raalst/arduino-1.5.1/dsptest_due.ino:62: warning: undefined reference to `arm_max_q31'

So i conclude I must now tweak the IDE to also use library libarm_cortexM3l_math.a when linking.
I found this file in the arduino 1.5.1 IDE distribution

Can somebody tell me how to achieve that ? I'm not much at home in gcc.

I did check with nm --print-armap that the function names
of the DSP lib are indeed in this library, so I think I have the right one.
I put the .a file in a lot of directories where .a files were already present (like .....arduino-1.5.1/hardware/arduino/sam/variants, where the library libsam_sam3x8e_gcc_rel.a lives).

I also added -larm_cortexM3l_math in boards.txt :
Code:
arduino_due_x_dbg.build.extra_flags=-D__SAM3X8E__ -mthumb -DUSB_PID={build.pid} -DUSB_VID={build.vid} -DUSBCON -larm_cortexM3l_math


but no luck yet....

I would be very grateful for a bit of explanation of what goes where and how to add this DSPlib library when linking the sketch.
Or the confirmation that this "should just work"  and I have hit a little bugette  smiley-cool



« Last Edit: January 01, 2013, 11:51:26 am by raalst » Logged

Forum Administrator
Milano, Italy
Offline Offline
Sr. Member
*****
Karma: 23
Posts: 292
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try to give a look at the platforms.txt file (in the same folder where boards.txt is) you should change the line:

## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -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,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls_sam3.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group

and add your library just after

... "{build.variant.path}/{build.variant_system_lib}" "{build.variant.path}/YOURLIBHERE.a" ...

something like this should do fine:

## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -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,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls_sam3.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.variant.path}/libarm_cortexM3l_math.a" "{build.path}/{archive_file}" -Wl,--end-group

but remember, this is a totally Untested Solution™.
Logged

C.

0
Offline Offline
Full Member
***
Karma: 2
Posts: 109
ArduiYES!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I understand I'm on my own, targeting my own feet with my large guns  smiley-cool

But thank you VERY much for this help, let's see...
Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 109
ArduiYES!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 
  Success !!!
 
  the software links, and runs the example. this means I have a lot of DSP goodies at my disposal, together with two DAC's and a lot of
  ADC's.

   Wheeeeeeeee !

sketch from /arduino-1.5.1/hardware/arduino/sam/system/CMSIS/CMSIS/DSP_Lib/Examples, mutilated by me
Code:
#define ARM_MATH_CM3
#include <arm_math.h>

#define TEST_LENGTH_SAMPLES 2048


 
static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
 
uint32_t M = 0;
 
/* ------------------------------------------------------------------
* Global variables for FFT Bin Example
* ------------------------------------------------------------------- */
uint32_t fftSize = 1024;
uint32_t ifftFlag = 0;
uint32_t doBitReverse = 1;
 
/* Reference index at which max energy of bin ocuurs */
uint32_t refIndex = 213, testIndex = 0;
 
/* ----------------------------------------------------------------------
Test Input signal contains 10KHz signal + Uniformly distributed white noise
** ------------------------------------------------------------------- */

float32_t testInput_f32_10khz[2048] =
{  
-0.865129623056441, 0.000000000000000, -2.655020678073846, 0.000000000000000, 0.600664612949661, 0.000000000000000, 0.080378093886515, 0.000000000000000,
... lots more numbers clipped away (see mentioned example dir, fft_bin example for full table ....
-2.899160484012034, 0.000000000000000, 2.563004262857762, 0.000000000000000, 3.078328403304206, 0.000000000000000, 0.105906778385130, 0.000000000000000,
};

void setup() {
  Serial.begin(19200);
  Serial.println(" start program ");
}

void loop() {
      
    
       /** \example arm_fft_bin_example_f32.c
  */  

arm_status status;
arm_cfft_radix4_instance_f32 S;
float32_t maxValue;

status = ARM_MATH_SUCCESS;

/* Initialize the CFFT/CIFFT module */  
status = arm_cfft_radix4_init_f32(&S, fftSize, ifftFlag, doBitReverse);
Serial.println("step 1");
/* Process the data through the CFFT/CIFFT module */
arm_cfft_radix4_f32(&S, testInput_f32_10khz);
Serial.println("step 2");  

/* Process the data through the Complex Magnitude Module for  
calculating the magnitude at each bin */
arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);  
Serial.println("step 3");  
/* Calculates maxValue and returns corresponding BIN value */
arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
Serial.println("step 4");  
        Serial.println(testIndex,DEC);
        Serial.println(refIndex,DEC);      
        
    while(1);                             /* main function does not return */
    
}

output :
Code:
start program
step 1
step 2
step 3
step 4
213
213



to reproduce this, follow cmaglie's advice (with caution..)
 
and be sure the library mentioned (.../arduino-1.5.1/hardware/arduino/sam/system/CMSIS/CMSIS/Lib/GCC/libarm_cortexM3l_math.a) has been copied to directory  .../arduino-1.5.1/hardware/arduino/sam/variants/arduino_due_x

for an idea what is in this library, have a look at
.../arduino-1.5.1/hardware/arduino/sam/system/CMSIS/CMSIS/Documentation/DSP_Lib/html/index.html
It even contains a PID controller ! and examples...


btw, additional examples about how to program various bits of the DUE can be found here (I'm not sure if this is about
the same library, or something that looks like it) : http://asf.atmel.com/docs/3.1.3/api.html.
click on a subject (be sure to select sam3x8e, or whatever matches this code most) and hope there is an example shown...
« Last Edit: January 02, 2013, 03:21:57 pm by raalst » Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 109
ArduiYES!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

running all 4 fft computations in the example 1000 times
(and assuming Millis() works correctly on the DUE)
takes about 35 seconds. 
hence 35 milliseconds per fft, for 1024 bins,

and 28 fft1024 calculations per second.   

Im falling in love with this beast...

Code:
start program
34939
69320
Logged

US
Offline Offline
Full Member
***
Karma: 4
Posts: 183
Electronics are the new Legos
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am looking to read one of the ADC lines which has an Adafruit electret mic amp board on it, perform an FFT, then display a frequency vs. amplitude plot with the data.  Has anyone progressed to something similar to this point?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

running all 4 fft computations in the example 1000 times
(and assuming Millis() works correctly on the DUE)
takes about 35 seconds. 
hence 35 milliseconds per fft, for 1024 bins,

and 28 fft1024 calculations per second.   

Im falling in love with this beast...

Code:
start program
34939
69320


I followed all your steps, I edited the platforms.txt file, butno glory,  when my Arduino Due boots, it freezes.
It freezes whenever I call any of the functions of your example, i.e. arm_cfft_radix4_init_f32. If I comment ount that line, everything works.

When I compile I get the following errors:
Code:
EXTRACTOR_FFT_ARDUINO_DUE.cpp.o: In function `Ejecuta_FFT()':
D:\Arduino\arduino-1.5.2/EXTRACTOR_FFT_ARDUINO_DUE.ino:131: warning: undefined reference to `arm_cfft_radix4_init_f32'
D:\Arduino\arduino-1.5.2/EXTRACTOR_FFT_ARDUINO_DUE.ino:135: warning: undefined reference to `arm_cfft_radix4_f32'
D:\Arduino\arduino-1.5.2/EXTRACTOR_FFT_ARDUINO_DUE.ino:140: warning: undefined reference to `arm_cmplx_mag_f32'
D:\Arduino\arduino-1.5.2/EXTRACTOR_FFT_ARDUINO_DUE.ino:143: warning: undefined reference to `arm_max_f32'
Binary sketch size: 23.212 bytes (of a 524.288 byte maximum) - 4% used

Any hint on this?
Thank you.
Logged

Offline Offline
God Member
*****
Karma: 32
Posts: 507
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please turn on verbose mode in preferences and post the full output. I followed the instructions here and it worked fine.

Is there any reason not to include this modification in the next IDE release? It doesn't affect sketches which don't use the functions.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please turn on verbose mode in preferences and post the full output. I followed the instructions here and it worked fine.

Is there any reason not to include this modification in the next IDE release? It doesn't affect sketches which don't use the functions.

Ok, I have spotted the error.

First I restarted the Arduino IDE.  smiley-lol smiley-lol

Then I tried to change the points of the FFT to the half by using:
Code:
#define TEST_LENGTH_SAMPLES 1024
uint32_t fftSize = 512;

So I get the error at the call:
Code:
arm_cfft_radix4_f32(&S, testInput_f32_10khz);

after step 1.


Then I checked the file arm_cfft_radix4_init_f32.c, and there is not a 512 point fft!!!
Is there any way to introduce it?


« Last Edit: March 02, 2013, 07:54:19 pm by PakARD » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have seen that in the CMSIS library, those functions exist in radix2 format as well:

http://mazsola.iit.uni-miskolc.hu/DATA/segedletek/arm/cmsis/CMSIS/Documentation/DSP/html/group___radix2___c_f_f_t___c_i_f_f_t.html

But they are not included in the Arduino Due Libraries, why? Is it possible to add them? If it is, will they work with similar performance?

Thank you

Logged

South Africa
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just spent half an hour trying to figure out why it wouldn't compile before I realized I still had the board selected as UNO ... (facepalm)

Anyway moving on. Just to confirm did I also need to modify the board.txt file as per what raalst tried first or was the change to the platforms.txt all that was needed? I've changed both and it's working like a dream but I won't leave board.txt modified if the change wasn't needed.

I've been finding and comparing different PID and FFT libraries for the DUE and to have them so neatly pre-packaged and (according to the docs) cortex optimized is way beyond what I expected to get, so big thanks raalst & cmaglie. I'm going to be trying to FFT a piezo sensor input to identify vibration modes in machinery as a fault finding/early fault detection system. If I get it right I'll make a post for it.

Cheers

Andrew
Logged

Rocket science is easy, it's all this electrical stuff that gets me.

Offline Offline
God Member
*****
Karma: 32
Posts: 507
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Only platform.txt needs to be changed, as per cmaglie's post.

Just to reiterate what I said before - I've now had this modification for 2 months and have used the IDE heavily and have had absolutely no problems or incompatibilities at all with sketches not using the library. I would recommend this change to be included in the next IDE release.
Logged


0
Offline Offline
Full Member
***
Karma: 2
Posts: 109
ArduiYES!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice to hear the post has been useful.

I'm making good progress attaching a mic, sampling it and displaying the FFT on a simple 128x64 glcd.
this requires use of the ADC, use of the DMA (pdc), the dsp library and U8glib. and a lot of large arrays.
but it still fits.

I created my own constants to refer to the registers, just to be sure to understand the datasheet

the DMA is freerunning, the sampling rate controlled by the prescaler value.
when needed I ask the PDC to get an array worth of ADC data, then busy-wait for the array to be filled.
after that FFT and display.  

I am confused by the large amount of clocks in the system. it is correct to assume MCK is 4 Mhz in the DUE ?
does anybody know for sure ?
I do see FFT output, but relating it to frequencies is out of my league and currently done by running
the baudline (great piece of software !) tone generator at a known frequency in my PC.

current code (as an example, quite possibly of "how not to program"..) : see attachment


* ownDMA_ADC_GLCD_fft_v3.ino (63.65 KB - downloaded 81 times.)
« Last Edit: April 14, 2013, 06:45:32 am by raalst » Logged

US
Offline Offline
Full Member
***
Karma: 4
Posts: 183
Electronics are the new Legos
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great work raalst.  I would hope that DMA sampling could be rolled into a library some day.  Sooner than that I'd hope the Arduino Team would support formally some of the ARM libraries like the math one which includes the FFT - the power and code is already there, just make it easier for the development community to use it in the same spirit that has been done for other platforms.
Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 109
ArduiYES!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good links deserve plugging :
this link is about the only one I found that goes into any detail on the DUE ADC capabilities and settings
http://www.djerickson.com/arduino/
Logged

Pages: [1] 2   Go Up
Jump to: