Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
E
e7020e_2021
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
Carl Österberg
e7020e_2021
Commits
c391ea71
Commit
c391ea71
authored
4 years ago
by
Per Lindgren
Browse files
Options
Downloads
Patches
Plain Diff
updated rtic_bare7
parent
01e7f9f8
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
examples/rtic_bare7.rs
+90
-21
90 additions, 21 deletions
examples/rtic_bare7.rs
with
90 additions
and
21 deletions
examples/rtic_bare7.rs
+
90
−
21
View file @
c391ea71
//! rtic_bare7.rs
//! rtic_bare7.rs
//!
//!
//!
Clocking
//!
HAL OutputPin abstractions
//!
//!
//! What it covers:
//! What it covers:
//! - using embedded hal, and the OutputPin abstraction
//! - using embedded hal, and the OutputPin abstraction
#![no_main]
#![no_std]
use
panic_rtt_target
as
_
;
use
panic_rtt_target
as
_
;
use
rtic
::
cyccnt
::{
Instant
,
U32Ext
as
_
};
use
rtic
::
cyccnt
::{
Instant
,
U32Ext
as
_
};
use
rtt_target
::{
rprintln
,
rtt_init_print
};
use
rtt_target
::{
rprintln
,
rtt_init_print
};
use
stm32f4xx_hal
::
stm32
;
use
stm32f4xx_hal
::
stm32
;
use
stm32f4xx_hal
::{
gpio
::{
gpioa
::
PA5
,
Output
,
PushPull
},
prelude
::
*
,
};
use
core
::
convert
::
Infallible
;
use
embedded_hal
::
digital
::
v2
::{
OutputPin
,
ToggleableOutputPin
};
const
OFFSET
:
u32
=
8_000_000
;
const
OFFSET
:
u32
=
8_000_000
;
#[rtic::app(device
=
stm32f4xx_hal::stm32,
monotonic
=
rtic::cyccnt::CYCCNT,
peripherals
=
true
)]
#[rtic::app(device
=
stm32f4xx_hal::stm32,
monotonic
=
rtic::cyccnt::CYCCNT,
peripherals
=
true
)]
...
@@ -17,6 +28,7 @@ const APP: () = {
...
@@ -17,6 +28,7 @@ const APP: () = {
struct
Resources
{
struct
Resources
{
// late resources
// late resources
GPIOA
:
stm32
::
GPIOA
,
GPIOA
:
stm32
::
GPIOA
,
// led: PA5<Output<PushPull>>,
}
}
#[init(schedule
=
[
toggle]
)]
#[init(schedule
=
[
toggle]
)]
fn
init
(
cx
:
init
::
Context
)
->
init
::
LateResources
{
fn
init
(
cx
:
init
::
Context
)
->
init
::
LateResources
{
...
@@ -76,23 +88,38 @@ const APP: () = {
...
@@ -76,23 +88,38 @@ const APP: () = {
}
}
};
};
fn
_toggle_generic
(
led
:
&
mut
dyn
OutputPin
<
Error
=
Infallible
>
,
toggle
:
&
mut
bool
)
{
if
*
toggle
{
led
.set_high
()
.ok
();
}
else
{
led
.set_low
()
.ok
();
}
*
toggle
=
!*
toggle
;
}
fn
_toggleable_generic
(
led
:
&
mut
dyn
ToggleableOutputPin
<
Error
=
Infallible
>
)
{
led
.toggle
()
.ok
();
}
// 1. In this example you will use RTT.
// 1. In this example you will use RTT.
//
//
// > cargo run --example rtic_bare7
// > cargo run --example rtic_bare7
//
//
//
Now l
ook
at
the documentation for `
embedded_hal::digital::v2::OutputPin
`.
//
L
ook
in
the
generated
documentation for `
set_high`/`set_low
`.
// (You created documentation for your dependencies in previous exercise
// (You created documentation for your dependencies in previous exercise
// so you can just search (press `S`) for `OutputPin`).
// so you can just search (press `S`) for `OutputPin`).
// You will find that these methods are implemented for `Output` pins.
//
//
// You see that the OutputPin trait defines `set_low`/`set_high` functions.
// Now change your code to use these functions instead of the low-level GPIO API.
// Your task is to alter the code to use the `set_low`/`set_high` API.
//
//
// HINTS:
// HINTS:
// - A GPIOx peripheral can be `split` into individual PINs Px0..Px15).
// - A GPIOx peripheral can be `split` into individual PINs Px0..Px15).
// - A Pxy, can be turned into an `Output` by `into_push_pull_output`.
// - A Pxy, can be turned into an `Output` by `into_push_pull_output`.
// - You may optionally set other pin properties as well (such as `speed`).
// - You may optionally set other pin properties as well (such as `speed`).
// - An `Output` pin provides `set_low`/`set_high`
// - An `Output` pin provides `set_low`/`set_high`
// (and implements the `OutputPin` trait in embedded-hal).
// - Instead of passing `GPIO` resource to the `toggle` task pass the
// `led: PA5<Output<PushPull>>` resource instead.
//
//
// Comment your code to explain the steps taken.
// Comment your code to explain the steps taken.
//
//
...
@@ -101,29 +128,71 @@ const APP: () = {
...
@@ -101,29 +128,71 @@ const APP: () = {
//
//
// Commit your code (bare7_1)
// Commit your code (bare7_1)
//
//
// 2.
Optional
// 2.
Further generalizations:
//
//
// Use the `toggle` function instead to further simply your code.
// Now look at the documentation for `embedded_hal::digital::v2::OutputPin`.
//
// You see that the OutputPin trait defines `set_low`/`set_high` functions.
// Your task is to alter the code to use the `set_low`/`set_high` API.
//
//
// Notice:
// The function `_toggle_generic` is generic to any object that
// The `ToggleableOutputPin` abstraction requires `embedded-hal`
// implements the `OutputPin<Error = Infallible>` trait.
// to compiled with the `unproven` feature.
//
//
// The `embedded-hal` traits is mostly used to write drivers
// The type parameter `Error = Infallible` indicates that
// that is hardware agnostic (and thus cross platform).
// there are no errors to be expected (hence infallible).
//
// Our `PA5<Output<PushPull>>` (led) is such an implementor.
// Additionally, `_toggle_generic` takes a mutable reference
// `toggle: &mut bool`, so you need to pass your `TOGGLE` variable.
//
// As you see, `TOGGLE` holds the "state", switching between
// `true` and `false` (to make your led blink).
//
// Change your code into using the `_toggle_generic` function.
// (You may rename it to `toggle_generic` if wished.)
//
// Confirm that your implementation correctly toggles the LED as in
// previous exercise.
//
// Commit your code (bare7_2)
//
// 3. What about the state?
//
// In your code `TOGGLE` holds the "state". However, the underlying
// hardware ALSO holds the state (if the corresponding bit is set/cleared).
//
// What if we can leverage that, and guess what we can!!!!
//
// Look at the documentation for `embedded_hal::digital::v2::ToggleableOutputPin`,
// and the implementation of:
//
// fn _toggleable_generic(led: &mut dyn ToggleableOutputPin<Error = Infallible>) {
// led.toggle().ok();
// }
//
// The latter does not take any state variable, instead it directly `toggle()`
// the `ToggleableOutputPin`.
//
// Now alter your code to leverage on the `_toggleable_generic` function.
// (You should be able to remove the `TOGGLE` state variable altogether.)
//
// Confirm that your implementation correctly toggles the LED as in
// previous exercise.
//
//
// However:
// Commit your code (bare7_3)
// In our case we can use `toggle` directly as implemented by the `stm32f4xx-hal`.
//
//
//
Confirm that your implementation correctly toggles the LED.
//
4. Discussion:
//
//
// Which one do you prefer and why (what problem does it solve)?
// In this exercise you have gone from a very hardware specific implementation,
// to leveraging abstractions (batteries included).
//
//
//
** your answer here **
//
Your final code amounts to "configuration" rather than "coding".
//
//
//
Commit your answer (bare7_2)
//
This reduces the risk of errors (as you let the libraries do the heavy lifting).
//
//
// 3. Discussion
// This also improves code-re use. E.g., if you were to do something less
// trivial then merely toggling you can do that in a generic manner,
// breaking out functionality into "components" re-usable in other applications.
//
//
//
In
th
is
ex
ercise you have learned more on navi
ga
t
in
g the generated documentation
//
Of course
th
e
ex
ample is trivial, you don't
gain
much here, but the principle
//
and to use abstractions to simplify and generalize your code
.
//
is the same behind drivers for USART communication, USB, PMW3389 etc
.
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