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
Loading items

Target

Select target project
  • pln/e7020e_2020
  • 97gushan/e7020e_2020
  • markhakansson/e7020e_2020
  • Grumme2/e7020e_2020
  • Hammarkvast/e7020e_2020
5 results
Select Git revision
Loading items
Show changes
Commits on Source (21)
[]
\ No newline at end of file
[]
\ No newline at end of file
......@@ -16,9 +16,9 @@
"preLaunchTask": "cargo build",
"executable": "./target/thumbv7em-none-eabihf/debug/app",
"configFiles": [
"interface/stlink.cfg",
// "interface/stlink-v2-1.cfg", // deprecated setup script
"target/stm32f4x.cfg"
//"interface/stlink.cfg",
"interface/stlink-v2-1.cfg", // deprecated setup script
// "target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor arm semihosting enable"
......@@ -39,9 +39,9 @@
"preLaunchTask": "cargo build --example",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/${fileBasenameNoExtension}",
"configFiles": [
"interface/stlink.cfg",
// "interface/stlink-v2-1.cfg", // deprecated setup script
"target/stm32f4x.cfg"
//"interface/stlink.cfg",
"interface/stlink-v2-1.cfg", // deprecated setup script
// "target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor arm semihosting enable",
......@@ -76,8 +76,8 @@
"executable": "./target/thumbv7em-none-eabihf/debug/examples/${fileBasenameNoExtension}",
"configFiles": [
"interface/stlink.cfg",
// "interface/stlink-v2-1.cfg", // deprecated setup script
"target/stm32f4x.cfg"
"interface/stlink-v2-1.cfg", // deprecated setup script
// "target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor arm semihosting enable",
......@@ -101,8 +101,8 @@
"executable": "./target/thumbv7em-none-eabihf/debug/examples/${fileBasenameNoExtension}",
"configFiles": [
"interface/stlink.cfg",
// "interface/stlink-v2-1.cfg", // deprecated setup script
"target/stm32f4x.cfg"
"interface/stlink-v2-1.cfg", // deprecated setup script
// "target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor arm semihosting enable",
......@@ -125,9 +125,9 @@
"preLaunchTask": "cargo build --example --features rtfm",
"executable": "./target/thumbv7em-none-eabihf/debug/examples/${fileBasenameNoExtension}",
"configFiles": [
"interface/stlink.cfg",
// "interface/stlink-v2-1.cfg", // deprecated setup script
"target/stm32f4x.cfg"
//"interface/stlink.cfg",
"interface/stlink-v2-1.cfg", // deprecated setup script
// "target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor arm semihosting enable",
......@@ -150,9 +150,9 @@
"preLaunchTask": "cargo build --example --release",
"executable": "./target/thumbv7em-none-eabihf/release/examples/${fileBasenameNoExtension}",
"configFiles": [
"interface/stlink.cfg",
// "interface/stlink-v2-1.cfg", // deprecated setup script
"target/stm32f4x.cfg"
//"interface/stlink.cfg",
"interface/stlink-v2-1.cfg", // deprecated setup script
// "target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor arm semihosting enable",
......@@ -175,9 +175,9 @@
"preLaunchTask": "cargo build --example --release --features stm32f4",
"executable": "./target/thumbv7em-none-eabihf/release/examples/${fileBasenameNoExtension}",
"configFiles": [
"interface/stlink.cfg",
// "interface/stlink-v2-1.cfg", // deprecated setup script
"target/stm32f4x.cfg"
//"interface/stlink.cfg",
"interface/stlink-v2-1.cfg", // deprecated setup script
// "target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor reset init", // sets the MCU to 64MHz
......
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aligned"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1ce8b3382016136ab1d31a1b5ce807144f8b7eb2d5f16b2108f0f07edceb94"
dependencies = [
"as-slice",
]
[[package]]
name = "app"
version = "0.1.0"
dependencies = [
"aligned",
"cortex-m",
"cortex-m-rt",
"cortex-m-rtfm",
"cortex-m-semihosting",
"heapless",
"nb",
"panic-halt",
"panic-itm",
"panic-semihosting",
"stm32f4 0.9.0",
"stm32f4xx-hal",
"ufmt",
]
[[package]]
name = "as-slice"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be6b7e95ac49d753f19cab5a825dea99a1149a04e4e3230b33ae16e120954c04"
dependencies = [
"generic-array 0.12.3",
"generic-array 0.13.2",
"stable_deref_trait",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bare-metal"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
"rustc_version",
]
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cast"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
dependencies = [
"rustc_version",
]
[[package]]
name = "cortex-m"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763"
dependencies = [
"aligned",
"bare-metal",
"volatile-register",
]
[[package]]
name = "cortex-m-rt"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00d518da72bba39496024b62607c1d8e37bcece44b2536664f1132a73a499a28"
dependencies = [
"cortex-m-rt-macros",
"r0",
]
[[package]]
name = "cortex-m-rt-macros"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4717562afbba06e760d34451919f5c3bf3ac15c7bb897e8b04862a7428378647"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cortex-m-rtfm"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf0b9fd3f042cb3793d15daf3cea201b2f25c99b0b5b936a551bb6909c3ae5b"
dependencies = [
"cortex-m",
"cortex-m-rt",
"cortex-m-rtfm-macros",
"heapless",
"rtfm-core",
]
[[package]]
name = "cortex-m-rtfm-macros"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62092f6ff344e9b0adb748f0302ed69889ba2fae1fce446e3788d4726ea73bb"
dependencies = [
"proc-macro2",
"quote",
"rtfm-syntax",
"syn",
]
[[package]]
name = "cortex-m-semihosting"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "113ef0ecffee2b62b58f9380f4469099b30e9f9cbee2804771b4203ba1762cfa"
dependencies = [
"cortex-m",
]
[[package]]
name = "embedded-hal"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b"
dependencies = [
"nb",
"void",
]
[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
dependencies = [
"typenum",
]
[[package]]
name = "hash32"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10b591a0032f114b7a77d4fbfab452660c553055515b7d7ece355db080d19087"
dependencies = [
"as-slice",
"generic-array 0.13.2",
"hash32",
]
[[package]]
name = "indexmap"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
dependencies = [
"autocfg",
]
[[package]]
name = "nb"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
[[package]]
name = "panic-halt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
[[package]]
name = "panic-itm"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98830d17a95587207e41edaa3009b143d326ce134b0e3538ac98246a67d66cc3"
dependencies = [
"cortex-m",
]
[[package]]
name = "panic-semihosting"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03864ac862876c16a308f5286f4aa217f1a69ac45df87ad3cd2847f818a642c"
dependencies = [
"cortex-m",
"cortex-m-semihosting",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
[[package]]
name = "rtfm-core"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ec893edb2aa5b70320b94896ffea22a7ebb1cf3f942bb67cd5b60a865a63493"
[[package]]
name = "rtfm-syntax"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4455e23c34df3d66454e7e218a4d76a7f83321d04a806be614463341cec4116e"
dependencies = [
"indexmap",
"proc-macro2",
"syn",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "stable_deref_trait"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
[[package]]
name = "stm32f4"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec5833f4399bfeca7c33a3797d2cfc4db14e871794cc4796de80d2a44864cc2a"
dependencies = [
"bare-metal",
"cortex-m",
"cortex-m-rt",
"vcell",
]
[[package]]
name = "stm32f4"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88640ad08c62e0651a1320187f38c3655d025ed580a10f0e4d85a2cc4829069f"
dependencies = [
"bare-metal",
"cortex-m",
"cortex-m-rt",
"vcell",
]
[[package]]
name = "stm32f4xx-hal"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8b5b1feabb6f6f4ae8ddab194f6b79965f4d9be66d5717f58468c38d3bd90c4"
dependencies = [
"bare-metal",
"cast",
"cortex-m",
"cortex-m-rt",
"embedded-hal",
"nb",
"stm32f4 0.8.0",
"void",
]
[[package]]
name = "syn"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "typenum"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
[[package]]
name = "ufmt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7ecea7ef79d3f8f878eee614afdf5256475c63ad76139d4da6125617c784a0"
dependencies = [
"proc-macro-hack",
"ufmt-macros",
"ufmt-write",
]
[[package]]
name = "ufmt-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed813e34a2bfa9dc58ee2ed8c8314d25e6d70c911486d64b8085cb695cfac069"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "ufmt-write"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "vcell"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
dependencies = [
"vcell",
]
......@@ -21,7 +21,7 @@ heapless = "0.5.3"
[dependencies.cortex-m]
version = "0.6.2"
# features = ["inline-asm"] # <- currently requires nightly compiler
features = ["inline-asm"] # <- currently requires nightly compiler
[dependencies.cortex-m-rt]
version = "0.6.12"
......
......@@ -22,25 +22,40 @@ use panic_semihosting as _;
use cortex_m_rt::entry;
// a constant (cannot be changed at run-time)
const X_INIT: u32 = 10;
// const X_INIT: u32 = core::u32::MAX;
//const X_INIT: u32 = 10;
const X_INIT: u32 = core::u32::MAX;
// global mutable variables (changed using unsafe code)
static mut X: u32 = X_INIT;
static mut Y: u32 = 0;
fn read_x()->u32{
unsafe{X}
}
fn read_y()->u32{
unsafe{Y}
}
fn write_y(y:u32){
unsafe{Y=y};
}
fn write_x(x:u32){
unsafe{X=x};
}
#[entry]
fn main() -> ! {
// local mutable variable (changed in safe code)
let mut x = unsafe { X };
let mut x = read_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_x(read_x().wrapping_add(1));
write_y(read_x());
assert!(x == read_x() && read_x() == read_y()+1);
}
}
......@@ -57,17 +72,22 @@ fn main() -> ! {
// Look under Variables/Local what do you find.
//
// ** your answer here **
// local
// x: 4685359
//
// In the Expressions (WATCH -vscode) view add X and Y
// what do you find
//
// ** your answer here **
//
// X: 4685359
// Y: <optimized out>
// 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 **
// Its inceremented by one each iteration and it will eventually wrap.
//
// Commit your answers (bare0_1)
//
......@@ -76,6 +96,8 @@ fn main() -> ! {
// (Hint, look under OUTPUT/Adopter Output to see the `openocd` output.)
//
// ** your answer here **
// First it says that the local x gets optimized out then it panics
// "panicked at 'attempt to add with overflow', examples/bare0.rs:42:9"
//
// Commit your answers (bare0_2)
//
......@@ -84,10 +106,10 @@ fn main() -> ! {
// Change (both) += operations to use wrapping_add
// load and run the program, what happens
// ** your answer here **
//
// x wraps around and becomes 0 and X doesnt change
// Now continue execution, what happens
// ** your answer here **
//
// x continues to get bigger X is still the same
// Commit your answers (bare0_3)
//
// (If the program did not succeed back to the breakpoint
......@@ -96,7 +118,7 @@ fn main() -> ! {
// 4. Change the assertion to `assert!(x == X && X == Y + 1)`, what happens?
//
// ** place your answer here **
//
// the program panics "panicked at 'assertion failed: x == X && X == Y + 1', examples/bare0.rs:45:13"
// Commit your answers (bare0_4)
//
// 5. Remove the assertion and implement "safe" functions for
......
......@@ -24,9 +24,9 @@ fn main() -> ! {
cortex_m::asm::bkpt();
// prevent optimization by read-volatile (unsafe)
unsafe {
core::ptr::read_volatile(&x);
}
// unsafe {
// core::ptr::read_volatile(&x);
// }
}
}
......@@ -59,10 +59,12 @@ fn main() -> ! {
// (passing 3 breakpoints)
//
// ** your answer here **
//
// The program panicsc
// What is the `ITM` output.
//
// ** your answer here **
// panicked at 'attempt to add with overflow', examples/bare1.rs:23:9
//
// Commit your answer (bare1_1)
//
......@@ -73,18 +75,58 @@ fn main() -> ! {
//
// What is the output of:
// > disassemble
//
// ** your answer here **
//
// (gdb) disassemble
// Dump of assembler code for function bare1::__cortex_m_rt_main:
// 0x0800040a <+0>: push {r7, lr}
// 0x0800040c <+2>: mov r7, sp
// 0x0800040e <+4>: sub sp, #16
// 0x08000410 <+6>: mvn.w r0, #1
// 0x08000414 <+10>: str r0, [sp, #8]
// 0x08000416 <+12>: movs r0, #0
// 0x08000418 <+14>: strb.w r0, [sp, #12]
// 0x0800041c <+18>: ldr r0, [sp, #8]
// 0x0800041e <+20>: str r0, [sp, #4]
// 0x08000420 <+22>: b.n 0x8000422 <bare1::__cortex_m_rt_main+24>
// => 0x08000422 <+24>: bkpt 0x0000
// 0x08000424 <+26>: b.n 0x8000426 <bare1::__cortex_m_rt_main+28>
// ---Type <return> to continue, or q <return> to quit---
// 0x08000426 <+28>: ldr r0, [sp, #4]
// 0x08000428 <+30>: adds r1, r0, #1
// 0x0800042a <+32>: mov r2, r1
// 0x0800042c <+34>: cmp r1, r0
// 0x0800042e <+36>: str r2, [sp, #0]
// 0x08000430 <+38>: bcc.n 0x8000446 <bare1::__cortex_m_rt_main+60>
// 0x08000432 <+40>: b.n 0x8000434 <bare1::__cortex_m_rt_main+42>
// 0x08000434 <+42>: ldr r0, [sp, #0]
// 0x08000436 <+44>: str r0, [sp, #4]
// 0x08000438 <+46>: bkpt 0x0000
// 0x0800043a <+48>: b.n 0x800043c <bare1::__cortex_m_rt_main+50>
// 0x0800043c <+50>: add r0, sp, #4
// 0x0800043e <+52>: bl 0x800045e <core::ptr::read_volatile>
// 0x08000442 <+56>: b.n 0x8000444 <bare1::__cortex_m_rt_main+58>
// 0x08000444 <+58>: b.n 0x8000422 <bare1::__cortex_m_rt_main+24>
// 0x08000446 <+60>: movw r0, #9520 ; 0x2530
// ---Type <return> to continue, or q <return> to quit---
// 0x0800044a <+64>: movt r0, #2048 ; 0x800
// 0x0800044e <+68>: movw r2, #9492 ; 0x2514
// 0x08000452 <+72>: movt r2, #2048 ; 0x800
// 0x08000456 <+76>: movs r1, #28
// 0x08000458 <+78>: bl 0x80008ec <core::panicking::panic>
// 0x0800045c <+82>: udf #254 ; 0xfe
// End of assembler dump.
// How many instructions are in between the two `bkpt` instructions in the loop.
// Notice, the generated code may not be exactly what you expect :)
//
// ** your answer here **
// 10
//
// Which instruction stores the local variable on the stack.
//
// ** your answer here **
//
// 0x0800040a <+0>: push {r7, lr}
// Commit your answers (bare1_2)
//
// 3. Release mode (optimized builds).
......@@ -101,18 +143,33 @@ fn main() -> ! {
//
// ** your answer here **
//
// Dump of assembler code for function bare1::__cortex_m_rt_main:
// 0x0800040a <+0>: sub sp, #4
// 0x0800040c <+2>: mvn.w r0, #1
// 0x08000410 <+6>: str r0, [sp, #0]
// 0x08000412 <+8>: adds r0, #1
// => 0x08000414 <+10>: bkpt 0x0000
// 0x08000416 <+12>: str r0, [sp, #0]
// 0x08000418 <+14>: bkpt 0x0000
// 0x0800041a <+16>: ldr r0, [sp, #0]
// 0x0800041c <+18>: b.n 0x8000412 <bare1::__cortex_m_rt_main+8>
// End of assembler dump.
// How many instructions are in between the two `bkpt` instructions.
//
// ** your answer here **
//
// 1
// Where is the local variable stored?
//
// ** your answer here **
// 0x08000410 <+6>: str r0, [sp, #0]
//
// Is there now any reference to the panic handler?
// If not, why is that the case?
//
// ** your answer here **
// No there is not any refrence to the panic handler
// Because in release mode rust does not include checks for
// integer overflow. If overflow occurs it just wrapps with twos complement.
//
// commit your answers (bare1_3)
//
......@@ -149,15 +206,28 @@ fn main() -> ! {
//
// ** your answer here **
//
// Dump of assembler code for function bare1::__cortex_m_rt_main:
// 0x0800040a <+0>: bkpt 0x0000
// => 0x0800040c <+2>: bkpt 0x0000
// 0x0800040e <+4>: b.n 0x800040a <bare1::__cortex_m_rt_main>
// End of assembler dump
//
// How many instructions are in between the two `bkpt` instructions.
//
// ** your answer here **
// 0
//
// Where is the local variable stored?
// What happened, and why is Rust + LLVM allowed to do that?
//
// ** your answer here **
//
// 0x0800040e <+4>: b.n 0x800040a <bare1::__cortex_m_rt_main>
//
// In release mode the program is the most optimized
// which means that the compiler can remove instructions that arent necessary
//
//
// commit your answers (bare1_4)
//
//
......
......@@ -78,18 +78,27 @@ fn main() -> ! {
// What is the output in the ITM console?
//
// ** your answer here **
//
// bare2
// Start 45
// End 561000215
// Diff 561000170
// Rebuild and run in release mode
//
// > cargo build --example bare2 --release
//
// ** your answer here **
// bare2
// Start 2539927876
// End 2543927884
// Diff 4000008
//
// Compute the ratio between debug/release optimized code
// (the speedup).
//
// ** your answer here **
//
// start : 1.77 *10⁻8
// End : 45.35
// diff: 140.25
// commit your answers (bare2_1)
//
// 3. *Optional
......
......@@ -18,26 +18,30 @@ 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();
let c: &u8;
for c in bs {
hprint!("{},", c).unwrap();
}
hprintln!("iterate iterate using (raw) indexing").unwrap();
let i: usize;
for i in 0..s.len() {
hprintln!("{},", bs[i]).unwrap();
}
hprintln!("").unwrap();
let a = [65u8; 4];
// let mut a = [0u8; 4];
let a: [u8;4] = [65u8; 4];
let mut a = [0u8; 4];
let mut a = &bs[..];
hprintln!("").unwrap();
hprintln!("a = {}", core::str::from_utf8(&a).unwrap()).unwrap();
......@@ -55,27 +59,40 @@ fn main() -> ! {
// 1. What is the output in the `openocd` (Adapter Output) console?
//
// ** your answer here **
// 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]
// What is the type of `c`?
//
// ** your answer here **
// &u8
//
// What is the type of `a`?
//
// ** your answer here **
// array [u8;4]
//
// What is the type of `i`?
//
// ** your answer here **
//
// usize
// Commit your answers (bare3_1)
//
// 2. Make types of `s`, `bs`, `c`, `a`, `i` explicit.
......@@ -87,6 +104,10 @@ fn main() -> ! {
// Run the program, what happens and why?
//
// ** your answer here **
// The output for a is:
// a =
// a is an array of zeros and when its printed it takes the ascii value of 0
// which is null so it doesnt print anything
//
// Commit your answers (bare3_3)
//
......
......@@ -36,8 +36,8 @@ use address::*;
#[inline(always)]
fn read_u32(addr: u32) -> u32 {
unsafe { core::ptr::read_volatile(addr as *const _) }
//core::ptr::read_volatile(addr as *const _)
// unsafe { core::ptr::read_volatile(addr as *const _) }
core::ptr::read_volatile(addr as *const _)
}
#[inline(always)]
......@@ -56,10 +56,12 @@ fn wait(i: u32) {
#[entry]
fn main() -> ! {
// power on GPIOA
//6.3.9
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,6 +70,7 @@ 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);
......@@ -85,6 +88,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
......@@ -102,12 +106,25 @@ fn main() -> ! {
// What was the error message and explain why.
//
// ** your answer here **
// error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
// --> examples/bare4.rs:40:5
// |
// 40 | core::ptr::read_volatile(addr as *const _)
// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
// |
// = note: consult the function's documentation for information on how to avoid undefined behavior
//
// error: aborting due to previous error
//
// read_voliatile is a unsafe so it panics
//
// 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 **
//
// because rust cant guarantee to know whats on the memmory address
//
// Commit your answers (bare4_2)
//
// 3. Volatile read/writes are explicit *volatile operations* in Rust, while in C they
......@@ -121,14 +138,30 @@ fn main() -> ! {
//
// ** your answer here **
//
// because volatile just reads the momory address so if it is done in the wrong order it
// might read values that are wrong and the use them.
//
// 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 **
//
// // power on GPIOA
// let r = read_u32(RCC_AHB1ENR); // read
// write_u32(RCC_AHB1ENR, r | 1); // set enable
//
// //configure PA5 as output
// let r = read_u32(GPIOA_MODER) & !(0b11 << (5 * 2)); // read and mask
// write_u32(GPIOA_MODER, r | 0b01 << (5 * 2)); // set output mode
//
// if poweron giopa would happen after the config it could cause problems
//
// Without the non-reordering property of `write_volatile/read_volatile` could that happen in theory
// (argue from the point of data dependencies).
//
// ** your answer here **
//
// its important that they are non-reordering because otherwise if a write_volitile is dependent on data from a read_volitile
// and its reorderd it would not have all the relevent data it needs.
//
// Commit your answers (bare4_3)
......@@ -9,16 +9,18 @@
#![no_std]
#![no_main]
extern crate panic_halt;
extern crate panic_semihosting;
extern crate cortex_m;
use cortex_m_rt::entry;
use cortex_m_semihosting::{hprint, hprintln};
// C like API...
mod stm32f40x {
#[allow(dead_code)]
use core::{cell, ptr};
use cortex_m_semihosting::{hprint, hprintln};
#[rustfmt::skip]
mod address {
pub const PERIPH_BASE: u32 = 0x40000000;
......@@ -51,18 +53,30 @@ mod stm32f40x {
}
//modify (reads, modifies a field, and writes the volatile cell)
//
//parameters:
//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) {
unsafe{
let mut mask: u32 = 1;
for i in 0..width{
mask = mask | 1 << i;
}
mask = mask << offset;
let vaoff = (value << offset);
let vaoffmask = vaoff & mask;
let readinvmask = self.read() & !mask;
let finalval = readinvmask |vaoffmask;
hprintln!("{:#b}",finalval);
self.write(finalval);
}
}
}
#[repr(C)]
#[allow(non_snake_case)]
......@@ -141,27 +155,28 @@ 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);
hprintln!("{:?}", 123).unwrap();
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]
......@@ -169,7 +184,7 @@ fn main() -> ! {
let rcc = unsafe { &mut *RCC::get() }; // get the reference to RCC in memory
let gpioa = unsafe { &mut *GPIOA::get() }; // get the reference to GPIOA in memory
// test(); // uncomment to run test
test(); // uncomment to run test
idle(rcc, gpioa);
loop {
continue;
......@@ -188,20 +203,20 @@ fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) {
loop {
// set PA5 high
gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led)
//gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led)
// alternatively to set the bit high we can
// read the value, or with PA5 (bit 5) and write back
// gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
wait(10_000);
// set PA5 low
gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led)
//gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led)
// alternatively to clear the bit we can
// read the value, mask out PA5 (bit 5) and write back
// gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
wait(10_000);
}
}
......
......@@ -14,7 +14,7 @@
extern crate panic_halt;
use cortex_m::iprintln;
use cortex_m_semihosting::hprintln;
use nb::block;
extern crate stm32f4xx_hal as hal;
......@@ -30,7 +30,6 @@ const APP: () = {
// Late resources
TX: Tx<USART2>,
RX: Rx<USART2>,
ITM: ITM,
}
// init runs in an interrupt free section
......@@ -39,8 +38,7 @@ const APP: () = {
let mut core = cx.core;
let device = cx.device;
let stim = &mut core.ITM.stim[0];
iprintln!(stim, "bare8");
hprintln!("bare8");
let rcc = device.RCC.constrain();
......@@ -55,7 +53,7 @@ const APP: () = {
let serial = Serial::usart2(
device.USART2,
(tx, rx),
Config::default().baudrate(115_200.bps()),
Config::default().baudrate(9_600.bps()),
clocks,
)
.unwrap();
......@@ -67,25 +65,23 @@ const APP: () = {
init::LateResources {
TX: tx,
RX: rx,
ITM: core.ITM,
}
}
// idle may be interrupted by other interrupts/tasks in the system
#[idle(resources = [RX, TX, ITM])]
#[idle(resources = [RX, TX])]
fn idle(cx: idle::Context) -> ! {
let rx = cx.resources.RX;
let tx = cx.resources.TX;
let stim = &mut cx.resources.ITM.stim[0];
loop {
match block!(rx.read()) {
Ok(byte) => {
iprintln!(stim, "Ok {:?}", byte);
hprintln!("Ok {:?}", byte);
tx.write(byte).unwrap();
}
Err(err) => {
iprintln!(stim, "Error {:?}", err);
hprintln!("Error {:?}", err);
}
}
}
......
......@@ -8,7 +8,6 @@
//! buffer may overflow.
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
......@@ -20,12 +19,11 @@ extern crate stm32f4xx_hal as hal;
use crate::hal::prelude::*;
use crate::hal::serial::{config::Config, Serial};
use cortex_m::iprintln;
use cortex_m_semihosting::hprintln;
#[entry]
fn main() -> ! {
let mut c = hal::stm32::CorePeripherals::take().unwrap();
let stim = &mut c.ITM.stim[0];
//let stim = &mut c.ITM.stim[0];
let p = hal::stm32::Peripherals::take().unwrap();
......@@ -51,13 +49,13 @@ fn main() -> ! {
let (mut tx, mut rx) = serial.split();
loop {
match block!(rx.read()) {
match rx.read() {
Ok(byte) => {
iprintln!(stim, "Ok {:?}", byte);
hprintln!("Ok {:?}", byte).unwrap();
let _ = tx.write(byte);
}
Err(err) => {
iprintln!(stim, "Error {:?}", err);
hprintln!( "Error {:?}", err).unwrap();
}
}
}
......
source [find interface/stlink.cfg]
#source [find interface/stlink.cfg]
# deprecated
# source [find interface/stlink-v2-1.cfg]
source [find interface/stlink-v2-1.cfg]
transport select hla_swd
# increase working area to 64KB
......