Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • student
1 result

Target

Select target project
  • pln/e7020e_2019
  • Henrik/e7020e_2019
  • wijk/e7020e_2019
  • sheepwall/e7020e_2019
  • Tiberg/e7020e_2019
  • Tyllstrom/e7020e_2019
  • Ridgep/e7020e_2019
7 results
Select Git revision
  • nrf52
  • student
2 results
Show changes
Commits on Source (34)
......@@ -59,7 +59,7 @@
"preLaunchTask": "cargo build --example itm",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/itm",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"postLaunchCommands": [
......@@ -89,7 +89,7 @@
"preLaunchTask": "cargo build --example panic",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/panic",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"postLaunchCommands": [
......@@ -119,7 +119,7 @@
"preLaunchTask": "cargo build --example exception_itm --release",
"executable": "./target/thumbv7em-none-eabihf/release/examples/exception_itm",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -145,7 +145,7 @@
"preLaunchTask": "cargo build --example exception_itm_raw",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/exception_itm_raw",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -302,7 +302,7 @@
"preLaunchTask": "cargo build --example bare0",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare0",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -331,7 +331,7 @@
]
},
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -360,7 +360,7 @@
]
},
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -389,7 +389,7 @@
]
},
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -418,7 +418,7 @@
]
},
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -434,7 +434,7 @@
"monitor arm semihosting enable"
],
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -450,7 +450,7 @@
"monitor arm semihosting enable"
],
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -466,7 +466,7 @@
"monitor arm semihosting enable"
],
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -482,7 +482,7 @@
"monitor arm semihosting enable"
],
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"cwd": "${workspaceRoot}"
......@@ -495,7 +495,7 @@
"preLaunchTask": "cargo build --example bare6",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare6",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"postLaunchCommands": [
......@@ -524,7 +524,7 @@
"preLaunchTask": "cargo build --example bare6",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare6",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"postLaunchCommands": [
......@@ -585,7 +585,7 @@
"preLaunchTask": "cargo build --example bare7",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare7",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"postLaunchCommands": [
......@@ -616,7 +616,7 @@
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare7",
// uses local config files
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"postLaunchCommands": [
......@@ -646,7 +646,7 @@
"preLaunchTask": "cargo build --example bare8",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare8",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -673,7 +673,7 @@
"preLaunchTask": "cargo build --example bare9",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare9",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -700,7 +700,7 @@
"preLaunchTask": "cargo build --example bare9 --release",
"executable": "./target/thumbv7em-none-eabihf/release/examples/bare9",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -727,7 +727,7 @@
"preLaunchTask": "cargo build --example bare10 --release",
"executable": "./target/thumbv7em-none-eabihf/release/examples/bare10",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -759,7 +759,7 @@
"preLaunchTask": "cargo build --example bare10",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/bare10",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -791,7 +791,7 @@
"preLaunchTask": "cargo build --example marcus --release",
"executable": "./target/thumbv7em-none-eabihf/release/examples/marcus",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......@@ -823,7 +823,7 @@
"preLaunchTask": "cargo build --example equivalence --release",
"executable": "./target/thumbv7em-none-eabihf/release/examples/equivalence",
"configFiles": [
"interface/stlink.cfg",
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
"swoConfig": {
......
......@@ -28,19 +28,19 @@ optional = true
[dependencies.cortex-m]
version = "0.5.8"
# features = ["inline-asm"] # <- currently requires nightly compiler
features = ["inline-asm"] # <- currently requires nightly compiler
# Uncomment for the allocator example.
# alloc-cortex-m = "0.3.5"
[dependencies.stm32f4]
version = "0.5.0"
version = "0.6.0"
features = ["stm32f413", "rt"]
optional = true
[dependencies.stm32f4xx-hal]
git = "https://github.com/stm32-rs/stm32f4xx-hal.git"
version = "0.2.8"
version = "0.3.0"
features = ["stm32f413", "rt"]
optional = true
......
......@@ -18,26 +18,43 @@ extern crate panic_halt;
// Minimal runtime / startup for Cortex-M microcontrollers
use cortex_m_rt::entry;
use core::cell::UnsafeCell;
struct U32 {
data: UnsafeCell<u32>,
}
// a constant (cannot be changed at run-time)
const X_INIT: u32 = 10;
const X_INIT: u32 = 0xffffffff;
// global mutabale variables (changed using unsafe code)
static mut X: u32 = X_INIT;
static mut Y: u32 = 0;
static X: U32 = U32 {
data: UnsafeCell::new(X_INIT),
};
static Y: U32 = U32 {
data: UnsafeCell::new(0),
};
unsafe impl Sync for U32 {}
#[entry]
fn main() -> ! {
// local mutabale variable (changed in safe code)
let mut x = unsafe { X };
let mut x = read_u32(&X);
loop {
x += 1; // <- place breakpoint here (3)
unsafe {
X += 1;
Y = X;
assert!(x == X && X == Y);
x = x.wrapping_add(1); // <- place breakpoint here (3)
write_u32(&X, read_u32(&X).wrapping_add(1) );
write_u32(&Y, read_u32(&X));
assert!(x == read_u32(&X) && read_u32(&X) == read_u32(&Y) );
}
}
fn read_u32(uint: &U32) -> u32 {
return unsafe{ *uint.data.get()};
}
fn write_u32(write_to: &U32, value: u32) {
unsafe{ *write_to.data.get() = value };
}
// 0. Compile/build the example in debug (dev) mode.
......@@ -48,25 +65,26 @@ fn main() -> ! {
// 1. Run the program in the debugger, let the program run for a while and
// then press pause. Look in the (Local -vscode) Variables view what do you find.
//
// ** your answer here **
// *** x: 962669 ***
//
// In the Expressions (WATCH -vscode) view add X and Y
// what do you find
//
// ** your answer here **
// *** Watch X and Y didn't work, added watch to 'bare0::X::h2583a8be644794f3' and 'bare0::Y::hef3986a5288bec08' to be able to read the variables
// X = 962669, Y = 962668 ***
//
// Step through one complete iteration of the loop
// and see how the (Local) Variables are updated
// can you foresee what will eventually happen?
//
// ** place your answer here **
// *** x is incremented. Eventually x will wrap. ***
//
// Commit your answers (bare0_1)
//
// 2. Alter the constant X_INIT so that `x += 1` directly causes `x` to wrap
// what happens when `x` wraps
//
// ** your answer here **
// ** We end up in the panic handler **
//
// Commit your answers (bare0_2)
//
......@@ -74,10 +92,10 @@ fn main() -> ! {
//
// Change (both) += opertions to use wrapping_add
// load and run the progam, what happens
// ** your answer here **
// ** x value wraps around u32 max 4294967295 and get value 0**
//
// Now continue exectution, what happens
// ** your answer here **
// ** X,Y and x is incremented and wraps around max **
//
// Commit your answers (bare0_3)
//
......@@ -86,7 +104,7 @@ fn main() -> ! {
//
// 4. Change the asserion to `assert!(x == X && X == Y + 1)`, what happens?
//
// ** place your answer here **
// ** The assert fails and we go into panic handler **
//
// Commit your answers (bare0_4)
//
......
......@@ -13,6 +13,10 @@
extern crate panic_halt;
use cortex_m_rt::entry;
use cortex_m::{iprintln, Peripherals};
use cortex_m_semihosting::hprintln;
use core::num::Wrapping;
#[entry]
#[inline(never)]
......@@ -20,13 +24,18 @@ fn main() -> ! {
// Prepend by `x` by _ to avoid warning (never used).
// The compiler is smart enough to figure out that
// `x` is not used in any menaningful way.
//let mut p = Peripherals::take().unwrap();
//let stim = &mut p.ITM.stim[0];
let mut _x = 0;
let mut _x = Wrapping(0u32);
let one = Wrapping(1u32);
loop {
_x += 1;
_x += one;
cortex_m::asm::nop();
//iprintln!(stim, "{}",_x);
//hprintln!("{}", _x).unwrap();
cortex_m::asm::bkpt();
_x -= 1;
_x -= one;
}
}
......@@ -55,10 +64,10 @@ fn main() -> ! {
// loop, (press pause/suspend to verify this).
// what is the output in the ITM console
//
// ** your answer here **
// ** 1 **
//
// What is the output in the semihosting (openocd) console
// ** your answer here **
// ** 1 **
//
// Commit your answers (bare1_1)
//
......@@ -68,7 +77,39 @@ fn main() -> ! {
// What is the output of:
// (gdb) disassemble
//
// ** your answer here **
// ** Dump of assembler code for function main:
// 0x08000400 <+0>: sub sp, #16
// 0x08000402 <+2>: movs r0, #0
// 0x08000404 <+4>: str r0, [sp, #12]
// 0x08000406 <+6>: b.n 0x8000408 <main+8>
// => 0x08000408 <+8>: ldr r0, [sp, #12]
// 0x0800040a <+10>: adds r1, r0, #1
// 0x0800040c <+12>: mov r2, r1
// 0x0800040e <+14>: cmp r1, r0
// 0x08000410 <+16>: str r2, [sp, #8]
// 0x08000412 <+18>: bvs.n 0x800042c <main+44>
// 0x08000414 <+20>: b.n 0x8000416 <main+22>
// 0x08000416 <+22>: ldr r0, [sp, #8]
// 0x08000418 <+24>: str r0, [sp, #12]
// 0x0800041a <+26>: ldr r1, [sp, #12]
// 0x0800041c <+28>: subs r2, r1, #1
// 0x0800041e <+30>: cmp r1, #1
// 0x08000420 <+32>: str r2, [sp, #4]
// 0x08000422 <+34>: bvs.n 0x800043a <main+58>
// 0x08000424 <+36>: b.n 0x8000426 <main+38>
// 0x08000426 <+38>: ldr r0, [sp, #4]
// 0x08000428 <+40>: str r0, [sp, #12]
// 0x0800042a <+42>: b.n 0x8000408 <main+8>
// 0x0800042c <+44>: movw r0, #1964 ; 0x7ac
// 0x08000430 <+48>: movt r0, #2048 ; 0x800
// 0x08000434 <+52>: bl 0x800045c <core::panicking::panic::h4c45e71f0f614f08>
// 0x08000438 <+56>: udf #254 ; 0xfe
// 0x0800043a <+58>: movw r0, #2036 ; 0x7f4
// 0x0800043e <+62>: movt r0, #2048 ; 0x800
// 0x08000442 <+66>: bl 0x800045c <core::panicking::panic::h4c45e71f0f614f08>
// 0x08000446 <+70>: udf #254 ; 0xfe
// End of assembler dump.
// **
//
// Commit your answers (bare1_2)
//
......@@ -78,7 +119,42 @@ fn main() -> ! {
// What is the output of:
// (gdb) disassemble
//
// ** your answer here **
// **
// Dump of assembler code for function main:
// 0x08000404 <+0>: sub sp, #16
// 0x08000406 <+2>: movs r0, #0
// 0x08000408 <+4>: str r0, [sp, #12]
// 0x0800040a <+6>: b.n 0x800040c <main+8>
// 0x0800040c <+8>: ldr r0, [sp, #12]
// => 0x0800040e <+10>: adds r1, r0, #1
// 0x08000410 <+12>: mov r2, r1
// 0x08000412 <+14>: cmp r1, r0
// 0x08000414 <+16>: str r2, [sp, #8]
// 0x08000416 <+18>: bvs.n 0x8000436 <main+50>
// 0x08000418 <+20>: b.n 0x800041a <main+22>
// 0x0800041a <+22>: ldr r0, [sp, #8]
// 0x0800041c <+24>: str r0, [sp, #12]
// 0x0800041e <+26>: bl 0x8000400 <cortex_m::asm::nop::h0ac7b7a3f33f2667>
// 0x08000422 <+30>: b.n 0x8000424 <main+32>
// 0x08000424 <+32>: ldr r0, [sp, #12]
// 0x08000426 <+34>: subs r1, r0, #1
// 0x08000428 <+36>: cmp r0, #1
// 0x0800042a <+38>: str r1, [sp, #4]
// 0x0800042c <+40>: bvs.n 0x8000444 <main+64>
// 0x0800042e <+42>: b.n 0x8000430 <main+44>
// 0x08000430 <+44>: ldr r0, [sp, #4]
// 0x08000432 <+46>: str r0, [sp, #12]
// 0x08000434 <+48>: b.n 0x800040c <main+8>
// 0x08000436 <+50>: movw r0, #1980 ; 0x7bc
// 0x0800043a <+54>: movt r0, #2048 ; 0x800
// 0x0800043e <+58>: bl 0x8000466 <core::panicking::panic::h4c45e71f0f614f08>
// 0x08000442 <+62>: udf #254 ; 0xfe
// 0x08000444 <+64>: movw r0, #2052 ; 0x804
// 0x08000448 <+68>: movt r0, #2048 ; 0x800
// 0x0800044c <+72>: bl 0x8000466 <core::panicking::panic::h4c45e71f0f614f08>
// 0x08000450 <+76>: udf #254 ; 0xfe
// End of assembler dump.
// **
//
// Commit your answers (bare1_3)
//
......@@ -88,7 +164,44 @@ fn main() -> ! {
// What is the output of:
// (gdb) disassemble
//
// ** your answer here **
// **
// Dump of assembler code for function main:
// 0x08000404 <+0>: sub sp, #16
// 0x08000406 <+2>: movs r0, #0
// 0x08000408 <+4>: str r0, [sp, #12]
// 0x0800040a <+6>: b.n 0x800040c <main+8>
// 0x0800040c <+8>: ldr r0, [sp, #12]
// 0x0800040e <+10>: adds r1, r0, #1
// 0x08000410 <+12>: mov r2, r1
// 0x08000412 <+14>: cmp r1, r0
// 0x08000414 <+16>: str r2, [sp, #8]
// 0x08000416 <+18>: bvs.n 0x800043a <main+54>
// 0x08000418 <+20>: b.n 0x800041a <main+22>
// 0x0800041a <+22>: ldr r0, [sp, #8]
// 0x0800041c <+24>: str r0, [sp, #12]
// 0x0800041e <+26>: bl 0x8000400 <cortex_m::asm::nop::h0ac7b7a3f33f2667>
// 0x08000422 <+30>: b.n 0x8000424 <main+32>
// => 0x08000424 <+32>: bkpt 0x0000
// 0x08000426 <+34>: b.n 0x8000428 <main+36>
// 0x08000428 <+36>: ldr r0, [sp, #12]
// 0x0800042a <+38>: subs r1, r0, #1
// 0x0800042c <+40>: cmp r0, #1
// 0x0800042e <+42>: str r1, [sp, #4]
// 0x08000430 <+44>: bvs.n 0x8000448 <main+68>
// 0x08000432 <+46>: b.n 0x8000434 <main+48>
// 0x08000434 <+48>: ldr r0, [sp, #4]
// 0x08000436 <+50>: str r0, [sp, #12]
// 0x08000438 <+52>: b.n 0x800040c <main+8>
// 0x0800043a <+54>: movw r0, #1980 ; 0x7bc
// 0x0800043e <+58>: movt r0, #2048 ; 0x800
// 0x08000442 <+62>: bl 0x800046a <core::panicking::panic::h4c45e71f0f614f08>
// 0x08000446 <+66>: udf #254 ; 0xfe
// 0x08000448 <+68>: movw r0, #2052 ; 0x804
// 0x0800044c <+72>: movt r0, #2048 ; 0x800
// 0x08000450 <+76>: bl 0x800046a <core::panicking::panic::h4c45e71f0f614f08>
// 0x08000454 <+80>: udf #254 ; 0xfe
// End of assembler dump.
// **
//
// Commit your answers (bare1_4)
//
......@@ -101,7 +214,13 @@ fn main() -> ! {
// Compare the generated assembly for the loop
// between the dev (unoptimized) and release (optimized) build.
//
// ** your answer here **
// **
// Dump of assembler code for function main:
// 0x08000400 <+0>: nop
// => 0x08000402 <+2>: bkpt 0x0000
// 0x08000404 <+4>: b.n 0x8000400 <main>
// End of assembler dump.
// **
//
// commit your answers (bare1_5)
//
......@@ -133,7 +252,25 @@ fn main() -> ! {
//
// What is now the disassembly of the loop (in debug mode):
//
// ** your answer here **
// **
// Dump of assembler code for function main:
// 0x08000404 <+0>: sub sp, #8
// 0x08000406 <+2>: movs r0, #0
// 0x08000408 <+4>: str r0, [sp, #4]
// 0x0800040a <+6>: b.n 0x800040c <main+8>
// 0x0800040c <+8>: ldr r0, [sp, #4]
// 0x0800040e <+10>: adds r0, #1
// 0x08000410 <+12>: str r0, [sp, #4]
// 0x08000412 <+14>: bl 0x8000400 <cortex_m::asm::nop::h5c0367e982e73891>
// 0x08000416 <+18>: b.n 0x8000418 <main+20>
// => 0x08000418 <+20>: bkpt 0x0000
// 0x0800041a <+22>: b.n 0x800041c <main+24>
// 0x0800041c <+24>: ldr r0, [sp, #4]
// 0x0800041e <+26>: subs r0, #1
// 0x08000420 <+28>: str r0, [sp, #4]
// 0x08000422 <+30>: b.n 0x800040c <main+8>
// End of assembler dump.
// **
//
// commit your answers (bare1_6)
//
......@@ -149,11 +286,39 @@ fn main() -> ! {
//
// What is now the disassembly of the code in dev mode?
//
// ** your answer here **
// **
// Dump of assembler code for function main:
// 0x080004e4 <+0>: sub sp, #8
// 0x080004e6 <+2>: movs r0, #0
// 0x080004e8 <+4>: str r0, [sp, #0]
// 0x080004ea <+6>: movs r0, #1
// 0x080004ec <+8>: str r0, [sp, #4]
// 0x080004ee <+10>: b.n 0x80004f0 <main+12>
// 0x080004f0 <+12>: ldr r1, [sp, #4]
// 0x080004f2 <+14>: mov r0, sp
// 0x080004f4 <+16>: bl 0x8000490 <core::num::wrapping::_$LT$impl$u20$core..ops..arith..AddAssign$u20$for$u20$core..num..Wrapping$LT$u32$GT$$GT$::add_assign::hbb56dbef6bcfa964>
// 0x080004f8 <+20>: b.n 0x80004fa <main+22>
// 0x080004fa <+22>: bl 0x80004e0 <cortex_m::asm::nop::h0ac7b7a3f33f2667>
// 0x080004fe <+26>: b.n 0x8000500 <main+28>
// => 0x08000500 <+28>: bkpt 0x0000
// 0x08000502 <+30>: b.n 0x8000504 <main+32>
// 0x08000504 <+32>: ldr r1, [sp, #4]
// 0x08000506 <+34>: mov r0, sp
// 0x08000508 <+36>: bl 0x80004b8 <core::num::wrapping::_$LT$impl$u20$core..ops..arith..SubAssign$u20$for$u20$core..num..Wrapping$LT$u32$GT$$GT$::sub_assign::hcf06b8f89372a809>
// 0x0800050c <+40>: b.n 0x800050e <main+42>
// 0x0800050e <+42>: b.n 0x80004f0 <main+12>
// End of assembler dump.
// **
//
// What is now the disassembly of the code in release mode?
//
// ** your answer here **
// **
// Dump of assembler code for function main:
// 0x08000400 <+0>: nop
// => 0x08000402 <+2>: bkpt 0x0000
// 0x08000404 <+4>: b.n 0x8000400 <main>
// End of assembler dump.
// **
//
// commit your answers (bare1_7)
//
......
......@@ -71,18 +71,26 @@ fn main() -> ! {
//
// What is the output in the ITM console?
//
// ** your answer here **
// **
// [2019-02-21T12:23:01.072Z] bare2
// [2019-02-21T12:23:29.117Z] Start 42606
// [2019-02-21T12:23:29.118Z] End 448042815
// **
//
// Rebuild and run in release mode
//
// > cargo build --example bare2 --release
//
// ** your answer here **
// **
// [2019-02-21T12:30:44.941Z] bare2
// [2019-02-21T12:30:45.142Z] Start 3057860134
// [2019-02-21T12:30:45.142Z] End 3061860142
// **
//
// Compute the ratio between debug/release optimized code
// (the speedup).
//
// ** your answer here **
// ** 448000209 / 4000008 = 111,99982825 times **
//
// commit your answers (bare2_1)
//
......@@ -90,6 +98,72 @@ fn main() -> ! {
// Inspect the generated binaries, and try stepping through the code
// for both debug and release binaries. How do they differ?
//
// ** your answer here **
// ** Biggest difference in wait loop
// -- Debug --
// disassemble
// {"token":118,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
// Dump of assembler code for function bare2::wait::hfe7ce9f60a404aeb:
// 0x08000746 <+0>: push {r7, lr}
// 0x08000748 <+2>: sub sp, #56 ; 0x38
// 0x0800074a <+4>: mov r1, r0
// 0x0800074c <+6>: str r0, [sp, #16]
// 0x0800074e <+8>: ldr r0, [sp, #16]
// 0x08000750 <+10>: movs r2, #0
// 0x08000752 <+12>: str r2, [sp, #24]
// 0x08000754 <+14>: str r0, [sp, #28]
// 0x08000756 <+16>: ldr r0, [sp, #24]
// 0x08000758 <+18>: ldr r2, [sp, #28]
// 0x0800075a <+20>: str r1, [sp, #12]
// 0x0800075c <+22>: mov r1, r2
// 0x0800075e <+24>: bl 0x8000a9a <_$LT$I$u20$as$u20$core..iter..traits..IntoIterator$GT$::into_iter::h5a903f40a945694e>
// 0x08000762 <+28>: str r0, [sp, #8]
// 0x08000764 <+30>: str r1, [sp, #4]
// 0x08000766 <+32>: b.n 0x8000768 <bare2::wait::hfe7ce9f60a404aeb+34>
// 0x08000768 <+34>: ldr r0, [sp, #8]
// 0x0800076a <+36>: str r0, [sp, #32]
// 0x0800076c <+38>: ldr r1, [sp, #4]
// 0x0800076e <+40>: str r1, [sp, #36] ; 0x24
// 0x08000770 <+42>: b.n 0x8000772 <bare2::wait::hfe7ce9f60a404aeb+44>
// 0x08000772 <+44>: add r0, sp, #32
// 0x08000774 <+46>: bl 0x8000a00 <core::iter::range::_$LT$impl$u20$core..iter..iterator..Iterator$u20$for$u20$core..ops..range..Range$LT$A$GT$$GT$::next::h8a120a1de333cffb>
// => 0x08000778 <+50>: str r1, [sp, #48] ; 0x30
// 0x0800077a <+52>: str r0, [sp, #44] ; 0x2c
// 0x0800077c <+54>: b.n 0x800077e <bare2::wait::hfe7ce9f60a404aeb+56>
// 0x0800077e <+56>: ldr r0, [sp, #44] ; 0x2c
// 0x08000780 <+58>: cmp r0, #0
// 0x08000782 <+60>: str r0, [sp, #0]
// 0x08000784 <+62>: beq.n 0x8000790 <bare2::wait::hfe7ce9f60a404aeb+74>
// 0x08000786 <+64>: b.n 0x8000788 <bare2::wait::hfe7ce9f60a404aeb+66>
// 0x08000788 <+66>: ldr r0, [sp, #0]
// 0x0800078a <+68>: cmp r0, #1
// 0x0800078c <+70>: beq.n 0x8000796 <bare2::wait::hfe7ce9f60a404aeb+80>
// 0x0800078e <+72>: b.n 0x8000794 <bare2::wait::hfe7ce9f60a404aeb+78>
// 0x08000790 <+74>: add sp, #56 ; 0x38
// 0x08000792 <+76>: pop {r7, pc}
// 0x08000794 <+78>: udf #254 ; 0xfe
// 0x08000796 <+80>: ldr r0, [sp, #48] ; 0x30
// 0x08000798 <+82>: str r0, [sp, #52] ; 0x34
// 0x0800079a <+84>: ldr r0, [sp, #52] ; 0x34
// 0x0800079c <+86>: str r0, [sp, #40] ; 0x28
// 0x0800079e <+88>: bl 0x8000af6 <cortex_m::asm::nop::he6ee95faef743e38>
// 0x080007a2 <+92>: b.n 0x80007a4 <bare2::wait::hfe7ce9f60a404aeb+94>
// 0x080007a4 <+94>: b.n 0x8000772 <bare2::wait::hfe7ce9f60a404aeb+44>
// End of assembler dump.
//
// -- Release --
// disassemble
// {"token":172,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
// Dump of assembler code for function bare2::wait::h0be3841658d4de56:
// 0x0800065c <+0>: movw r0, #16960 ; 0x4240
// 0x08000660 <+4>: movt r0, #15
// 0x08000664 <+8>: subs r0, #1
// 0x08000666 <+10>: nop
// 0x08000668 <+12>: bne.n 0x8000664 <bare2::wait::h0be3841658d4de56+8>
// => 0x0800066a <+14>: bx lr
// End of assembler dump.
//
// **
//
// commit your answers (bare2_2)
......@@ -18,26 +18,27 @@ use cortex_m_semihosting::{hprint, hprintln};
#[entry]
fn main() -> ! {
hprintln!("bare3").unwrap();
let s = "ABCD";
let bs = s.as_bytes();
let s: &str = "ABCD";
let bs: &[u8] = s.as_bytes();
hprintln!("s = {}", s).unwrap();
hprintln!("bs = {:?}", bs).unwrap();
hprintln!("iterate over slice").unwrap();
for c in bs {
let c: &u8 = c;
hprint!("{},", c).unwrap();
}
hprintln!("iterate iterate using (raw) indexing").unwrap();
for i in 0..s.len() {
let i: usize = i;
hprintln!("{},", bs[i]).unwrap();
}
hprintln!("").unwrap();
let a = [65u8; 4];
//let mut a = [0u8; 4];
let mut a = [0u8; 4];
a.clone_from_slice(&bs);
hprintln!("").unwrap();
hprintln!("a = {}", core::str::from_utf8(&a).unwrap()).unwrap();
......@@ -52,27 +53,40 @@ fn main() -> ! {
//
// 1. What is the output in the `openocd` (Adapter Output) console?
//
// ** your answer here **
// **
// bare3
// s = ABCD
// bs = [65, 66, 67, 68]
// iterate over slice
// 65,66,67,68,iterate iterate using (raw) indexing
// 65,
// 66,
// 67,
// 68,
//
//
// a = AAAA
// **
//
// What is the type of `s`?
//
// ** your answer here **
// ** str **
//
// What is the type of `bs`?
//
// ** your answer here **
// ** [u8] byte slice**
//
// What is the type of `c`?
//
// ** your answer here **
// ** u8 byte **
//
// What is the type of `a`?
//
// ** your answer here **
// ** array **
//
// What is the type of `i`?
//
// ** your answer here **
// ** usize **
//
// Commit your answers (bare3_1)
//
......@@ -84,7 +98,7 @@ fn main() -> ! {
//`
// Run the program, what happens and why?
//
// ** your answer here **
// ** All elements in the final array are 0, The first variable "a" is shadowed by the second**
//
// Commit your answers (bare3_3)
//
......
......@@ -22,9 +22,12 @@ mod address {
pub const PERIPH_BASE: u32 = 0x40000000;
pub const AHB1PERIPH_BASE: u32 = PERIPH_BASE + 0x00020000;
pub const RCC_BASE: u32 = AHB1PERIPH_BASE + 0x3800;
// 6.3.11
pub const RCC_AHB1ENR: u32 = RCC_BASE + 0x30;
pub const GBPIA_BASE: u32 = AHB1PERIPH_BASE + 0x0000;
// 8.4.1
pub const GPIOA_MODER: u32 = GBPIA_BASE + 0x00;
// 8.4.7
pub const GPIOA_BSRR: u32 = GBPIA_BASE + 0x18;
}
......@@ -56,10 +59,12 @@ fn wait(i: u32) {
#[entry]
fn main() -> ! {
// power on GPIOA
// 6.3.11
let r = read_u32(RCC_AHB1ENR); // read
write_u32(RCC_AHB1ENR, r | 1); // set enable
// configure PA5 as output
// 8.4.1
let r = read_u32(GPIOA_MODER) & !(0b11 << (5 * 2)); // read and mask
write_u32(GPIOA_MODER, r | 0b01 << (5 * 2)); // set output mode
......@@ -68,10 +73,12 @@ fn main() -> ! {
loop {
// set PA5 high
// 8.4.7
write_u32(GPIOA_BSRR, 1 << 5); // set bit, output hight (turn on led)
wait(10_000);
// set PA5 low
// 8.4.7
write_u32(GPIOA_BSRR, 1 << (5 + 16)); // clear bit, output low (turn off led)
wait(10_000);
}
......@@ -84,7 +91,7 @@ fn main() -> ! {
//
// 1. Did you enjoy the blinking?
//
// ** your answer here **
// ** Yes **
//
// Now lookup the data-sheets, and read each section referred,
// 6.3.11, 8.4.1, 8.4.7
......@@ -101,12 +108,14 @@ fn main() -> ! {
//
// What was the error message and explain why.
//
// ** your answer here **
// ** "call to unsafe function is unsafe and requires unsafe function or block"
// The read_volatile takes a raw pointer as parameter, dereferencing a raw pointer is always considered unsafe
// **
//
// Digging a bit deeper, why do you think `read_volatile` is declared `unsafe`.
// (https://doc.rust-lang.org/core/ptr/fn.read_volatile.html, for some food for thought )
//
// ** your answer here **
// ** It's not certain that the memory address is readable or that the memory is aligned thus may result in undefined behavior **
//
// Commit your answers (bare4_2)
//
......@@ -119,16 +128,20 @@ fn main() -> ! {
//
// Why is it important that ordering of volatile operations are ensured by the compiler?
//
// ** your answer here **
// ** Variable used by volatile operations may change between accesses,
// reordering might introduce undefined or unexpected behaviour,
// if a read is ordered before a write the value would alter and not return the expected,
// or if reading from a register is performed before that register is set as read. **
//
// Give an example in the above code, where reordering might make things go horribly wrong
// (hint, accessing a peripheral not being powered...)
//
// ** your answer here **
// ** Read or write to GPIOA_BSRR before GPIOA_MODER is set to output,
// doing anything before setting RCC_AHB1ENR would be bad **
//
// Without the non-reording proprety of `write_volatile/read_volatile` could that happen in theory
// (argue from the point of data dependencies).
//
// ** your answer here **
// ** Writing/Reading in wrong order would result in unexpexed results. **
//
// Commit your answers (bare4_3)
......@@ -56,13 +56,17 @@ mod stm32f40x {
// offset (field offset)
// width (field width)
// value (new value that the field should take)
//
// impl VolatileCell<u32> {
// #[inline(always)]
// pub fn modify(&self, offset: u8, width: u8, value: u32) {
// // your code here
// }
// }
impl VolatileCell<u32> {
#[inline(always)]
pub fn modify(&self, offset: u8, width: u8, value: u32) {
let current_value = self.read();
let b = 0b11111111;
let mask = !( (b << offset + width) | !(b << offset) );
let masked_value = mask & (value << offset);
let modified_value = (current_value & !mask) | masked_value;
self.write(modified_value);
}
}
#[repr(C)]
#[allow(non_snake_case)]
......@@ -141,27 +145,27 @@ fn wait(i: u32) {
}
// simple test of Your `modify`
//fn test() {
// let t:VolatileCell<u32> = unsafe { core::mem::uninitialized() };
// t.write(0);
// assert!(t.read() == 0);
// t.modify(3, 3, 0b10101);
// //
// // 10101
// // ..0111000
// // ---------
// // 000101000
// assert!(t.read() == 0b101 << 3);
// t.modify(4, 3, 0b10001);
// // 000101000
// // 111
// // 001
// // 000011000
// assert!(t.read() == 0b011 << 3);
fn test() {
let t:VolatileCell<u32> = unsafe { core::mem::uninitialized() };
t.write(0);
assert!(t.read() == 0);
t.modify(3, 3, 0b10101);
//
// 10101
// ..0111000
// ---------
// 000101000
assert!(t.read() == 0b101 << 3);
t.modify(4, 3, 0b10001);
// 000101000
// 111
// 001
// 000011000
assert!(t.read() == 0b011 << 3);
//if << is used, your code will panic in dev (debug), but not in release mode
// t.modify(32, 3, 1);
//}
t.modify(32, 3, 1);
}
// system startup, can be hidden from the user
#[entry]
......@@ -177,24 +181,18 @@ fn main() -> ! {
// user application
fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) {
// power on GPIOA
let r = rcc.AHB1ENR.read(); // read
rcc.AHB1ENR.write(r | 1 << (0)); // set enable
rcc.AHB1ENR.modify(0, 1, 0b1);
// configure PA5 as output
let r = gpioa.MODER.read() & !(0b11 << (5 * 2)); // read and mask
gpioa.MODER.write(r | 0b01 << (5 * 2)); // set output mode
gpioa.MODER.modify(5*2, 2, 0b01);
loop {
// set PA5 high
gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led)
// gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
wait(10_000);
gpioa.ODR.modify(5, 1, 0b1);
//Modify wait by the speedup of a release build.
wait(1_119_982);
// set PA5 low
gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led)
// gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
wait(10_000);
gpioa.ODR.modify(5, 1, 0b0);
wait(1_119_982);
}
}
......@@ -227,7 +225,7 @@ fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) {
// - field width (in bits, u8),
// - and value (u32).
//
// Implement and check that running `test` gives you expected behavior.
// Implement and` gives you expected behavior.
//
// Change the code into using your new API.
//
......
......@@ -83,22 +83,22 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// mco2 : SYSCLK = 0b00
// mcopre : divide by 4 = 0b110
rcc.cfgr
.modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) });
.modify(|_, w| w.mco2().sysclk().mco2pre().div4() );
// power on GPIOC, RM0368 6.3.11
rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit());
rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
// MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet
// table 9
// AF0, gpioc reset value = AF0
// configure PC9 as alternate function 0b10, RM0368 6.2.10
gpioc.moder.modify(|_, w| w.moder9().bits(0b10));
gpioc.moder.modify(|_, w| w.moder9().alternate());
// otyper reset state push/pull, in reset state (don't need to change)
// ospeedr 0b11 = very high speed
gpioc.ospeedr.modify(|_, w| w.ospeedr9().bits(0b11));
gpioc.ospeedr.modify(|_, w| w.ospeedr9().very_high_speed());
}
// 0. Compile and run the example, in 16Mhz
......@@ -128,7 +128,7 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// What is the frequency of blinking?
//
// ** your answer here **
// ** 1Hz **
//
// commit your answers (bare6_1)
//
......@@ -137,15 +137,15 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// What is the frequency of MCO2 read by the oscilloscope?
//
// ** your answer here **
// ** 4MHz **
//
// Compute the value of SYSCLK based on the oscilloscope reading
//
// ** your answer here **
// ** 4 * 4 (MCOPRE) = 16MHz **
//
// What is the peak to peak reading of the signal?
//
// ** your answer here **
// ** 8.4V **
//
// Make a folder called "pictures" in your git project.
// Make a screen dump or photo of the oscilloscope output.
......@@ -165,7 +165,7 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//`
// What is the frequency of blinking?
//
// ** your answer here **
// ** 1Hz **
//
// Commit your answers (bare6_3)
//
......@@ -173,15 +173,15 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// What is the frequency of MCO2 read by the oscilloscope?
//
// ** your answer here **
// ** 16MHz **
//
// Compute the value of SYSCLK based on the oscilloscope reading.
//
// ** your answer here **
// ** 64MHz **
//
// What is the peak to peak reading of the signal?
//
// ** your answer here **
// ** 8.4V **
//
// Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_64mhz_high_speed".
......
......@@ -33,8 +33,8 @@ fn main() -> ! {
let rcc = p.RCC.constrain();
// 16 MHz (default, all clocks)
let clocks = rcc.cfgr.freeze();
// let clocks = rcc.cfgr.freeze();
let clocks = rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(84.mhz()).freeze();
let gpioa = p.GPIOA.split();
let tx = gpioa.pa2.into_alternate_af7();
......@@ -49,6 +49,12 @@ fn main() -> ! {
)
.unwrap();
let gpioc = p.GPIOC.split();
gpioc.pc9.into_alternate_af0().set_speed(hal::gpio::Speed::VeryHigh);
// MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet
// table 9
// AF0, gpioc reset value = AF0
// Separate out the sender and receiver of the serial port
let (mut tx, mut rx) = serial.split();
......@@ -125,11 +131,11 @@ fn main() -> ! {
//
// rcc.cfgr.sysclk(64.mhz()).pclk1(64.mhz()).pclk2(64.mhz()).freeze();
//
// ** your answer here **
// ** Max frequency of PCLK1 is 50 MHz **
//
// rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(64.mhz()).freeze();
//
// ** your answer here **
// ** Using prescales there is no way of dividing 84 to reach the wanted value of 64 for PCLK2 **
//
// Commit your answers (bare7_1)
//
......@@ -144,15 +150,15 @@ fn main() -> ! {
//
// What is the frequency of MCO2 read by the oscilloscope.
//
// ** your answer here **
// ** 84MHz **
//
// Compute the value of SYSCLK based on the oscilloscope reading.
//
// ** your answer here **
// ** 84MHz **
//
// What is the peak to peak reading of the signal.
//
// ** your answer here **
// ** 9.8V **
//
// Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_84mhz_high_speed"
......@@ -163,11 +169,11 @@ fn main() -> ! {
//
// Did the frequency change in comparison to assignment 5?
//
// ** your answer here **
// ** It became unreadable **
//
// What is the peak to peak reading of the signal (and why did it change)?
//
// ** your answer here **
// ** < 100 mV. The value of the pin is alternating to fast for the setting, max frequency for low speed mode is 4-8 MHz depending on CL value **
//
// Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_84mhz_low_speed".
......@@ -197,11 +203,16 @@ fn main() -> ! {
//
// What did you receive, and what was the output of the ITM trace.
//
// ** your answer here **
// ** Received abcd, seding a longer string caused overflow
// ITM trace
// [2019-03-06T09:27:25.066Z] Ok 97
// [2019-03-06T09:27:25.066Z] Ok 98
// [2019-03-06T09:27:25.067Z] Ok 99
// [2019-03-06T09:27:25.067Z] Ok 100 **
//
// Explain why the buffer overflows.
//
// ** your answer here **
// ** We are reading a byte, printing and then writing. This will take some time and we will receive new bytes before the serial is flushed. **
//
// commit your answers (bare7_4)
//
......
......@@ -3,6 +3,6 @@
# Depending on the hardware revision you got you'll have to pick ONE of these
# interfaces. At any time only one interface should be commented out.
source [find interface/stlink.cfg]
source [find interface/stlink-v2-1.cfg]
source [find target/stm32f4x.cfg]
pictures/bare_6_16mhz_high_speed.jpg

243 KiB

pictures/bare_6_64mhz_high_speed.jpg

243 KiB

pictures/bare_6_84mhz_high_speed.jpg

216 KiB

pictures/bare_6_84mhz_low_speed.jpg

149 KiB