Skip to content

Commit

Permalink
Add test for unwinding in interrupt handler.
Browse files Browse the repository at this point in the history
  • Loading branch information
zyma98 committed Aug 16, 2024
1 parent 47c80ca commit 55b7733
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .github/workflows/actions/build/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,12 @@ runs:
category: sync
sub-category: channel
test-name: concurrency_and_stress

# *** Tests for interrupt - unwind ***

- name: Build test test-interrupt-unwind-simple
uses: ./.github/workflows/actions/build-test
with:
category: interrupt
sub-category: unwind
test-name: simple
25 changes: 25 additions & 0 deletions .github/workflows/interrupt-unwind.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Run Tests for Interrupt Unwinding

on:
workflow_call:
secrets:
cookie:
required: true

env:
CARGO_TERM_COLOR: always

jobs:
simple:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run test simple
uses: ./.github/workflows/actions/run-test
with:
cookie: ${{ secrets.cookie }}
category: interrupt
sub-category: unwind
test-name: simple
16 changes: 16 additions & 0 deletions .github/workflows/interrupt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Run Tests for Interrupt

on:
workflow_call:
secrets:
cookie:
required: true

env:
CARGO_TERM_COLOR: always

jobs:
unwind:
uses: ./.github/workflows/unwind.yaml
secrets:
cookie: ${{ secrets.cookie }}
File renamed without changes.
2 changes: 1 addition & 1 deletion .github/workflows/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
cookie: ${{ secrets.cookie }}

unwind:
uses: ./.github/workflows/unwind.yaml
uses: ./.github/workflows/task-unwind.yaml
secrets:
cookie: ${{ secrets.cookie }}

Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ jobs:
uses: ./.github/workflows/task.yaml
secrets:
cookie: ${{ secrets.cookie }}

interrupt:
uses: ./.github/workflows/interrupt.yaml
secrets:
cookie: ${{ secrets.cookie }}
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,9 @@ path = "examples/tests/task/segmented_stack/function_arguments.rs"
[[example]]
name = "test-task-segmented_stack-return_values"
path = "examples/tests/task/segmented_stack/return_values.rs"

# *** Tests for interrupt - unwind ***

[[example]]
name = "test-interrupt-unwind-simple"
path = "examples/tests/interrupt/unwind/simple.rs"
77 changes: 77 additions & 0 deletions examples/tests/interrupt/unwind/simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//!
#![no_main]
#![no_std]
#![feature(naked_functions)]

extern crate alloc;

use core::sync::atomic::{AtomicUsize, Ordering};
use hopter::{
boot::main,
debug::semihosting,
hprintln,
interrupt::handler,
sync::{AllIrqExceptSvc, MutexIrqSafe},
};
use stm32f4xx_hal::{
pac::{Interrupt, Peripherals, TIM2},
prelude::*,
timer::{CounterUs, Event},
};

static TIMER: MutexIrqSafe<Option<CounterUs<TIM2>>, AllIrqExceptSvc> = MutexIrqSafe::new(None);

#[main]
fn main(_cp: cortex_m::Peripherals) {
let dp = Peripherals::take().unwrap();

// For unknown reason QEMU accepts only the following clock frequency.
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(16.MHz()).pclk1(8.MHz()).freeze();

let mut timer = dp.TIM2.counter(&clocks);

// Generate an interrupt when the timer expires.
timer.listen(Event::Update);

// Enable TIM2 interrupt.
unsafe {
cortex_m::peripheral::NVIC::unmask(Interrupt::TIM2);
}

// Set the timer to expire every 1 second.
// Empirically when set to 62 seconds the interval is actually
// approximately 1 second. Weird QEMU.
timer.start(62.secs()).unwrap();

// Move the timer into the global storage to prevent it from being dropped.
*TIMER.lock() = Some(timer);
}

/// Get invoked approximately every 1 second.
#[handler(TIM2)]
extern "C" fn tim2_handler() {
static IRQ_CNT: AtomicUsize = AtomicUsize::new(0);
let prev_cnt = IRQ_CNT.fetch_add(1, Ordering::SeqCst);

let _print_on_drop = PrintOnDrop("Resource released");

if prev_cnt % 2 == 0 {
panic!();
}

hprintln!("TIM2 IRQ count {}", prev_cnt);

if prev_cnt >= 5 {
semihosting::terminate(true);
}
}

struct PrintOnDrop(&'static str);

impl Drop for PrintOnDrop {
fn drop(&mut self) {
hprintln!("{}", self.0);
}
}
8 changes: 8 additions & 0 deletions examples/tests/interrupt/unwind/simple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Resource released
TIM2 IRQ count 1
Resource released
Resource released
TIM2 IRQ count 3
Resource released
Resource released
TIM2 IRQ count 5

0 comments on commit 55b7733

Please sign in to comment.