Skip to content
Snippets Groups Projects
Commit 7e456dfe authored by tommy's avatar tommy
Browse files

bare1-3 done

parent 1f548f52
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,15 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"cwd": "${workspaceRoot}",
"executable": "./bin/executable.elf",
"name": "Debug Microcontroller",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd"
},
{
"type": "cortex-debug",
"request": "launch",
......
......@@ -20,9 +20,10 @@ const APP: () = {
fn init(_cx: init::Context) {
let mut x = core::u32::MAX - 1;
loop {
// cortex_m::asm::bkpt();
x += 1;
// cortex_m::asm::bkpt();
cortex_m::asm::bkpt();
//x += 1;
x = x.wrapping_add(1);
cortex_m::asm::bkpt();
// prevent optimization by read-volatile (unsafe)
unsafe {
......@@ -45,11 +46,11 @@ const APP: () = {
//
// Paste the error message:
//
// ** your answer here **
// panicked at 'attempt to add with overflow', examples/rtic_bare1.rs:24:13
//
// Explain in your own words why the code panic:ed.
//
// ** your answer here **
// It panicked because of an attempted overflow
//
// Commit your answer (bare1_1)
//
......@@ -65,11 +66,18 @@ const APP: () = {
//
// Paste the backtrace:
//
// ** your answer here
// #0 lib::__bkpt () at asm/lib.rs:49
// #1 0x0800104e in cortex_m::asm::bkpt () at /root/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.7.1/src/asm.rs:15
// #2 panic_semihosting::panic (info=0x2000fed8) at /root/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.6/src/lib.rs:92
// #3 0x0800039a in core::panicking::panic_fmt () at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:92
// #4 0x08000374 in core::panicking::panic () at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:50
// #5 0x08000ebe in rtic_bare1::init (_cx=...) at /home/tommy/Documents/Inbygda_system/e7020e_2021/examples/rtic_bare1.rs:24
// #6 0x08000f08 in rtic_bare1::APP::main () at /home/tommy/Documents/Inbygda_system/e7020e_2021/examples/rtic_bare1.rs:15
// {"token":181,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
//
// Explain in your own words the chain of calls.
//
// ** your answer here
// The error occurs and then sends it further up and into panic and ending up in asm/lib
//
// Commit your answer (bare1_2)
//
......@@ -82,20 +90,22 @@ const APP: () = {
//
// What is the value of `x`?
//
// ** your answer here **
// x: 4294967294
//
// Explain in your own words where this value comes from.
//
// ** your answer here **
// x is initiated as usigned 32-bit integer set as max - 1 that will set it as 2^32 - 1
//
// Now continue the program, since you are in a loop
// the program will halt again at line 24.
//
// What is the value of `x`?
//
// x: 4294967295
//
// Explain in your own words why `x` now has this value.
//
// ** your answer here **
// Since we increase x by 1 for every time we loop
//
// Now continue again.
//
......@@ -109,7 +119,7 @@ const APP: () = {
//
// Explain in your own words why a panic makes sense at this point.
//
// ** your answer here **
// The panic makes sense because x overflows by increasing the max (2^32 = 4294967295) by 1.
//
// Commit your answer (bare1_3)
//
......@@ -126,13 +136,13 @@ const APP: () = {
//
// Explain in your own words what this assembly line does.
//
// ** your answer here **
// load r0 with the value that stackpointer points to.
//
// In Cortex Registers (left) you can see the content of `r0`
//
// What value do you observe?
//
// ** your answer here **
// r0 = -2
//
// You can also get the register info from GDB directly.
//
......@@ -150,7 +160,7 @@ const APP: () = {
//
// Explain in your own words what is happening here.
//
// ** your answer here **
// We add 1 to r0 and update the N. Z, C and V flags.
//
// We move to the next assembly instruction:
//
......@@ -159,7 +169,7 @@ const APP: () = {
//
// What is the reported value for `r0`
//
// ** your answer here **
// r0 = -1
//
// So far so good.
//
......@@ -190,7 +200,7 @@ const APP: () = {
//
// What does BCS do?
//
// ** your answer here **
// Checks if carry flag is set, if it is branches to +36
//
// Now let's see what happens.
//
......@@ -204,7 +214,7 @@ const APP: () = {
//
// Explain in your own words where we are heading.
//
// ** your answer here **
// we move in 20485872 into r0, 20485856 into r2 and 28 into r1 but only overwrites the 9 lowest bits.
//
// To validate that your answer, let's let the program continue
//
......@@ -215,13 +225,13 @@ const APP: () = {
// Explain in your own words what the code
// 0x08000f28 .. 0x08000f38 achieves
//
// #28 generates the panic (overflow) while r0 and r2 tells where.
//
// Hint 1, look at the error message?
// Hint 2, look at the call stack.
// Hint 3, the code is generated by the Rust compiler to produce the error message.
// there is no "magic" here, just a compiler generating code...
//
// ** your answer here **
//
// Commit your answer (bare1_4)
//
// 5. Now we can remove the break point (click the `Remove All Breakpoints`),
......@@ -229,7 +239,7 @@ const APP: () = {
//
// Close the debug session and press F5 again to re-compile and launch the app.
//
// Continue until you hit the firs breakpoint.
// Continue until you hit the first breakpoint.
//
// The disassembly should look like this:
//
......@@ -273,7 +283,7 @@ const APP: () = {
//
// Do you see any way this code may end up in a panic?
//
// ** your answer here **
// When calling bkpt when not in debug will cause a panic.
//
// So clearly, the "semantics" (meaning) of the program has changed.
// This is on purpose, Rust adopts "unchecked" (wrapping) additions (and subtractions)
......@@ -288,16 +298,45 @@ const APP: () = {
//
// Paste the generated assembly:
//
// ** your answer here **
// Dump of assembler code for function rtic_bare1::APP::main:
/* 0x08000eae <+0>: push {r7, lr}
0x08000eb0 <+2>: mov r7, sp
0x08000eb2 <+4>: sub sp, #56 ; 0x38
=> 0x08000eb4 <+6>: bl 0x8000faa <lib::__cpsid>
0x08000eb8 <+10>: movw r0, #0
0x08000ebc <+14>: movw r4, #60688 ; 0xed10
0x08000ec0 <+18>: movt r0, #8192 ; 0x2000
0x08000ec4 <+22>: movs r1, #1
0x08000ec6 <+24>: strb r1, [r0, #0]
0x08000ec8 <+26>: add r0, sp, #4
0x08000eca <+28>: movt r4, #57344 ; 0xe000
0x08000ece <+32>: str r0, [sp, #20]
0x08000ed0 <+34>: mov r0, r4
0x08000ed2 <+36>: strd r4, r4, [sp, #28]
0x08000ed6 <+40>: bl 0x8000f78 <_ZN4core4cell19UnsafeCell$LT$T$GT$3get17hc981151b10f99f20E>
0x08000eda <+44>: bl 0x8000f46 <_ZN4core3ptr13read_volatile17hb977623ea709e27cE>
0x08000ede <+48>: orr.w r5, r0, #2
0x08000ee2 <+52>: str r0, [sp, #24]
0x08000ee4 <+54>: mov r0, r4
0x08000ee6 <+56>: str r4, [sp, #36] ; 0x24
0x08000ee8 <+58>: str r5, [sp, #40] ; 0x28
0x08000eea <+60>: bl 0x8000f78 <_ZN4core4cell19UnsafeCell$LT$T$GT$3get17hc981151b10f99f20E>
0x08000eee <+64>: mov r1, r5
0x08000ef0 <+66>: bl 0x8000f54 <_ZN4core3ptr14write_volatile17h73c310961d025d87E>
0x08000ef4 <+70>: bl 0x8000e84 <rtic_bare1::init>
0x08000ef8 <+74>: bl 0x8000fae <lib::__cpsie>
0x08000efc <+78>: bl 0x8000fb2 <lib::__wfi>
0x08000f00 <+82>: b.n 0x8000efc <rtic_bare1::APP::main+78>
End of assembler dump. */
//
// Can this code generate a panic?
//
// ** your answer here **
// No.
//
// Is there now any reference to the panic handler?
// If not, why is that the case?
//
// ** your answer here **
// When we use wrap it allows us to wrap around, hence no overflow or panic.
//
// commit your answers (bare1_5)
//
......@@ -327,12 +366,30 @@ const APP: () = {
//
// Dump the generated assembly.
//
// ** your answer here **
/*Dump of assembler code for function rtic_bare1::init:
0x08000e84 <+0>: push {r4, r6, r7, lr}
0x08000e86 <+2>: add r7, sp, #8
0x08000e88 <+4>: sub sp, #16
0x08000e8a <+6>: movw r0, #5808 ; 0x16b0
0x08000e8e <+10>: mov r4, sp
0x08000e90 <+12>: movt r0, #2048 ; 0x800
0x08000e94 <+16>: ldr r0, [r0, #0]
0x08000e96 <+18>: str r0, [sp, #0]
0x08000e98 <+20>: bl 0x8000fa6 <lib::__bkpt>
0x08000e9c <+24>: ldr r0, [sp, #0]
0x08000e9e <+26>: adds r0, #1
0x08000ea0 <+28>: str r0, [sp, #0]
0x08000ea2 <+30>: bl 0x8000fa6 <lib::__bkpt>
=> 0x08000ea6 <+34>: mov r0, r4
0x08000ea8 <+36>: bl 0x8000f46 <_ZN4core3ptr13read_volatile17hb977623ea709e27cE>
0x08000eac <+40>: b.n 0x8000e98 <rtic_bare1::init+20>
End of assembler dump.
*/
//
// Where is the local variable stored?
// What happened, and why is Rust + LLVM allowed to optimize out your code?
//
// ** your answer here **
// On the stack pointer. When volatile is commented the Rust + LLVM is allowed to make optimizations.
//
// Commit your answers (bare1_6)
//
......
......@@ -44,7 +44,7 @@ const APP: () = {
hprintln!("End {:?}", end).ok();
hprintln!("Diff {:?}", end.wrapping_sub(start)).ok();
// wait(100);
wait(100);
}
};
......@@ -76,16 +76,22 @@ fn wait(i: u32) {
// What is the output in the Adapter Output console?
// (Notice, it will take a while we loop one million times at only 16 MHz.)
//
// ** your answer here **
// Start 128543196
// End 295543279
// Diff 167000083
//
// Rebuild and run in (Cortex Release).
//
// ** your answer here **
// Start 1088552331
// End 1092552347
// Diff 4000016
//
// Compute the ratio between debug/release optimized code
// (the speedup).
//
// ** your answer here **
// Start: 128543196/1088552331 = 0,118086372459
// End: 295543279/1092552347 = 0,270507202526
// Diff: 167000083/4000016 = 41,7498537506
//
// commit your answers (bare2_1)
//
......@@ -110,7 +116,17 @@ fn wait(i: u32) {
//
// Dump generated assembly for the "wait" function.
//
// ** your answer here **
/* Dump of assembler code for function rtic_bare2::wait:
0x080004a0 <+0>: push {r7, lr}
0x080004a2 <+2>: mov r7, sp
0x080004a4 <+4>: movw r0, #16960 ; 0x4240
0x080004a8 <+8>: movt r0, #15
=> 0x080004ac <+12>: nop
0x080004ae <+14>: subs r0, #1
0x080004b0 <+16>: bne.n 0x80004ac <rtic_bare2::wait+12>
0x080004b2 <+18>: pop {r7, pc}
End of assembler dump.
*/
//
// Under the ARM calling convention, r0.. is used as arguments.
// However in this case, we se that r0 is set by the assembly instructions,
......@@ -120,7 +136,8 @@ fn wait(i: u32) {
//
// Answer in your own words, how they assign r0 to 1000000.
//
// ** your answer here **
// By combining instruction +4 and +8 we get 0xf4240 since movt is the upper 16-bit
// and movw is lower 16-bit and converting it from hexa to decimal we get 1000000.
//
// Commit your answers (bare2_2)
//
......@@ -130,10 +147,19 @@ fn wait(i: u32) {
//
// Dump the generated assembly for the "wait" function.
//
// ** your answer here **
// Dump of assembler code for function rtic_bare2::wait:
/*
0x080004a0 <+0>: push {r7, lr}
0x080004a2 <+2>: mov r7, sp
=> 0x080004a4 <+4>: nop
0x080004a6 <+6>: subs r0, #1
0x080004a8 <+8>: bne.n 0x80004a4 <rtic_bare2::wait+4>
0x080004aa <+10>: pop {r7, pc}
End of assembler dump.
*/
//
// Answer in your own words, why you believe the generated code differs?
//
// ** your answer here **
// It starts the wait function where it just loops nops.
//
//
......@@ -13,25 +13,35 @@
use cortex_m_semihosting::hprintln;
use panic_semihosting as _;
use rtic::cyccnt::Instant;
use rtic::cyccnt::Duration;
use stm32f4;
#[rtic::app(device = stm32f4)]
#[rtic::app(device = stm32f4, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = {
#[init]
fn init(mut cx: init::Context) {
cx.core.DWT.enable_cycle_counter();
let start = Instant::now();
//let start = Instant::elapsed(&Instant::now());
wait(1_000_000);
let end = Instant::now();
let timeElapsed = start.elapsed();
//let diff_f = Duration::as_cycles(&(end-start));
//let diff = Duration::as_cycles(&end.duration_since(start));
let diff_elapsed = Duration::as_cycles(&timeElapsed);
// notice all printing outside of the section to measure!
hprintln!("Start {:?}", start).ok();
hprintln!("End {:?}", end).ok();
// hprintln!("Diff {:?}", (end - start) ).ok();
//hprintln!("Diff {:?}", diff).ok();
//hprintln!("Diff {:?}", diff_f).ok();
hprintln!("Diff {:?}", diff_elapsed).ok();
}
};
// burns CPU cycles by just looping `i` times
#[inline(never)]
#[no_mangle]
......@@ -42,6 +52,7 @@ fn wait(i: u32) {
}
}
// 0. Setup
//
// > cargo doc --open
......@@ -62,7 +73,8 @@ fn wait(i: u32) {
//
// What is the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(47356)
// End Instant(4047373)
//
// As you see line 31 is commented out (we never print the difference).
//
......@@ -76,7 +88,9 @@ fn wait(i: u32) {
//
// What is now the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(4025484479)
// End Instant(4029484495)
// Diff 4000016
//
// Commit your answers (bare3_1)
//
......@@ -86,7 +100,9 @@ fn wait(i: u32) {
//
// What is now the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(1525994886)
// End Instant(1529994902)
// Diff 4000016
//
// Commit your answers (bare3_2)
//
......@@ -95,7 +111,9 @@ fn wait(i: u32) {
//
// What is now the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(4000822764)
// End Instant(4004822780)
// Diff 4000020
//
// Commit your answers (bare3_3)
//
......
......@@ -14,6 +14,7 @@ const APP: () = {
struct Resources {
// late resources
GPIOA: stm32::GPIOA,
GPIOC: stm32::GPIOC,
}
#[init(schedule = [toggle])]
fn init(cx: init::Context) -> init::LateResources {
......@@ -41,9 +42,11 @@ const APP: () = {
// configure PA5 as output, RM0368 8.4.1
device.GPIOA.moder.modify(|_, w| w.moder5().bits(1));
device.GPIOC.moder.modify(|_, w| w.moder13().bits(0));
// pass on late resources
init::LateResources {
GPIOA: device.GPIOA,
GPIOC: device.GPIOC,
}
}
......@@ -54,6 +57,7 @@ const APP: () = {
continue;
}
}
read_bit();
#[task(resources = [GPIOA], schedule = [toggle])]
fn toggle(cx: toggle::Context) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment