Skip to content

Commit ff28702

Browse files
author
Mikaël BRIDAY
committed
[cortex-m] stress test for FPU support
1 parent 7dfba84 commit ff28702

6 files changed

Lines changed: 272 additions & 0 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FPU_test
2+
build
3+
*_exe
4+
*.bin
5+
*.map
6+
build.py
7+
make.py
8+
CMakeLists.txt
9+
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "tpl_os.h"
2+
#include "stm32l4xx.h"
3+
#include "pinAccess.h"
4+
#include <math.h>
5+
6+
//see machines/cortex-m/armv7em/stm32l432/lib/serial.h
7+
#include "serial.h"
8+
9+
#define APP_Task_backgroundTask_START_SEC_CODE
10+
#include "tpl_memmap.h"
11+
12+
13+
void updateClock_80MHz();
14+
//update the systick configuration
15+
void tpl_set_systick_timer();
16+
17+
//We use PA6 and PA7 to measure on logic analyser that the fpu computation is effectively preemted by the high priority task.
18+
FUNC(int, OS_APPL_CODE) main(void)
19+
{
20+
pinMode(GPIOB,3,OUTPUT); //led 1 is PB3
21+
updateClock_80MHz();
22+
//call systick config again => System Core Clock updated.
23+
tpl_set_systick_timer();
24+
25+
tpl_serial_begin();
26+
pinMode(GPIOA, 6, OUTPUT); // refered as A5 on Nucleo
27+
pinMode(GPIOA, 7, OUTPUT); // refered as A6 on Nucleo
28+
StartOS(OSDEFAULTAPPMODE);
29+
return 0;
30+
}
31+
32+
volatile float shared; //float type => atomic
33+
34+
TASK(highPrioTask)
35+
{
36+
digitalWrite(GPIOA,6,1);
37+
volatile double tmp1; //volatile tmp value to limit compiler optimization
38+
39+
double a = cos(shared);
40+
double b = sin(shared);
41+
tmp1 = sqrt(a*a+b*b);
42+
digitalWrite(GPIOA,6,0);
43+
TerminateTask();
44+
}
45+
46+
// basic FPU reated calculation
47+
// it computes the Sum of 1/(i^2), from 1 to ...
48+
// This sum converge (slowly) to pi^2/6 => we get an approx of pi
49+
// and print it every 1000 iterations
50+
TASK(backgroundTask)
51+
{
52+
volatile double tmp1; //volatile tmp value to limit compiler optimization
53+
54+
double n = 0.0;
55+
double un = 0.0;
56+
int idx = 0;
57+
while(1)
58+
{
59+
digitalWrite(GPIOA,7,1);
60+
n += 1.0;
61+
double term = 1/(n*n);
62+
tmp1 = term;
63+
un += term;
64+
double _pi = sqrt(un*6);
65+
shared = (float)_pi;
66+
int int_part = (int)_pi;
67+
int frac_part = (int)((_pi-int_part)*100000000UL);
68+
idx ++;
69+
digitalWrite(GPIOA,7,0);
70+
71+
if(idx % 1000 == 0)
72+
{
73+
tpl_serial_wait_for_tx_complete();
74+
tpl_serial_print_string("_pi: ");
75+
tpl_serial_print_int(int_part,10,1); //val, base, field width
76+
tpl_serial_putchar('.');
77+
tpl_serial_print_int(frac_part,10,8); //val, base, field width
78+
tpl_serial_print_string("\r\n");
79+
}
80+
}
81+
82+
83+
// int i = 1;
84+
// un += 1/((double)i*i);
85+
// double pi = sqrt(un*6);
86+
// tpl_serial_print_string("count: ");
87+
// tpl_serial_print_int((int)(pi*1000),10,6); //val, base, field width
88+
// tpl_serial_print_string("\r\n");
89+
// i++;
90+
// digitalToggle(GPIOB,3); //led
91+
TerminateTask();
92+
}
93+
94+
//tmp TODO: add ISR into library.
95+
void itUsart();
96+
ISR(usart)
97+
{
98+
itUsart();
99+
}
100+
101+
#define APP_Task_backgroundTask_STOP_SEC_CODE
102+
#include "tpl_memmap.h"
103+
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
OIL_VERSION = "2.5";
2+
3+
IMPLEMENTATION trampoline {
4+
/* This fix the default STACKSIZE of tasks */
5+
TASK {
6+
UINT32 STACKSIZE = 300 ;
7+
} ;
8+
9+
/* This fix the default STACKSIZE of ISRs */
10+
ISR {
11+
UINT32 STACKSIZE = 200 ;
12+
} ;
13+
};
14+
15+
CPU serial {
16+
OS config {
17+
STATUS = EXTENDED;
18+
PAINT_STACK = TRUE;
19+
PAINT_REGISTERS = TRUE;
20+
21+
BUILD = TRUE {
22+
TRAMPOLINE_BASE_PATH = "../../../../../..";
23+
APP_SRC = "FPU_test.c";
24+
APP_SRC = "clock.c";
25+
APP_NAME = "FPU_test";
26+
LIBRARY = serial {
27+
TXBUFFER = 64;
28+
};
29+
CFLAGS = "-O3";
30+
CFLAGS = "-finline-functions";
31+
// CFLAGS = "-fomit-frame-pointer -fno-common";
32+
CFLAGS = "-ffast-math -funroll-loops";
33+
34+
LDFLAGS = "-Map=serial.map";
35+
COMPILER = "arm-none-eabi-gcc";
36+
ASSEMBLER = "arm-none-eabi-as";
37+
LINKER = "arm-none-eabi-ld";
38+
COPIER = "arm-none-eabi-objcopy";
39+
SYSTEM = CMAKE {VSCODE=TRUE;};
40+
};
41+
SYSTEM_CALL = TRUE;
42+
MEMMAP = TRUE {
43+
COMPILER = gcc;
44+
LINKER = gnu_ld { SCRIPT = "script.ld"; };
45+
ASSEMBLER = gnu_as;
46+
MEMORY_PROTECTION = FALSE;
47+
};
48+
};
49+
50+
APPMODE appStd {};
51+
52+
TASK highPrioTask {
53+
PRIORITY = 20;
54+
AUTOSTART = FALSE;
55+
USEFLOAT= TRUE;
56+
ACTIVATION = 1;
57+
SCHEDULE = FULL;
58+
};
59+
60+
TASK backgroundTask {
61+
PRIORITY = 2;
62+
AUTOSTART = TRUE {APPMODE = appStd;};
63+
USEFLOAT= TRUE;
64+
ACTIVATION = 1;
65+
SCHEDULE = FULL;
66+
};
67+
68+
ALARM periodicAl {
69+
COUNTER = SystemCounter;
70+
ACTION = ACTIVATETASK {
71+
TASK = highPrioTask;
72+
};
73+
AUTOSTART = TRUE {
74+
APPMODE = appStd;
75+
ALARMTIME = 2;
76+
CYCLETIME = 1;
77+
};
78+
};
79+
//ISR required by the serial TX
80+
ISR usart {
81+
CATEGORY = 1;
82+
PRIORITY = 10;
83+
SOURCE = USART2_IRQ; //TX on PA2/A7
84+
};
85+
};
86+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Serial example
2+
3+
This application is a stress test for the CPU.
4+
5+
* A background task performs a calculation requiring floating point operations (the sum of the terms 1/n²). The sequence converges to pi²/6, allowing us to calculate an approximation of pi. Every 1,000 iterations, the value is sent over the serial link.
6+
* The high-priority task preempts the background task to also perform floating-point calculations.
7+
8+
Reconstruction of the task scheduling with preemption, using a logic analyzer:
9+
10+
![logicScheduling.png](logicScheduling.png)
11+
12+
The SystemCounter is at 1ms. The serial configuration is 115200, 8N1, with the serial line connected to the debugger (/dev/ttyACM0 on Linux).
13+
14+
`
15+
goil --target=cortex-m/armv7em/stm32l432 --templates=../../../../../../goil/templates/ FPU_test.oil
16+
`
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "stm32l4xx.h"
2+
3+
/* system clock:
4+
* %%%% STM32L432 Nucleo => 80MHz %%%%
5+
* - use internal HSI RC oscillator => 16MHz
6+
* - PLL source is HSI => 16MHz
7+
* - configure PLLx10/2 => SYSCLK = 80MHz
8+
* - flash needs 4 wait states (F>64MHz)
9+
* - APB1 clocks sets to 80MHz
10+
* - APB2 clocks sets to 80MHz
11+
*
12+
* */
13+
void updateClock_80MHz()
14+
{
15+
// Must set flash latency (4 wait states): F>64MHz
16+
FLASH->ACR |= 4 << FLASH_ACR_LATENCY_Pos // add 4 wait states
17+
| FLASH_ACR_PRFTEN; // enable prefetch buffer
18+
19+
20+
//no clock division for APB1
21+
RCC->CFGR &= ~RCC_CFGR_PPRE1_Msk;
22+
//no clock division for APB2
23+
RCC->CFGR &= ~RCC_CFGR_PPRE2_Msk;
24+
//no clock division for AHB
25+
RCC->CFGR &= ~RCC_CFGR_HPRE_Msk;
26+
27+
//make sure that MSI is the system clock (default)
28+
RCC->CFGR &= ~RCC_CFGR_SW_Msk; // reset SW configuration
29+
while((RCC->CFGR & RCC_CFGR_SWS) != 0){}
30+
31+
RCC->CR |= RCC_CR_HSION; // turn on HSI (16MHz)
32+
while((RCC->CR & RCC_CR_HSIRDY) == 0){}
33+
34+
35+
RCC->CR &= ~(RCC_CR_PLLON); // turn off PLL
36+
while(RCC->CR & RCC_CR_PLLRDY){} // wait until pll is stopped
37+
38+
RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC_Pos); // reset PLLSRC
39+
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI ; // HSI => 16MHz
40+
41+
RCC->PLLCFGR |= 7 << RCC_PLLCFGR_PLLPDIV_Pos ; // PLLSAI2CLK = VCO/7
42+
43+
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN_Msk ; // reset PLLN (numerator)
44+
RCC->PLLCFGR |= 10 << RCC_PLLCFGR_PLLN_Pos; //PLLN = 10
45+
46+
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM_Msk ; // reset PLLM (denominator) => PLLM=1
47+
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLR_Msk ; // reset PLLR (division factor) => PLLR=1
48+
49+
RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN; // enable PLLR (the one for SYSCLK)
50+
51+
RCC->CR |= RCC_CR_PLLON; // turn on PLL
52+
while(!(RCC->CR & RCC_CR_PLLRDY)){}
53+
54+
RCC->CFGR |= RCC_CFGR_SW_PLL; // PLL is system clock
55+
56+
SystemCoreClockUpdate();
57+
58+
}
46.7 KB
Loading

0 commit comments

Comments
 (0)