Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
rtic_f4xx_nucleo
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Per Lindgren
rtic_f4xx_nucleo
Commits
13682e44
Commit
13682e44
authored
4 years ago
by
Per Lindgren
Browse files
Options
Downloads
Patches
Plain Diff
timing_task
parent
98208c34
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
examples/timing_resources.rs
+122
-0
122 additions, 0 deletions
examples/timing_resources.rs
examples/timing_task.rs
+120
-0
120 additions, 0 deletions
examples/timing_task.rs
src/main.rs
+2
-20
2 additions, 20 deletions
src/main.rs
with
244 additions
and
20 deletions
examples/timing_resources.rs
0 → 100644
+
122
−
0
View file @
13682e44
//! examples/timing_resources.rs
// #![deny(unsafe_code)]
// #![deny(warnings)]
#![no_main]
#![no_std]
use
core
::
ptr
::
read_volatile
;
use
cortex_m
::{
asm
,
peripheral
::
DWT
};
use
panic_halt
as
_
;
use
stm32f4
::
stm32f411
;
#[rtic::app(device
=
stm32f411)]
const
APP
:
()
=
{
struct
Resources
{
// A resource
dwt
:
DWT
,
}
#[init]
fn
init
(
mut
cx
:
init
::
Context
)
->
init
::
LateResources
{
// Initialize (enable) the monotonic timer (CYCCNT)
cx
.core.DCB
.enable_trace
();
cx
.core.DWT
.enable_cycle_counter
();
init
::
LateResources
{
dwt
:
cx
.core.DWT
}
}
#[idle(resources
=
[
dwt]
)]
fn
idle
(
mut
cx
:
idle
::
Context
)
->
!
{
unsafe
{
cx
.resources.dwt.cyccnt
.write
(
0
)
};
asm
::
bkpt
();
rtic
::
pend
(
stm32f411
::
Interrupt
::
EXTI0
);
asm
::
bkpt
();
loop
{
continue
;
}
}
#[task(binds
=
EXTI0)]
fn
exti0
(
_cx
:
exti0
::
Context
)
{
asm
::
bkpt
();
}
};
// Now we are going to have a look at the scheduling of RTIC tasks
//
// First create an objdump file:
// > cargo objdump --example timing_resources --release --features nightly -- --disassemble > timing_resources.objdump
//
// Lookup the EXTI0 symbol (RTIC binds the exti0 task to the interrupt vector).
//
// You should find something like:
//
// 08000232 <EXTI0>:
// 8000232: 00 be bkpt #0
// 8000234: 00 20 movs r0, #0
// 8000236: 80 f3 11 88 msr basepri, r0
// 800023a: 70 47 bx lr
//
// The application triggers the `exti0` task from `idle`, let's see
// how that pans out.
//
// > cargo run --example timing_resources --release --features nightly
// Then continue to the first breakpoint instruction:
// (gdb) c
// timing_resources::idle (cx=...) at examples/timing_resources.rs:32
// 32 asm::bkpt();
//
// (gdb) x 0xe0001004
// 0
//
// Here we see, that we have successfully set the cycle counter to zero.
// The `rtic::pend(stm32f411::Interrupt::EXTI0)` "emulates" the
// arrival/triggering of an external interrupt associated with
// the `exti0` task.
//
// (gdb) c
// timing_resources::APP::EXTI0 () at examples/timing_resources.rs:13
// 13 #[rtic::app(device = stm32f411)]
//
// Since `exti0` has a default prio = 1, it will preempt `idle` (at prio = 0),
// and the debugger breaks in the `exti0` task.
//
// (gdb) x 0xe0001004
//
// [Your answer here]
//
// (gdb) disassemble
//
// [Your answer here]
//
// You should see that we hit the breakpoint in `exti0`, and
// that the code complies to the objdump EXTI disassembly.
//
// Confer to the document:
// https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/beginner-guide-on-interrupt-latency-and-interrupt-latency-of-the-arm-cortex-m-processors
//
// What was the software latency observed to enter the task?
//
// [Your answer here]
//
// Does RTIC infer any overhead?
//
// [Your answer here]
//
// Now we can continue to measure the round trip time.
//
// (gdb) c
// timing_resources::idle (cx=...) at examples/timing_resources.rs:34
// 34 asm::bkpt();
//
// (gdb) x 0xe0001004
//
// [Your answer here]
//
// Looking at the EXTI0 (exti0) code, we see two additional
// instructions used to restore the BASEPRI register.
// This OH will be removed in next release of RTIC.
// So we can conclude RTIC to have a 2-cycle OH (in this case).
// (In the general case, as we will see later restoring BASEPRI
// is actually necessary so its just this corner case that is
// sub-optimal.)
This diff is collapsed.
Click to expand it.
examples/timing_task.rs
0 → 100644
+
120
−
0
View file @
13682e44
//! examples/timing_task.rs
#![deny(warnings)]
#![no_main]
#![no_std]
use
cortex_m
::{
asm
,
peripheral
::
DWT
};
use
panic_halt
as
_
;
use
stm32f4
::
stm32f411
;
#[rtic::app(device
=
stm32f411)]
const
APP
:
()
=
{
struct
Resources
{
dwt
:
DWT
,
}
#[init]
fn
init
(
mut
cx
:
init
::
Context
)
->
init
::
LateResources
{
// Initialize (enable) the monotonic timer (CYCCNT)
cx
.core.DCB
.enable_trace
();
cx
.core.DWT
.enable_cycle_counter
();
init
::
LateResources
{
dwt
:
cx
.core.DWT
}
}
#[idle(resources
=
[
dwt]
)]
fn
idle
(
cx
:
idle
::
Context
)
->
!
{
unsafe
{
cx
.resources.dwt.cyccnt
.write
(
0
)
};
asm
::
bkpt
();
rtic
::
pend
(
stm32f411
::
Interrupt
::
EXTI0
);
asm
::
bkpt
();
loop
{
continue
;
}
}
#[task(binds
=
EXTI0)]
fn
exti0
(
_cx
:
exti0
::
Context
)
{
asm
::
bkpt
();
}
};
// Now we are going to have a look at the scheduling of RTIC tasks
//
// First create an objdump file:
// > cargo objdump --example timing_task --release --features nightly -- --disassemble > timing_task.objdump
//
// Lookup the EXTI0 symbol (RTIC binds the exti0 task to the interrupt vector).
//
// You should find something like:
//
// 08000232 <EXTI0>:
// 8000232: 00 be bkpt #0
// 8000234: 00 20 movs r0, #0
// 8000236: 80 f3 11 88 msr basepri, r0
// 800023a: 70 47 bx lr
//
// The application triggers the `exti0` task from `idle`, let's see
// how that pans out.
//
// > cargo run --example timing_task --release --features nightly
// Then continue to the first breakpoint instruction:
// (gdb) c
// timing_task::idle (cx=...) at examples/timing_task.rs:28
// 28 asm::bkpt();
//
// (gdb) x 0xe0001004
// 0
//
// Here we see, that we have successfully set the cycle counter to zero.
// The `rtic::pend(stm32f411::Interrupt::EXTI0)` "emulates" the
// arrival/triggering of an external interrupt associated with
// the `exti0` task.
//
// (gdb) c
// timing_task::APP::EXTI0 () at examples/timing_task.rs:11
// 11 #[rtic::app(device = stm32f411)]
//
// Since `exti0` has a default prio = 1, it will preempt `idle` (at prio = 0),
// and the debugger breaks in the `exti0` task.
// (Notice, RTIC translates logical priorities to hw priorities for you.)
//
// (gdb) x 0xe0001004
//
// [Your answer here]
//
// (gdb) disassemble
//
// [Your answer here]
//
// You should see that we hit the breakpoint in `exti0`, and
// that the code complies to the objdump EXTI disassembly.
//
// Confer to the document:
// https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/beginner-guide-on-interrupt-latency-and-interrupt-latency-of-the-arm-cortex-m-processors
//
// What was the software latency observed to enter the task?
//
// [Your answer here]
//
// Does RTIC infer any overhead for launching the task?
//
// [Your answer here]
//
// Now we can continue to measure the round trip time.
//
// (gdb) c
// timing_resources::idle (cx=...) at examples/timing_resources.rs:34
// 34 asm::bkpt();
//
// (gdb) x 0xe0001004
//
// [Your answer here]
//
// Looking at the EXTI0 (exti0) code, we see two additional
// instructions used to restore the BASEPRI register.
// This OH will be removed in next release of RTIC.
// So we can conclude RTIC to have a 2-cycle OH (in this case).
// (In the general case, as we will see later restoring BASEPRI
// is actually necessary so its just this corner case that is
// sub-optimal.)
This diff is collapsed.
Click to expand it.
src/main.rs
+
2
−
20
View file @
13682e44
...
...
@@ -15,37 +15,19 @@ use stm32f4;
#[rtic::app(device
=
stm32f4)]
const
APP
:
()
=
{
#[init]
fn
init
(
cx
:
init
::
Context
)
{
// Cortex-M peripherals
let
_core
:
cortex_m
::
Peripherals
=
cx
.core
;
fn
init
(
_cx
:
init
::
Context
)
{
// Device specific peripherals
// let _device: lm3s6965::Peripherals = cx.device;
// // Safe access to local `static mut` variable
// let _x: &'static mut u32 = X;
rtt_init_print!
();
rprintln!
(
"init"
);
}
#[idle]
fn
idle
(
_cx
:
idle
::
Context
)
->
!
{
// // static mut X: u32 = 0;
// // // Cortex-M peripherals
// // let _core: cortex_m::Peripherals = cx.core;
// // // Device specific peripherals
// // // let _device: lm3s6965::Peripherals = cx.device;
// // // Safe access to local `static mut` variable
// // let _x: &'static mut u32 = X;
rprintln!
(
"idle"
);
panic!
(
"panic"
);
loop
{
continue
;
// cortex_m::asm::wfi(); // does not work for some reason
}
}
};
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment