Skip to content
Snippets Groups Projects
Commit b83af360 authored by Per Lindgren's avatar Per Lindgren
Browse files

bare1

parent 5b681bee
No related branches found
No related tags found
No related merge requests found
...@@ -226,6 +226,64 @@ ...@@ -226,6 +226,64 @@
], ],
"cwd": "${workspaceRoot}" "cwd": "${workspaceRoot}"
}, },
{
"type": "cortex-debug",
"request": "launch",
"servertype": "openocd",
"name": "bare2 (debug)",
"preLaunchTask": "cargo build --example bare2",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare2",
"postLaunchCommands": [
"monitor arm semihosting enable"
],
"swoConfig": {
"enabled": true,
"cpuFrequency": 16000000,
"swoFrequency": 2000000,
"source": "probe",
"decoders": [
{
"type": "console",
"label": "ITM",
"port": 0
}
]
},
"configFiles": [
"interface/stlink.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
},
{
"type": "cortex-debug",
"request": "launch",
"servertype": "openocd",
"name": "bare2 (release)",
"preLaunchTask": "cargo build --example bare2",
"executable": "./target/thumbv7em-none-eabihf/release/examples/bare2",
"postLaunchCommands": [
"monitor arm semihosting enable"
],
"swoConfig": {
"enabled": true,
"cpuFrequency": 16000000,
"swoFrequency": 2000000,
"source": "probe",
"decoders": [
{
"type": "console",
"label": "ITM",
"port": 0
}
]
},
"configFiles": [
"interface/stlink.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
},
{ {
"type": "cortex-debug", "type": "cortex-debug",
"request": "launch", "request": "launch",
......
...@@ -111,5 +111,29 @@ ...@@ -111,5 +111,29 @@
"isDefault": true "isDefault": true
} }
}, },
{
"type": "shell",
"label": "cargo build --example bare2",
"command": "cargo build --example bare2",
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "shell",
"label": "cargo build --example bare2 --release",
"command": "cargo build --example bare2 --release",
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
] ]
} }
\ No newline at end of file
//! bare1.rs
//!
//! Tracing and assembly code
//!
//! What it covers
//! - tracing over semihosting and ITM
//! - assembly calls and inline assembly
//! - more on arithmetics
//! ---
#![no_main]
#![no_std]
extern crate panic_halt;
use cortex_m::{iprintln, Peripherals};
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
#[entry]
fn main() -> ! {
let mut p = Peripherals::take().unwrap();
let stim = &mut p.ITM.stim[0];
let mut x = 27;
iprintln!(stim, "x = {:?}", x);
hprintln!("x = {:?}", x).unwrap();
loop {
x += 1;
cortex_m::asm::nop();
cortex_m::asm::bkpt();
x -= 1;
}
}
// 0. Setup
// For this example we will use the `nightly` compiler
// to get true inline assembly.
//
// > rustup override set nightly
//
// You may need/want to install addititonal components also),
// to that end look at the install section in the README.md.
// If you change toolchain, exit and re-start `vscode`.
//
// 1. Build and run the application
// Look at the `hello.rs` and `itm.rs` examples to setup the tracing.
//
// When debugging the application it should get stuck in the
// loop, (press pause/suspend to verify this).
// what is the output in the ITM console
//
// ** your answer here **
//
// What is the output in the semihosting (openocd) console
// ** your answer here **
//
// commit your answers (bare1_1)
//
// 2. Inspecting the generated assembly code
// If in `vcsode` the gdb console in DEBUG CONSOLE
// What is the output of:
// (gdb) disassemble
//
// ** your answer here **
//
// commit your answers (bare1_2)
//
// 3. Now remove the comment for `cortex_m::asm::nop()`.
// Rebuild and debug, pause the program.
// What is the output of:
// (gdb) disassemble
//
// ** your answer here **
//
// commit your answers (bare1_3)
//
// 4. Now remove the comment for `cortex_m::asm::bkpt()`
// Rebuild and debug, let the program run until it halts.
// What is the output of:
// (gdb) disassemble
//
// ** your answer here **
//
// commit your answers (bare1_4)
//
// 5. Release mode (optimized builds).
// Rebuild `bare1.rs` in release (optimized mode).
// Compare the generated assembly for the loop
// between the dev (unoptimized) and release (optimized) build.
//
// ** your answer here **
//
// commit your answers (bare1_5)
//
// Tips: The optimized build should have some 8 instructions
// while the debug (dev) build should have > 20 instructions
// (both counting the inner loop only). The debug build
// should have additional code that call panic if the additon
// wraps (and in such case call panic).
//
// Discussion:
// In release (optimized) mode the addition is unchecked,
// so there is a semantic difference here in between
// the dev and release modes. This is motivited by:
// 1) efficiency, unchecked is faster
// 2) convenience, it would be inconvenient to explicitly use
// wrapping arithmetics, and wrapping is what the programmer
// typically would expect in any case. So the check
// in dev/debug mode is just there for some extra safety
// if your intention is NON-wrapping arithmetics.
//
// 6. *Optional
// You can pass additional flags to the Rust `rustc` compiler.
//
// `-Z force-overflow-checks=off`
//
// Under this flag, code is never generated for oveflow checking.
// You can enable this flag (uncomment the corresponding flag in
// the `.cargo/config` file.)
//
// What is now the disassembly of the loop:
//
// ** your answer here **
//
// commit your answers (bare1_6)
//
// Now restore the `.cargo/config` to its original state.
//
// 7. *Optional
// There is another way to conveniently use wrapping arithmetics
// without passing flags to the compiler.
//
// https://doc.rust-lang.org/std/num/struct.Wrapping.html
//
// Rewrite the code using this approach.
//
// What is now the disassembly of the code in dev mode?
//
// ** your answer here **
//
// What is now the disassembly of the code in release mode?
//
// ** your answer here **
//
// commit your answers (bare1_7)
//
// Final discussion:
//
// Embedded code typically is performance sensitve, hence
// it is important to understand how code is generated
// to achieve efficient implementations.
//
// Moreover, arithmetics are key to processing of data,
// so its important that we are in control over the
// computations. E.g. comupting checksums, hashes, cryptos etc.
// all require precise control over wrapping vs. overflow behaviour.
//
// If you write a library depending on wrapping arithmetics
// do NOT rely on a compiler flag. (The end user might compile
// it without this flag enabled, and thus get erronous results.)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment