Skip to content

Commit e2f1330

Browse files
committed
test(port_arm_m): support benchmark tests on RP2040
The measured cycle counts are somewhat higher than those of `nucleo_f401re` (Cortex-M4F) by about 10%.
1 parent a869c0d commit e2f1330

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

src/r3_port_arm_m_test_driver/src/board_rp2040.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub mod mux {
1111
pub const BEGIN_LOG: &str = "\x172";
1212
}
1313

14+
pub const SYSTICK_FREQUENCY: u64 = 48_000_000;
15+
1416
#[panic_handler]
1517
fn panic(info: &PanicInfo) -> ! {
1618
// Disable IRQ
@@ -29,6 +31,12 @@ pub fn enter_poll_loop() -> ! {
2931
}
3032
}
3133

34+
/// Implements `kernel_benchmarks::Driver::performance_time`.
35+
pub fn performance_time() -> u32 {
36+
let timerawl = unsafe { (0x40054028 as *const u32).read_volatile() };
37+
timerawl.wrapping_mul(2) // scale by `tick.cycles`
38+
}
39+
3240
struct Logger;
3341

3442
impl log::Log for Logger {
@@ -69,6 +77,22 @@ pub const fn configure<System: Kernel>(b: &mut CfgBuilder<System>) {
6977
&p.WATCHDOG,
7078
);
7179

80+
// clk_ref → clk_sys = 48MHz
81+
p.CLOCKS.clk_sys_ctrl.modify(|_, w| w.src().clk_ref());
82+
83+
// Supply clk_ref / 2 = 24MHz to SysTick, watchdog, and timer
84+
// because we want to measure times at high precision in
85+
// benchmarks. Setting `cycles = 1` would be ideal but doesn't work
86+
// for some reason.
87+
p.WATCHDOG
88+
.tick
89+
.write(|b| unsafe { b.cycles().bits(2).enable().set_bit() });
90+
91+
// Reset the timer used by `performance_time`
92+
p.RESETS.reset.modify(|_, w| w.timer().set_bit());
93+
p.RESETS.reset.modify(|_, w| w.timer().clear_bit());
94+
while p.RESETS.reset_done.read().timer().bit_is_clear() {}
95+
7296
// Reset and enable IO bank 0
7397
p.RESETS
7498
.reset

src/r3_port_arm_m_test_driver/src/main.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,12 @@ macro_rules! instantiate_test {
7373
}
7474

7575
impl port::SysTickOptions for System {
76+
#[cfg(feature = "board-rp_pico")]
77+
const FREQUENCY: u64 = board_rp2040::SYSTICK_FREQUENCY;
78+
7679
// STM32F401
7780
// SysTick = AHB/8, AHB = HSI (internal 16-MHz RC oscillator)
81+
#[cfg(not(feature = "board-rp_pico"))]
7882
const FREQUENCY: u64 = 2_000_000;
7983
}
8084

@@ -88,10 +92,17 @@ macro_rules! instantiate_test {
8892
fn success() {
8993
report_success();
9094
}
95+
96+
#[cfg(not(feature = "board-rp_pico"))]
9197
fn performance_time() -> u32 {
9298
cortex_m::peripheral::DWT::get_cycle_count()
9399
}
94100

101+
#[cfg(feature = "board-rp_pico")]
102+
fn performance_time() -> u32 {
103+
board_rp2040::performance_time()
104+
}
105+
95106
const PERFORMANCE_TIME_UNIT: &'static str = "cycle(s)";
96107

97108
// Most targets should have at least four interrupt lines
@@ -125,6 +136,7 @@ macro_rules! instantiate_test {
125136
const fn configure_app(b: &mut CfgBuilder<System>) -> test_case::App<System> {
126137
// Configure DWT for performance measurement
127138
#[cfg(feature = "kernel_benchmarks")]
139+
#[cfg(not(feature = "board-rp_pico"))]
128140
StartupHook::<System>::build().start(|_| {
129141
unsafe {
130142
let mut peripherals = cortex_m::peripheral::Peripherals::steal();

0 commit comments

Comments
 (0)