Skip to content

Commit a44a0ee

Browse files
committed
Benches and toggle pin work on am6254
1 parent 5331fe5 commit a44a0ee

File tree

10 files changed

+373
-298
lines changed

10 files changed

+373
-298
lines changed

ref_app/src/app/benchmark/readme.md

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,44 +78,50 @@ $\pi$ using a Gauss AGM method with help
7878
from the [`decwide_t`](https://github.com/ckormanyos/real-time-cpp/blob/master/ref_app/src/math/wide_decimal/decwide_t.h)
7979
template class.
8080

81-
A typical range of performance classes is shown in the following table.
81+
A very wide range of microcontroller performance classes is shown in the following table.
8282
The benchmark used is a ${\sim}100$ decimal digit AGM $\pi$ calculation.
8383

8484
| Target | runtime $[ms]$ | relative |
8585
|--------------------|-----------------|------------|
86-
| `am335x` | 1.5 | 1.0 |
87-
| `stm32f446` | 5.1 | 3.4 |
88-
| `rpi_pico2_rp2350` | 6.3 | 4.2 |
89-
| `wch_ch32v307` | 8.0 | 5.3 |
90-
| `xtensa_esp32_s3` | 9.1 | 6.1 |
91-
| `rpi_pico_rp2040` | 19 | 13 |
92-
| `avr` | 420 | 280 |
86+
| `am6254_soc_` | 0.37 | 1.0 |
87+
| `am335x` | 1.5 | 4.0 |
88+
| `stm32f446` | 5.1 | 14 |
89+
| `rpi_pico2_rp2350` | 6.3 | 17 |
90+
| `wch_ch32v307` | 8.0 | 22 |
91+
| `xtensa_esp32_s3` | 9.1 | 25 |
92+
| `rpi_pico_rp2040` | 19 | 51 |
93+
| `avr` | 420 | 760 |
9394

9495
There are strikingly differing performance classes
9596
for the $8$-bit MICROCHIP(R) AVR controller of the ARDUINO
9697
and the $32$-bit ARM(R) 8 controller
9798
of the BeagleBone Black Edition, Rev. C.
9899
The $\pi$ calculation requires approximately
99-
$420~\text{ms}$ and $1.5~\text{ms}$,
100+
$420~\text{ms}$ and $1.5~\text{ms,}~$
100101
respectively, on these two microcontroller systems.
101102

103+
The $64$-bit ARM(R)v8-a (i.e., Cortex(R) A53) performs the
104+
calculation (running on one single A53 core of the PocketBeagle2 board)
105+
in $0.37~\text{ms.}$
106+
102107
The $32$-bit ARM(R) Cortex(R) M4F controller on
103108
the `stm32f446` board performs the calculation in
104109
the middle of the two extremes, with a result
105110
of $5.1~\text{ms}$.
106111

107112
The $32$-bit RISC-V controller (having a novel _open-source_ core)
108113
on the `wch_ch32v307` board boasts a quite respectable
109-
time of $8.0~\text{ms}$.
114+
time of $8.0~\text{ms.}$
110115

111116
Running on only one core (core0) of the $32$-bit
112117
controller of the `xtensa_esp32_s3` board results in
113118
a runtime of $9.1~\text{ms}$ for the calculation.
114119

115120
Using only one core (core1) on the $32$-bit ARM(R) Cortex(R) M0+
116121
controller of the `rpi_pico_rp2040` board results in a calculation
117-
time of $19~\text{ms}$. The next generation `rpi_pico2_rp2350`
122+
time of $19~\text{ms.}~$
123+
The next generation `rpi_pico2_rp2350`
118124
with dual ARM(R) Cortex(R) M33 cores definitively improves on this
119-
(still using only core1) with a time of $6.3~\text{ms}$.
125+
(still using only core1) with a time of $6.3~\text{ms.}~$
120126
This is slightly more than $3~\text{ms}$ times faster
121127
than its predecessor.

ref_app/src/mcal/am6254_soc/mcal_benchmark.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
{
1818
namespace benchmark
1919
{
20-
typedef mcal::port::port_pin<mcal::reg::gpio0, 36U> benchmark_port_type;
20+
using benchmark_port_type = mcal::port::port_pin<mcal::reg::gpio0, 36U>;
2121
}
2222
}
2323

ref_app/src/mcal/am6254_soc/mcal_irq.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@
88
#ifndef MCAL_IRQ_2010_04_10_H
99
#define MCAL_IRQ_2010_04_10_H
1010

11+
#include <core_macros.h>
12+
13+
#if defined(__cplusplus)
14+
extern "C"
15+
{
16+
#endif
17+
18+
static inline void mcal_irq_enable_all(void);
19+
static inline void mcal_irq_disable_all(void);
20+
21+
#if defined(__cplusplus)
22+
}
23+
#endif
24+
25+
#if defined(__cplusplus)
1126
namespace mcal
1227
{
1328
namespace irq
@@ -16,9 +31,22 @@
1631

1732
void init(const config_type*);
1833

19-
inline void enable_all () { /* TBD enable/disable fiqs/irqs for this arch. */ }
20-
inline void disable_all() { /* TBD enable/disable fiqs/irqs for this arch. */ }
34+
inline void enable_all() { ::mcal_irq_enable_all(); }
35+
inline void disable_all() { ::mcal_irq_disable_all(); }
2136
}
2237
}
38+
#endif
39+
40+
#if defined(__cplusplus)
41+
extern "C"
42+
{
43+
#endif
44+
45+
static inline void mcal_irq_enable_all(void) { arch_enable_ints(); arch_enable_fiqs(); }
46+
static inline void mcal_irq_disable_all(void) { arch_disable_fiqs(); arch_disable_ints(); }
47+
48+
#if defined(__cplusplus)
49+
}
50+
#endif
2351

2452
#endif // MCAL_IRQ_2010_04_10_H

ref_app/src/mcal/am6254_soc/mcal_port.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,12 @@
99

1010
void mcal::port::init(const config_type*)
1111
{
12+
// The pad configuration of gpio0.37 is on pad37 (empirical observation).
13+
// So we must initialize pad37 since we will use gpio0.36 as the
14+
// benchmark toggle-pin.
15+
mcal::port::port_pin<mcal::reg::gpio0, 36U>::set_pin_low();
16+
mcal::port::port_pin<mcal::reg::gpio0, 36U>::set_direction_output();
17+
18+
mcal::port::port_pin<mcal::reg::gpio0, 37U>::set_pin_low();
19+
mcal::port::port_pin<mcal::reg::gpio0, 37U>::set_direction_output();
1220
}

ref_app/src/mcal/am6254_soc/mcal_port.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@
9292
/* GPIO1 has no pad configuration */
9393
}
9494

95-
*reinterpret_cast<volatile std::uint32_t*>(static_cast<std::uintptr_t>(instance_base + static_cast<std::uintptr_t>((pin/32U) * UINT32_C(0x28)) + static_cast<std::uintptr_t>(UINT32_C(0x0C)) /* GPIO_CLR_DATA */)) |= static_cast<std::uint32_t>(UINT32_C(1) << pin_mod32);
96-
*reinterpret_cast<volatile std::uint32_t*>(static_cast<std::uintptr_t>(instance_base + static_cast<std::uintptr_t>((pin/32U) * UINT32_C(0x28)) + static_cast<std::uintptr_t>(UINT32_C(0x04)) /* GPIO_OUT_DATA */)) &= static_cast<std::uint32_t>(~(static_cast<std::uint32_t>(UINT32_C(1) << pin_mod32)));
9795
*reinterpret_cast<volatile std::uint32_t*>(static_cast<std::uintptr_t>(instance_base + static_cast<std::uintptr_t>((pin/32U) * UINT32_C(0x28)) + static_cast<std::uintptr_t>(UINT32_C(0x00)) /* GPIO_DIR */)) &= static_cast<std::uint32_t>(~(static_cast<std::uint32_t>(UINT32_C(1) << pin_mod32)));
9896
}
9997

ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <core_macros.h>
99
#include <gic-500.h>
1010
#include <mcal_cpu.h>
11+
#include <mcal_irq.h>
1112

1213
#include <stdbool.h>
1314
#include <stdint.h>
@@ -26,6 +27,7 @@ extern ATTRIBUTE_USED int main(void);
2627
extern void main_core1(void);
2728
extern void main_core2(void);
2829
extern void main_core3(void);
30+
extern void main_core0_init(void);
2931

3032
ATTRIBUTE_USED void timer_isr(void);
3133
ATTRIBUTE_USED void main_x(void);
@@ -38,7 +40,7 @@ void main_x(void)
3840
// Move the core initialization functions into main_init().
3941
main_init(ActiveCore);
4042

41-
if (ActiveCore == UINT32_C(0)) { (void) main(); }
43+
if (ActiveCore == UINT32_C(0)) { main_core0_init(); (void) main(); }
4244
else if(ActiveCore == UINT32_C(1)) { main_core1(); }
4345
else if(ActiveCore == UINT32_C(2)) { main_core2(); }
4446
else if(ActiveCore == UINT32_C(3)) { main_core3(); }
@@ -88,8 +90,7 @@ static void main_init(const uint32_t ActiveCore)
8890
pGICR->CORE[ActiveCore].SGI_PPI.ICFGR0 &= ~(uint32_t)(1 << ((29 - 16) * 2)); // clear bit to set level-triggered
8991

9092
/* enable global interrupt */
91-
arch_enable_ints();
92-
arch_enable_fiqs();
93+
mcal_irq_enable_all();
9394

9495
/* start the timer */
9596
ARM64_WRITE_SYSREG(CNTPS_TVAL_EL1, UINT64_C(0x0BEBC200));

ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main_cores.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
#include <mcal_cpu.h>
99
#include <mcal_led.h>
10+
#include <mcal_osc.h>
11+
#include <mcal_port.h>
12+
#include <mcal_wdg.h>
1013

1114
#include <util/utility/util_time.h>
1215

@@ -20,26 +23,30 @@ namespace local
2023
extern "C" auto main_core1(void) -> void;
2124
extern "C" auto main_core2(void) -> void;
2225
extern "C" auto main_core3(void) -> void;
26+
extern "C" auto main_core0_init(void) -> void;
2327

2428
extern "C" auto main_core1(void) -> void { local::main_core_worker(mcal::led::led1()); }
2529
extern "C" auto main_core2(void) -> void { local::main_core_worker(mcal::led::led2()); }
2630
extern "C" auto main_core3(void) -> void { local::main_core_worker(mcal::led::led3()); }
2731

32+
extern "C" auto main_core0_init(void) -> void
33+
{
34+
mcal::wdg::init (nullptr);
35+
mcal::port::init(nullptr);
36+
mcal::osc::init (nullptr);
37+
}
38+
2839
static auto local::main_core_worker(mcal::led::led_base& my_led) -> void
2940
{
3041
using local_timer_type = util::timer<std::uint64_t>;
3142
using local_tick_type = typename local_timer_type::tick_type;
3243

33-
local_timer_type led_timer(local_timer_type::seconds(local_tick_type { UINT8_C(1) }));
34-
3544
my_led.toggle();
3645

3746
for(;;)
3847
{
39-
while(!led_timer.timeout()) { mcal::cpu::nop(); }
48+
local_timer_type::blocking_delay(local_timer_type::seconds(local_tick_type { UINT8_C(1) }));
4049

4150
my_led.toggle();
42-
43-
led_timer.start_interval(local_timer_type::seconds(local_tick_type { UINT8_C(1) }));
4451
}
4552
}
Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,91 @@
1-
#ifndef _CORE_MACROS_H
2-
#define _CORE_MACROS_H
1+
#ifndef CORE_MACROS_2025_07_28_H
2+
#define CORE_MACROS_2025_07_28_H
33

4-
#if defined(__GNUC__)
5-
#pragma GCC system_header
6-
#endif
4+
#if defined(__GNUC__)
5+
#pragma GCC system_header
6+
#endif
77

8-
#include <stdint.h>
9-
#include <stdbool.h>
8+
#if defined(__cplusplus)
109

11-
#define DSB __asm__ volatile("dsb sy" ::: "memory")
12-
#define ISB __asm__ volatile("isb" ::: "memory")
10+
#include <cstdint>
1311

14-
#define STRINGIFY(x) #x
15-
#define TOSTRING(x) STRINGIFY(x)
12+
extern "C"
13+
{
1614

17-
#define ARM64_READ_SYSREG(reg) \
18-
({ \
15+
#else
16+
17+
#include <stdint.h>
18+
#include <stdbool.h>
19+
20+
#endif
21+
22+
#define DSB __asm__ volatile("dsb sy" ::: "memory")
23+
#define ISB __asm__ volatile("isb" ::: "memory")
24+
25+
#define STRINGIFY(x) #x
26+
#define TOSTRING(x) STRINGIFY(x)
27+
28+
#define ARM64_READ_SYSREG(reg) \
29+
({ \
1930
uint64_t _val; \
2031
__asm__ volatile("mrs %0," TOSTRING(reg) : "=r" (_val)); \
2132
_val; \
22-
})
33+
})
2334

24-
#define ARM64_WRITE_SYSREG(reg, val) \
25-
({ \
35+
#define ARM64_WRITE_SYSREG(reg, val) \
36+
({ \
2637
__asm__ volatile("msr " TOSTRING(reg) ", %0" :: "r" (val)); \
2738
ISB; \
28-
})
39+
})
2940

30-
#define CF do { __asm__ volatile("" ::: "memory"); } while(0)
41+
#define CF do { __asm__ volatile("" ::: "memory"); } while(0)
3142

32-
static inline void arch_enable_ints(void) {
43+
static inline void arch_enable_ints(void)
44+
{
3345
CF;
3446
__asm__ volatile("msr daifclr, #2" ::: "memory");
35-
}
47+
}
3648

37-
static inline void arch_disable_ints(void) {
49+
static inline void arch_disable_ints(void)
50+
{
3851
__asm__ volatile("msr daifset, #2" ::: "memory");
3952
CF;
40-
}
53+
}
4154

42-
static inline bool arch_ints_disabled(void) {
55+
static inline bool arch_ints_disabled(void)
56+
{
4357
unsigned long state;
4458

4559
__asm__ volatile("mrs %0, daif" : "=r"(state));
4660
state &= (1<<7);
4761

4862
return !!state;
49-
}
63+
}
5064

51-
static inline void arch_enable_fiqs(void) {
65+
static inline void arch_enable_fiqs(void)
66+
{
5267
CF;
5368
__asm__ volatile("msr daifclr, #1" ::: "memory");
54-
}
69+
}
5570

56-
static inline void arch_disable_fiqs(void) {
71+
static inline void arch_disable_fiqs(void)
72+
{
5773
__asm__ volatile("msr daifset, #1" ::: "memory");
5874
CF;
59-
}
75+
}
6076

61-
static inline bool arch_fiqs_disabled(void) {
77+
static inline bool arch_fiqs_disabled(void)
78+
{
6279
unsigned long state;
6380

6481
__asm__ volatile("mrs %0, daif" : "=r"(state));
6582
state &= (1<<6);
6683

6784
return !!state;
68-
}
69-
85+
}
7086

87+
#if defined(__cplusplus)
88+
}
89+
#endif
7190

72-
#endif /*_CORE_MACROS_H*/
91+
#endif // CORE_MACROS_2025_07_28_H

0 commit comments

Comments
 (0)