LABORATORIO DI ARCHITETTURE E...
Transcript of LABORATORIO DI ARCHITETTURE E...
LABORATORIO DI ARCHITETTURE E PROGRAMMAZIONE DEI SISTEMI
ELETTRONICI INDUSTRIALILaboratory Lesson 10:
CMSIS DSP Library and Functions
Final Assignment
Prof. Luca Benini <[email protected]> Simone Benatti <[email protected]>Prof Davide Rossi <[email protected]> Victor Kartsch<[email protected]>
Recap
LAB1: IDE & Debug
LAB2: GPIO & Systick
LAB3: Advanced Debug
LAB4: EXTI
LAB5: Timers
LAB6: FLASH & DMA
LAB7: USART
LAB8: ADC
LAB9: SPI
LAB10: CMSIS DSP
• CMSIS DSP lib and signal processing
CMSIS
CMSIS: Cortex Microcontroller Software Interface Standard
• Vendor-independent hardware abstraction layer for ARM Cortex-M
• Simple software interfaces for ARM core for:• Peripherals’ interfaces
• Real-time operating systems
• Middleware
• DSP functions
DSP Functions
Abs, dot products, fixed point operations, …
Complex math…
PIDs, …
Sin, cos, tan, …
FIR,IIR, conv, LMS…
Matrix multiplication, inverse, …
Mean, RMS, variance, ...
Conversion fix to float, …
FFTs
• Provides fast development for basic math for DSP• SPEEDUP code execution
Example 1: Dot product
𝒂 ∙ 𝒃 =
𝑛=1
∞
𝑎𝑛 ∙ 𝑏𝑛
Dot product or inner product or scalar product• One of the most used operations in all signal processing domains• Many efficient HW/SW implementations
Intuition Algebraic function
In our world vectors are…ARRAYS!
Dot product implementation
static int n;
for(n = 0 ; n<Array_dimension ; n++){
product += a[n]*b[n];}
𝒂 ∙ 𝒃 =
𝑛=1
∞
𝑎𝑛 ∙ 𝑏𝑛
The MATH The CODE
Problems:1. Many ldr & str operations2. Many multiplications and sums
Dot product with CMSIS DSP
arm_dot_prod_f32(&srcA_buf_f32, &srcB_buf_f32, MAX_BLOCKSIZE, &testOutput);
Vector 1 Vector 2 Dimension Output
In your sample code compare the 2 executions:
nonARM_product( &srcA_buf_f32,&srcB_buf_f32, &multOutput, MAX_BLOCKSIZE)
vsarm_dot_prod_f32(&srcA_buf_f32,&srcB_buf_f32, MAX_BLOCKSIZE, &testOutput);
1900 cycles
1000 cycles
SPEEDUP x2!!
Example 2 : Digital Filters
FIR pros:1. can be designed with linear phase2. simple to implement3. good for finite precision math
FIR cons:1. FIR requires more memory and computation (more coefficients)2. Bigger filters cause delays
There are two main digital filters categories:• FIR (Finite Impulse Response)• IIR (Infinite Impulse Response)
FIR basics
𝑦(𝑛) =
𝑘=0
𝑁−1
ℎ 𝑘 𝑥(𝑛 − 𝑘)
h(k) = Coefficients (aka taps)
x(n-k) = Input data
Filter diagramFilter formula
N = filter order (aka number of coeffs.) 𝑦(𝑛)
Calculate the coefficients
Use the following Matlab script:
% Define sampling frequencyFs = 1000; %1kHz
% Define cutoff frequency Cutoff_freq = 40;
% Calculate Nyquist frequencyNyq_frequency = Fs/2;Cutoff_norm = Cutoff_freq/Nyq_frequency;
% FIR orderorder = 4;
% Calculate taps (coefficients)FIR_coeff = fir1(order,Cutoff_norm);
Simple example with 3 coefficients
𝑦 𝑛 = ℎ 0 𝑥 𝑛 + ℎ 1 𝑥 𝑛 − 1 + ℎ 2 𝑥(𝑛 − 2)
In this case we have:
Coefficients
Input data
float X[1000];
float Y[1000];
float h[N] = {0.32590173795979338000, 0.34819652408041324000, 0.32590173795979338000};
int main()
{
float yn = 0;
int i,k;
const int N = 3;
float x[N] = {0,0,0};
X[0] = 1;
for(i=0; i<1000; i++)
{
for(k=0; k < N-1; k++) {
x[N-k-1] = x[N-k-2]; //shift the data
}
x[0] = X[i]; // move input sample to buffer
yn = 0; // clear output sample
for(k=0; k < N; k++) {
yn += h[k]*x[k]; // multiply and accumulate data with coefficients
}
Y[i] = yn; // move output sample to buffer
}
}
FIR C Implementation
CMSIS DSP Implementation
#define BLOCK_SIZE 32
#define NUM_TAPS 29
#define TEST_LENGTH_SAMPLES 320
uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE;
. . .
int main(void)
{
. . .
/* Initialize input and output buffer pointers */
inputF32 = &testInput_f32_1kHz_15kHz[0];
outputF32 = &testOutput[0];
/* Call FIR init function to initialize the instance structure. */
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32[0], &firStateF32[0], blockSize);
/* Call the FIR process function for every blockSize samples */
for(i=0; i < numBlocks; i++) {
arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize);
}
. . .
}
Check the code implementation!
Optimization: going faster!
You can tell your compiler to optimize the code when compiling, making the
execution faster ( >50% faster).
Optimization is not for dummies, use it only when you carefully debugged the code.
• some code that work without optimization may NOT work when you optimize, so
pay attention!
• It is strongly compiler dependent (in our case GCC)
We have several optimization flags (O0 – O3). The most popular are:
• O0 No optimization.
Direct correspondence between each line of code and the resulting machine
instructions
• O2 Enables more optimizations.
This mode turns on nearly all optimizations.
Optimization: going faster!
To set an optimization level in your project:Project proprieties -> C/C++ Build -> Settings -> MCU GCC Compiler -> Optimization -> select optimization level
If the code is well-written, optimization is more effective
CMSIS functions are specifically well-written for our platform:they enable loop unrolling, MAC instructions and other DSP features of our Cortex M4 MCU
Performance: Dot product
0
0,5
1
1,5
2
Dot product -O0 Dot product -O2
KCyc
les NO CMSIS
CMSIS DSP
NO CMSIS CMSIS DSP
Dot product -O0 1,9 0,99
Dot product -O2 0,3 0,24
Performance: FIR filter
0
200
400
600
800
1000
FIR -O0 FIR -O2
KCyc
les NO CMSIS
CMSIS DSP
NO CMSIS CMSIS DSP
FIR -O0 823 201
FIR -O2 138 43
Functions: declaration
Function prototype:• function name (must be unique)• type of input parameters (may be void)• type of return variable (may be void)• equivalent to variable declaration
Functions: implementation
Function implementation:• The actual code that is executed when
the function is called• The code is written only once, but it can
be used several times with different input parameters
Functions: use
Function use:• the actual call to the function• defines when the code is called during the
execution of a program• must provide the correct input parameters
Functions: libraries
Local function:• Delared and implemented in the current file• Can be only called within that file
Library function:• Declared in separate header file (.h) and
implemented in dedicated source file (.c)• Can be used in any file that includes its
header
Code organization
Until now we have always put everything in the main file:• OK for simple projects• NOT OK for complex and large projects• NOT OK for code sharing and re-use
You can create your own libraries!• Different files with collection of useful functions, for easy re-use• Try to be organized: group functions in a logical way
You have functions that compute mean, variance and min/max, and you want to put them in a features library… how? • Create file features.h in the ./inc subdirectory of your project• Put the functions prototypes in features.h• Create file features.c in the ./src subdirectory of your project• Put the functions implementations in features.c• In main: add #include “functions.h” and call your functions with the correct parameters.
Libraries and folders
When dealing with multiple files and libraries you can use folders and sub-folders to organize them• It is up to you, but some common practices are good to follow
Libraries and folders
When dealing with multiple files and libraries you can use folders and sub-folders to organize them• It is up to you, but some common practices are good to follow
When you create a project you already have a starting folder structure:• Main application files are in ./inc and ./src
Libraries and folders
When dealing with multiple files and libraries you can use folders and sub-folders to organize them• It is up to you, but some common practices are good to follow
When you create a project you already have a starting folder structure: • Main application files are in ./inc and ./src• StdPeriph_Driver: library organized with inc and src sub-floders
Libraries and folders
When dealing with multiple files and libraries you can use folders and sub-folders to organize them• It is up to you, but some common practices are good to follow
When you create a project you already have a starting folder structure:• Main application files are in ./inc and ./src• StdPeriph_Driver: library organized with inc and src sub-floders• Utilities: library with a common folder for header and source
files
Libraries and folders
When dealing with multiple files and libraries you can use folders and sub-folders to organize them• It is up to you, but some common practices are good to follow
When you create a project you already have a starting folder structure:• Main application files are in ./inc and ./src• StdPeriph_Driver: library organized with inc and src sub-floders• Utilities: library with a common folder for header and source
files
So what is the difference between putting a header file in ./inc or ./Utilities or ./StdPeriph_Driver/inc or creating a new (sub)directory?
Nothing, but you must ensure that the compiler and linker know when to get those files!
Libraries: project settings
If you add your files in the main src/inc folders everything will be ok……but, if you create a new folder to organize your files, it will give you lots of errors…!
You have to add the new folders to the compiler and linker paths!
• Create the folder/files you want or copy them in the project’s main folder• If you copy files outside Eclipse, you have to refresh to see them• You have to add any folder containing header files (.h) to the include paths• You have to add any folder containing source files (.c) to the source paths• If a folder contains both, add it in both paths• Subfolders are usually ok, but you may have to check
Libraries: include paths
You have to add any folder containing header files (.h) to the include paths:
Project proprieties -> C/C++ Build -> Settings -> MCU GCC Compiler -> Includes -> add the desired folder in the Include paths panel
You should use relative paths:• If you copy or export the project it will work• use project directory or workspace directory
as reference• copy from the folders already listed there