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/rtic_f4xx_nucleo
  • ironedde/rtic_f4xx_nucleo
  • inaule-6/rtic_f4xx_nucleo
  • rubenasplund/rtic_f4xx_nucleo
4 results
Select Git revision
Loading items
Show changes
Commits on Source (13)
......@@ -6,9 +6,9 @@
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"
runner = "probe-run --chip STM32F411RETx"
# runner = "probe-run --chip STM32F411RETx"
rustflags = [
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
......
......@@ -6,34 +6,23 @@
#![no_std]
use cortex_m::{asm, peripheral::DWT};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use panic_halt as _;
//use panic_rtt_target as _;
use stm32f4;
#[rtic::app(device = stm32f4)]
const APP: () = {
#[init]
fn init(mut cx: init::Context) {
rtt_init_print!();
rprintln!("init");
// Initialize (enable) the monotonic timer (CYCCNT)
cx.core.DCB.enable_trace();
cx.core.DWT.enable_cycle_counter();
rprintln!("start timed_loop");
let (start, end) = timed_loop();
rprintln!(
"start {}, end {}, diff {}",
start,
end,
end.wrapping_sub(start)
);
let (_start, _end) = timed_loop();
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
rprintln!("idle");
loop {
continue;
}
......@@ -60,37 +49,50 @@ fn timed_loop() -> (u32, u32) {
// ------------------------------------------------------------------------
// Exercises:
//
// start 2987, end 4793139, diff 4790152
//
// A.1) What is the cycle count for the loop?
// > cargo run --example rtt_timing
//
// [Your answer here]
// 4790152 cycles
//
// A.2) How many cycles per iteration?
//
// [Your answer here]
// 479.0152 cycles
//
// A.3) Why do we need a wrapping subtraction?
//
// [Your answer here]
// If the end value has wrapped around then start > end. Thus we need to wrap around when we subtract so we get the correct difference value.
//
// ------------------------------------------------------------------------
// Now try a release (optimized build, see `Cargo.toml` for build options).
// B.1) What is the cycle count for the loop?
// > cargo run --example rtt_timing --release
//
// start 30305915, end 30375916, diff 70001
//
// [Your answer here]
// 70001 cycles
//
// B.2) How many cycles per iteration?
//
// [Your answer here]
// 7.0001 cycles
//
// What is the speedup (A/B)?
//
// [Your answer here]
// 479.0152 / 7.0001 = 68.4297652891
//
//
// Why do you think it differs that much?
//
// [Your answer here]
// The unoptimized version has to store and pop all the register every time the nop function call is made. But the optimized version doesn't have to do that because it identifies that most of the registers are not used by the nop function. Thus it is ~68 times faster because there is 32 registers.
//
//
// ------------------------------------------------------------------------
// In the loop there is just a single assembly instruction (nop).
......@@ -112,15 +114,20 @@ fn timed_loop() -> (u32, u32) {
// C.1) What is the cycle count for the loop?
// > cargo run --example rtt_timing --release --features nightly
//
// start 1356808538, end 1356848539, diff 40001
//
// [Your answer here]
// 40001 cycles
//
// C.2) How many cycles per iteration?
//
// [Your answer here]
// 4.0001 cycles
//
// What is the speedup (A/C)?
//
// [Your answer here]
// 479.0152 / 4.0001 = 119.75080623
//
// ------------------------------------------------------------------------
// D) Now lets have a closer look at the generated assembly.
......@@ -131,6 +138,17 @@ fn timed_loop() -> (u32, u32) {
//
// [Assembly for function `timed_loop` here]
//
// 08000232 <timed_loop>:
// 8000232: movw r1, #4100
// 8000236: movw r2, #10000
// 800023a: movt r1, #57344
// 800023e: ldr r0, [r1]
// 8000240: subs r2, #1
// 8000242: nop
// 8000244: bne #-8 <timed_loop+0xe>
// 8000246: ldr r1, [r1]
// 8000248: bx lr
//
// Locate the loop body, and verify that it makes sense
// based on the information from the technical documentation:
//
......@@ -198,11 +216,45 @@ fn timed_loop() -> (u32, u32) {
// https://developer.arm.com/documentation/ddi0439/b/Data-Watchpoint-and-Trace-Unit/DWT-Programmers-Model
//
// [Your answer here]
// No, there is no function call. The two following line loads in the location of the cycle count,
// which is always updated. Thus r1 holds the location of the cycle counter.
// 0x08000232 <+0>: movw r1, #4100 ; 0x1004
// 0x0800023a <+8>: movt r1, #57344 ; 0xe000
// Then the two following lines loads in the current cycle value for start(r0) and end(r1).
// 0x0800023e <+12>: ldr r0, [r1, #0]
// 0x08000246 <+20>: ldr r1, [r1, #0]
//
//
// Now check your answer by dumping the registers
// (gdb) info registers
//
// [Register dump here]
// (gdb) info registers
// r0 0x80000000 -2147483648
// r1 0xe0001004 -536866812
// r2 0x2710 10000
// r3 0xa 10
// r4 0x20000000 536870912
// r5 0x20000430 536871984
// r6 0x0 0
// r7 0x2000ffe8 536936424
// r8 0x0 0
// r9 0x0 0
// r10 0x0 0
// r11 0x0 0
// r12 0x1 1
// sp 0x2000ff98 0x2000ff98
// lr 0x8000373 134218611
// pc 0x800023e 0x800023e <rtt_timing::timed_loop+12>
// xPSR 0x81000000 -2130706432
// fpscr 0x0 0
// msp 0x2000ff98 0x2000ff98
// psp 0x0 0x0
// primask 0x1 1
// basepri 0x0 0
// faultmask 0x0 0
// control 0x0 0
//
//
// We can now set a breakpoint exactly at the `nop`.
//
......@@ -228,6 +280,7 @@ fn timed_loop() -> (u32, u32) {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0x31de3cd8
//
// Now, let's execute one iteration:
// (gdb) continue
......@@ -235,10 +288,12 @@ fn timed_loop() -> (u32, u32) {
// What is now the current value of the cycle counter?
//
// [Your answer here]
// 0x31de3cdc
//
// By how much does the cycle counter increase for each iteration?
//
// [Your answer here]
// 4 cycles
//
// ------------------------------------------------------------------------
// F) Reseting the cycle counter
......@@ -275,9 +330,10 @@ fn timed_loop() -> (u32, u32) {
// (when hitting the `timed_loop` breakpoint)?
//
// [Your answer here]
// 0x00000009 = 9 cycles
//
// ------------------------------------------------------------------------
// F) Finally some statics
// G) Finally some statics
// For embedded it is often/typically crucial to reduce overhead,
// - code footprint (flash memory)
// - memory footprint (sram memory)
......@@ -315,6 +371,10 @@ fn timed_loop() -> (u32, u32) {
// > cargo size --example rtt_timing --release --features nightly
//
// [Your answer here]
// Compiling app v0.1.0 (/home/niklas/Desktop/D7020E/rtic_f4xx_nucleo)
// Finished release [optimized + debuginfo] target(s) in 0.63s
// text data bss dec hex filename
// 660 0 0 660 294 rtt_timing
//
// I was able to get down to:
// > cargo size --example rtt_timing --release --features nightly
......
......@@ -40,9 +40,9 @@ const APP: () = {
rtic::pend(stm32f411::Interrupt::EXTI0);
asm::bkpt();
cx.resources.shared.lock(|shared| {
// asm::bkpt();
asm::bkpt();
*shared += 1;
// asm::bkpt();
asm::bkpt();
});
asm::bkpt();
}
......@@ -72,6 +72,23 @@ const APP: () = {
// Explain what is happening here in your own words.
//
// [Your code here]
// movw r1, #0 = Set registery r1 to 0.
// mrs r0, basepri = Write the contents of the coprocessor register basepri to r0.
// bkpt #0 = breakpoint
// movt r1, #8192 = Set the fist 16-bits to 8192
// ldrd r2, r3, [r1] =
// adds r2, #1 = Adds one to r2.
// adc r3, r3, #0 = Adds r3 and 0 with carry and stores it in r3.
// strd r2, r3, [r1] =
// msr basepri, r0 = Writes the value of r0 into coprocessor register basepri.
// bx lr =
//
// The function starts by loading the priority celling into registry r0.
// Then it loads in the shared variable into register r2.
// Then it add one to the shared variable(r1).
// Then it sets the shared variable.
// Lastly it sets the priority celling back to what it was before.
//
//
// > cargo run --example timing_resources --release --features nightly
// Then continue to the first breakpoint instruction:
......@@ -91,10 +108,25 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x00000010 = 16 cycles
//
// (gdb) disassemble
//
// [Your answer here]
// (gdb) disassemble
// Dump of assembler code for function timing_resources::APP::EXTI0:
// 0x08000232 <+0>: movw r1, #0
// 0x08000236 <+4>: mrs r0, BASEPRI
// => 0x0800023a <+8>: bkpt 0x0000
// 0x0800023c <+10>: movt r1, #8192 ; 0x2000
// 0x08000240 <+14>: ldrd r2, r3, [r1]
// 0x08000244 <+18>: adds r2, #1
// 0x08000246 <+20>: adc.w r3, r3, #0
// 0x0800024a <+24>: strd r2, r3, [r1]
// 0x0800024e <+28>: msr BASEPRI, r0
// 0x08000252 <+32>: bx lr
// End of assembler dump.
//
//
// You should see that we hit the breakpoint in `exti0`, and
// that the code complies to the objdump EXTI disassembly.
......@@ -102,10 +134,12 @@ const APP: () = {
// What was the software latency observed to enter the task?
//
// [Your answer here]
// 16 - 2 = 14 cycles
//
// Does RTIC infer any overhead?
//
// [Your answer here]
// Yes, it add 2 cycles of overhead. Cortex-M4 interupt takes 12 cycles.
//
// The debugger reports that the breakpoint was hit in the `run<closure>`.
// The reason is that the RTIC implements the actual interrupt handler,
......@@ -124,6 +158,7 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x00000025 = 32 + 5 = 37 cycles
//
// You should have a total execution time in the range of 30-40 cycles.
//
......@@ -131,6 +166,9 @@ const APP: () = {
// `exti0` was safe without locking the resource.
//
// [Your answer here]
// I think the reason is that EXTI0 has a higher priorety then EXTI1 which means that EXTI0 will
// never be interupted by EXTI1. And EXTI0 can never interupt EXTI1 when it is using the shared
// variable becaise EXTI1 uses a lock.
//
// In `exti1` we also access `shared` but this time through a lock.
//
......@@ -160,10 +198,12 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x00000034 = 32 + 16 + 4 = 52 cycles
//
// Calculate the total time (in cycles), for this section of code.
//
// [Your answer here]
// 52 - 37 = 15 cycles
//
// You should get a value around 15 cycles.
//
......@@ -204,6 +244,7 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x00000028 = 32 + 8 = 40 cycles
//
// (gdb) c
//
......@@ -214,6 +255,7 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x00000032 = 32 + 16 + 2 = 50 cycles
//
// From a real-time perspective the critical section infers
// blocking (of higher priority tasks).
......@@ -221,6 +263,7 @@ const APP: () = {
// How many clock cycles is the blocking?
//
// [Your answer here]
// 50 - 40 = 10 cycles
//
// Finally continue out of the closure.
//
......@@ -231,6 +274,7 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x00000034 = 32 + 16 + 4 = 52 cycles
//
// This is the total execution time of:
//
......@@ -254,6 +298,19 @@ const APP: () = {
// Motivate your answer (not just a number).
//
// [Your answer here]
// Estimated cost per task:
// Pending the task EXTI1 cost 650 cycles (job latency).
// Starting the thread EXTI1 cost 1522 cycles (job overhead).
// Pending the task EXTI0 cost 650 cycles (job latency).
// Starting the thread EXTI0 cost 1522 cycles (job overhead).
// Locking the shared variable cost 260 cycles ().
// Unlocking the shared variable cost 170 cycles ().
// Returning to EXTI1 cost 1522 cycles (job overhead).
// Locking the shared variable cost 260 cycles ().
// Unlocking the shared variable cost 170 cycles ().
//
//
// The total cost: 650 + 1522 + 650 + 1522 + 260 + 170 + 1522 + 260 + 170 = 6726
//
// Notice, the Rust implementation is significantly faster than the C code version
// of Real-Time For the Masses back in 2013.
......@@ -264,3 +321,10 @@ const APP: () = {
// (Hint, what possible optimization can safely be applied by RTIC + Rust + LLVM.)
//
// [Your answer here]
// From the exercises I have learnt that the RTIC way of handling concurrency is much faster
// because it doesn't have to use locks everywhere. And the lock are much more efficient then the
// ones used in C. RTIC is also much more efficient regarding context switching because it doesn't do it as often.
// Rust provides safety for pointers which C doesn't. This means that it is easier to write shorter
// code in rust, which also can be easily more optimized compared to C. The optimizer for C can
// also be much more aggressive resulting in code that doesn't work as intended.
//
......@@ -82,10 +82,18 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x0000000b = 11 cycles
//
// (gdb) disassemble
//
// [Your answer here]
// (gdb) disassemble
// Dump of assembler code for function timing_task::APP::EXTI0:
// => 0x08000232 <+0>: bkpt 0x0000
// 0x08000234 <+2>: movs r0, #0
// 0x08000236 <+4>: msr BASEPRI, r0
// 0x0800023a <+8>: bx lr
// End of assembler dump.
//
// You should see that we hit the breakpoint in `exti0`, and
// that the code complies to the objdump EXTI disassembly.
......@@ -96,10 +104,14 @@ const APP: () = {
// What was the software latency observed to enter the task?
//
// [Your answer here]
// 11 - 0 = 11 cycles
//
// Does RTIC infer any overhead for launching the task?
//
// [Your answer here]
// No, it doesn't. In the document
// https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/beginner-guide-on-interrupt-latency-and-interrupt-latency-of-the-arm-cortex-m-processors
// it says that the interrupt latency for Cortex-M4 is 12.
//
// Now we can continue to measure the round trip time.
//
......@@ -110,6 +122,8 @@ const APP: () = {
// (gdb) x 0xe0001004
//
// [Your answer here]
// 0xe0001004: 0x00000017 = 16 + 7 = 23 cycles
//
//
// Looking at the EXTI0 (exti0) code, we see two additional
// instructions used to restore the BASEPRI register.
......
This diff is collapsed.
......@@ -21,10 +21,10 @@ const APP: () = {
#[idle]
fn idle(_cx: idle::Context) -> ! {
rprintln!("idle");
// panic!("panic");
loop {
continue;
}
panic!("panic");
// loop {
// continue;
// }
}
};
......@@ -51,6 +51,7 @@ const APP: () = {
// at /home/pln/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.13/src/lib.rs:526
//
// Make sure you got the expected output
// Awnser: Yes, got the expected output.
//
// C) Panic tracing
// Rust is designed for reliability, with the aim to deliver memory safety
......@@ -64,6 +65,30 @@ const APP: () = {
// What is the output?
//
// [Your answer here]
// Compiling app v0.1.0 (/home/niklas/Desktop/D7020E/rtic_f4xx_nucleo)
// error: unreachable expression
// --> src/main.rs:25:9
// |
// 24 | panic!("panic");
// | ---------------- any code following this expression is unreachable
// 25 | / loop {
// 26 | | continue;
// 27 | | }
// | |_________^ unreachable expression
// |
// note: the lint level is defined here
// --> src/main.rs:4:9
// |
// 4 | #![deny(warnings)]
// | ^^^^^^^^
// = note: `#[deny(unreachable_code)]` implied by `#[deny(warnings)]`
//
// error: aborting due to previous error
//
// error: could not compile `app`
//
// To learn more, run the command again with --verbose.
//
//
// D) Panic halt
// Tracing is nice during development, but requires a debugger attached
......@@ -77,12 +102,37 @@ const APP: () = {
// What is the output?
//
// [Your answer here]
// Compiling app v0.1.0 (/home/niklas/Desktop/D7020E/rtic_f4xx_nucleo)
// Finished dev [unoptimized + debuginfo] target(s) in 0.68s
// Running `probe-run --chip STM32F411RETx target/thumbv7em-none-eabi/debug/app`
// (HOST) INFO flashing program (10.53 KiB)
// (HOST) INFO success!
//────────────────────────────────────────────────────────────────────────────────
//init
//idle
//
//
// Now press Ctrl-C
//
// What is the output?
//
// [Your answer here]
//^Cstack backtrace:
// 0: core::sync::atomic::compiler_fence
// at /home/niklas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:2644
// 1: rust_begin_unwind
// at /home/niklas/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-halt-0.2.0/src/lib.rs:33
// 2: core::panicking::panic_fmt
// at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:85
// 3: core::panicking::panic
// at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:50
// 4: app::idle
// at src/main.rs:24
// 5: main
// at src/main.rs:13
// 6: Reset
// at /home/niklas/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.13/src/lib.rs:526
//
//
// E) Find the source
// Figure out how to find the source of `panic_halt`, and look at the implementation.
......@@ -92,3 +142,38 @@ const APP: () = {
//
// Paste the implementation here
// [Your answer here]
////! Set the panicking behavior to halt
////!
////! This crate contains an implementation of `panic_fmt` that simply halt in an infinite loop.
////!
////! # Usage
////!
////! ``` ignore
////! #![no_std]
////!
////! extern crate panic_halt;
////!
////! fn main() {
////! panic!("argument is ignored");
////! }
////! ```
////!
////! # Breakable symbols
////!
////! With the panic handler being `#[inline(never)]` the symbol `rust_begin_unwind` will be
////! available to place a breakpoint on to halt when a panic is happening.
//
//#![deny(missing_docs)]
//#![deny(warnings)]
//#![no_std]
//
//use core::panic::PanicInfo;
//use core::sync::atomic::{self, Ordering};
//
//#[inline(never)]
//#[panic_handler]
//fn panic(_info: &PanicInfo) -> ! {
// loop {
// atomic::compiler_fence(Ordering::SeqCst);
// }
//}
timing_resources: file format elf32-littlearm
Disassembly of section .text:
08000198 <Reset>:
8000198: 80 b5 push {r7, lr}
800019a: 6f 46 mov r7, sp
800019c: 00 f0 aa f8 bl #340
80001a0: 40 f2 08 00 movw r0, #8
80001a4: 40 f2 00 01 movw r1, #0
80001a8: c2 f2 00 00 movt r0, #8192
80001ac: c2 f2 00 01 movt r1, #8192
80001b0: 81 42 cmp r1, r0
80001b2: 14 d2 bhs #40 <Reset+0x46>
80001b4: 40 f2 00 01 movw r1, #0
80001b8: 00 22 movs r2, #0
80001ba: c2 f2 00 01 movt r1, #8192
80001be: 41 f8 04 2b str r2, [r1], #4
80001c2: 81 42 cmp r1, r0
80001c4: 3c bf itt lo
80001c6: 41 f8 04 2b strlo r2, [r1], #4
80001ca: 81 42 cmplo r1, r0
80001cc: 07 d2 bhs #14 <Reset+0x46>
80001ce: 41 f8 04 2b str r2, [r1], #4
80001d2: 81 42 cmp r1, r0
80001d4: 03 d2 bhs #6 <Reset+0x46>
80001d6: 41 f8 04 2b str r2, [r1], #4
80001da: 81 42 cmp r1, r0
80001dc: ef d3 blo #-34 <Reset+0x26>
80001de: 40 f2 00 00 movw r0, #0
80001e2: 40 f2 00 01 movw r1, #0
80001e6: c2 f2 00 00 movt r0, #8192
80001ea: c2 f2 00 01 movt r1, #8192
80001ee: 81 42 cmp r1, r0
80001f0: 1c d2 bhs #56 <Reset+0x94>
80001f2: 40 f2 0c 31 movw r1, #780
80001f6: 40 f2 00 02 movw r2, #0
80001fa: c0 f6 00 01 movt r1, #2048
80001fe: c2 f2 00 02 movt r2, #8192
8000202: 0b 68 ldr r3, [r1]
8000204: 42 f8 04 3b str r3, [r2], #4
8000208: 82 42 cmp r2, r0
800020a: 0f d2 bhs #30 <Reset+0x94>
800020c: 4b 68 ldr r3, [r1, #4]
800020e: 42 f8 04 3b str r3, [r2], #4
8000212: 82 42 cmp r2, r0
8000214: 0a d2 bhs #20 <Reset+0x94>
8000216: 8b 68 ldr r3, [r1, #8]
8000218: 42 f8 04 3b str r3, [r2], #4
800021c: 82 42 cmp r2, r0
800021e: 05 d2 bhs #10 <Reset+0x94>
8000220: cb 68 ldr r3, [r1, #12]
8000222: 10 31 adds r1, #16
8000224: 42 f8 04 3b str r3, [r2], #4
8000228: 82 42 cmp r2, r0
800022a: ea d3 blo #-44 <Reset+0x6a>
800022c: 00 f0 35 f8 bl #106
8000230: fe de trap
08000232 <EXTI0>:
8000232: 40 f2 00 01 movw r1, #0
8000236: ef f3 11 80 mrs r0, basepri
800023a: 00 be bkpt #0
800023c: c2 f2 00 01 movt r1, #8192
8000240: d1 e9 00 23 ldrd r2, r3, [r1]
8000244: 01 32 adds r2, #1
8000246: 43 f1 00 03 adc r3, r3, #0
800024a: c1 e9 00 23 strd r2, r3, [r1]
800024e: 80 f3 11 88 msr basepri, r0
8000252: 70 47 bx lr
08000254 <EXTI1>:
8000254: 41 f2 04 00 movw r0, #4100
8000258: 00 21 movs r1, #0
800025a: ce f2 00 00 movt r0, #57344
800025e: 40 22 movs r2, #64
8000260: 01 60 str r1, [r0]
8000262: 4e f2 00 20 movw r0, #57856
8000266: ce f2 00 00 movt r0, #57344
800026a: 00 be bkpt #0
800026c: 02 60 str r2, [r0]
800026e: e0 20 movs r0, #224
8000270: 00 be bkpt #0
8000272: 80 f3 11 88 msr basepri, r0
8000276: 40 f2 00 00 movw r0, #0
800027a: c2 f2 00 00 movt r0, #8192
800027e: d0 e9 00 23 ldrd r2, r3, [r0]
8000282: 01 32 adds r2, #1
8000284: 43 f1 00 03 adc r3, r3, #0
8000288: c0 e9 00 23 strd r2, r3, [r0]
800028c: f0 20 movs r0, #240
800028e: 80 f3 11 88 msr basepri, r0
8000292: 00 be bkpt #0
8000294: 81 f3 11 88 msr basepri, r1
8000298: 70 47 bx lr
0800029a <main>:
800029a: 4e f2 06 40 movw r0, #58374
800029e: e0 21 movs r1, #224
80002a0: ce f2 00 00 movt r0, #57344
80002a4: 72 b6 cpsid i
80002a6: 40 22 movs r2, #64
80002a8: 01 70 strb r1, [r0]
80002aa: 4e f2 00 11 movw r1, #57600
80002ae: ce f2 00 01 movt r1, #57344
80002b2: 0a 60 str r2, [r1]
80002b4: f0 22 movs r2, #240
80002b6: 42 70 strb r2, [r0, #1]
80002b8: 4e f6 10 52 movw r2, #60688
80002bc: 80 20 movs r0, #128
80002be: ce f2 00 02 movt r2, #57344
80002c2: 08 60 str r0, [r1]
80002c4: 13 68 ldr r3, [r2]
80002c6: 43 f0 02 03 orr r3, r3, #2
80002ca: 13 60 str r3, [r2]
80002cc: d2 f8 ec 30 ldr.w r3, [r2, #236]
80002d0: 43 f0 80 73 orr r3, r3, #16777216
80002d4: c2 f8 ec 30 str.w r3, [r2, #236]
80002d8: 41 f2 00 02 movw r2, #4096
80002dc: ce f2 00 02 movt r2, #57344
80002e0: 13 68 ldr r3, [r2]
80002e2: 43 f0 01 03 orr r3, r3, #1
80002e6: 13 60 str r3, [r2]
80002e8: c1 f8 00 01 str.w r0, [r1, #256]
80002ec: 62 b6 cpsie i
80002ee: 30 bf wfi
80002f0: fd e7 b #-6 <main+0x54>
080002f2 <WWDG>:
80002f2: fe e7 b #-4 <WWDG>
080002f4 <__pre_init>:
80002f4: 70 47 bx lr
080002f6 <HardFaultTrampoline>:
80002f6: 70 46 mov r0, lr
80002f8: 04 21 movs r1, #4
80002fa: 08 42 tst r0, r1
80002fc: 02 d1 bne #4 <HardFaultTrampoline+0xe>
80002fe: ef f3 08 80 mrs r0, msp
8000302: 02 e0 b #4 <HardFault_>
8000304: ef f3 09 80 mrs r0, psp
8000308: ff e7 b #-2 <HardFault_>
0800030a <HardFault_>:
800030a: fe e7 b #-4 <HardFault_>
timing_task: file format elf32-littlearm
Disassembly of section .text:
08000198 <Reset>:
8000198: 80 b5 push {r7, lr}
800019a: 6f 46 mov r7, sp
800019c: 00 f0 74 f8 bl #232
80001a0: 40 f2 00 00 movw r0, #0
80001a4: 40 f2 00 01 movw r1, #0
80001a8: c2 f2 00 00 movt r0, #8192
80001ac: c2 f2 00 01 movt r1, #8192
80001b0: 81 42 cmp r1, r0
80001b2: 14 d2 bhs #40 <Reset+0x46>
80001b4: 40 f2 00 01 movw r1, #0
80001b8: 00 22 movs r2, #0
80001ba: c2 f2 00 01 movt r1, #8192
80001be: 41 f8 04 2b str r2, [r1], #4
80001c2: 81 42 cmp r1, r0
80001c4: 3c bf itt lo
80001c6: 41 f8 04 2b strlo r2, [r1], #4
80001ca: 81 42 cmplo r1, r0
80001cc: 07 d2 bhs #14 <Reset+0x46>
80001ce: 41 f8 04 2b str r2, [r1], #4
80001d2: 81 42 cmp r1, r0
80001d4: 03 d2 bhs #6 <Reset+0x46>
80001d6: 41 f8 04 2b str r2, [r1], #4
80001da: 81 42 cmp r1, r0
80001dc: ef d3 blo #-34 <Reset+0x26>
80001de: 40 f2 00 00 movw r0, #0
80001e2: 40 f2 00 01 movw r1, #0
80001e6: c2 f2 00 00 movt r0, #8192
80001ea: c2 f2 00 01 movt r1, #8192
80001ee: 81 42 cmp r1, r0
80001f0: 1c d2 bhs #56 <Reset+0x94>
80001f2: 40 f2 a0 21 movw r1, #672
80001f6: 40 f2 00 02 movw r2, #0
80001fa: c0 f6 00 01 movt r1, #2048
80001fe: c2 f2 00 02 movt r2, #8192
8000202: 0b 68 ldr r3, [r1]
8000204: 42 f8 04 3b str r3, [r2], #4
8000208: 82 42 cmp r2, r0
800020a: 0f d2 bhs #30 <Reset+0x94>
800020c: 4b 68 ldr r3, [r1, #4]
800020e: 42 f8 04 3b str r3, [r2], #4
8000212: 82 42 cmp r2, r0
8000214: 0a d2 bhs #20 <Reset+0x94>
8000216: 8b 68 ldr r3, [r1, #8]
8000218: 42 f8 04 3b str r3, [r2], #4
800021c: 82 42 cmp r2, r0
800021e: 05 d2 bhs #10 <Reset+0x94>
8000220: cb 68 ldr r3, [r1, #12]
8000222: 10 31 adds r1, #16
8000224: 42 f8 04 3b str r3, [r2], #4
8000228: 82 42 cmp r2, r0
800022a: ea d3 blo #-44 <Reset+0x6a>
800022c: 00 f0 06 f8 bl #12
8000230: fe de trap
08000232 <EXTI0>:
8000232: 00 be bkpt #0
8000234: 00 20 movs r0, #0
8000236: 80 f3 11 88 msr basepri, r0
800023a: 70 47 bx lr
0800023c <main>:
800023c: 4e f2 06 40 movw r0, #58374
8000240: f0 21 movs r1, #240
8000242: ce f2 00 00 movt r0, #57344
8000246: 72 b6 cpsid i
8000248: 4e f6 fc 52 movw r2, #60924
800024c: 01 70 strb r1, [r0]
800024e: 4e f2 00 10 movw r0, #57600
8000252: ce f2 00 00 movt r0, #57344
8000256: 40 21 movs r1, #64
8000258: 01 60 str r1, [r0]
800025a: ce f2 00 02 movt r2, #57344
800025e: 13 68 ldr r3, [r2]
8000260: 43 f0 80 73 orr r3, r3, #16777216
8000264: 13 60 str r3, [r2]
8000266: 41 f2 00 02 movw r2, #4096
800026a: ce f2 00 02 movt r2, #57344
800026e: 13 68 ldr r3, [r2]
8000270: 43 f0 01 03 orr r3, r3, #1
8000274: 13 60 str r3, [r2]
8000276: 00 23 movs r3, #0
8000278: 62 b6 cpsie i
800027a: 53 60 str r3, [r2, #4]
800027c: 00 be bkpt #0
800027e: c0 f8 00 11 str.w r1, [r0, #256]
8000282: 00 be bkpt #0
8000284: fe e7 b #-4 <main+0x48>
08000286 <WWDG>:
8000286: fe e7 b #-4 <WWDG>
08000288 <__pre_init>:
8000288: 70 47 bx lr
0800028a <HardFaultTrampoline>:
800028a: 70 46 mov r0, lr
800028c: 04 21 movs r1, #4
800028e: 08 42 tst r0, r1
8000290: 02 d1 bne #4 <HardFaultTrampoline+0xe>
8000292: ef f3 08 80 mrs r0, msp
8000296: 02 e0 b #4 <HardFault_>
8000298: ef f3 09 80 mrs r0, psp
800029c: ff e7 b #-2 <HardFault_>
0800029e <HardFault_>:
800029e: fe e7 b #-4 <HardFault_>