I have a bit of embedded development experience, but I am trying to use the Discovery book (https://docs.rust-embedded.org/discovery/index.html) to learn about Rust on the Cortex-4M.
The book has you create a program that flashes an LED on and off at a 1 Hz rate. The code (directly from the book) is as follows:
#![deny(unsafe_code)]
#![no_main]
#![no_std]
use aux5::{entry, prelude::*, Delay, Leds};
#[entry]
fn main() -> ! {
let (mut delay, mut leds): (Delay, Leds) = aux5::init();
let half_period = 500_u16;
loop {
leds[0].on();
delay.delay_ms(half_period);
leds[0].off();
delay.delay_ms(half_period);
}
}
That worked. Then the book says to use the debugger to set the half_period variable to different values. I tried, and it had no impact. So I disassembled the code to get the following. I won't show all of it, but the relevant pieces, below. It starts out by creating space on the stack for local variables, including space for half_period. then it sets half_period to 500 at 0x8000210. However, when it comes time to call the delay.delay_ms function, the value 500 is loaded into r1, rather than reading the value of the variable half_period, see 0x8000234.
So, it seems to be treating my stack variable as a const. I decided to replace half_period with a static named HALF_PERIOD - but the same thing happened.
Next I called rustc directly from the compile line with the option "-C opt-level=0." Same result.
Now, the resulting compiled code has behavior that is correct, but I can no longer use gdb to set the value. Is this a feature of the compiler, to make things more efficient even though I am compiling in debug mode, with no optimization? Or is this a bug, prematurely optimizing code even though optimization is off?
080001ea led_roulette::__cortex_m_rt_main::hdb91259dda246b32:
; fn main() -> ! {
80001ea: 80 b5 push {r7, lr}
80001ec: 6f 46 mov r7, sp
80001ee: 92 b0 sub sp, #72
80001f0: 0a a8 add r0, sp, #40
; let (mut delay, mut leds): (Delay, Leds) = aux5::init();
80001f2: 00 f0 39 f8 bl #114
80001f6: ff e7 b #-2 <led_roulette::__cortex_m_rt_main::hdb91259dda246b32+0xe>
80001f8: 0a a8 add r0, sp, #40
80001fa: 03 a9 add r1, sp, #12
80001fc: 90 e8 1c 50 ldm.w r0, {r2, r3, r4, r12, lr}
8000200: 81 e8 1c 50 stm.w r1, {r2, r3, r4, r12, lr}
8000204: 0f 98 ldr r0, [sp, #60]
8000206: 10 99 ldr r1, [sp, #64]
8000208: 09 91 str r1, [sp, #36]
800020a: 08 90 str r0, [sp, #32]
800020c: 4f f4 fa 70 mov.w r0, #500
; let half_period = 500_u16;
8000210: 27 f8 02 0c strh r0, [r7, #-2]
; loop {
8000214: ff e7 b #-2 <led_roulette::__cortex_m_rt_main::hdb91259dda246b32+0x2c>
; leds[0].on();
8000216: 43 f6 e0 12 movw r2, #14816
800021a: c0 f6 00 02 movt r2, #2048
800021e: 08 a8 add r0, sp, #32
8000220: 00 21 movs r1, #0
8000222: 00 f0 57 fa bl #1198
8000226: 02 90 str r0, [sp, #8]
8000228: ff e7 b #-2 <led_roulette::__cortex_m_rt_main::hdb91259dda246b32+0x40>
800022a: 02 98 ldr r0, [sp, #8]
800022c: 00 f0 71 fa bl #1250
8000230: ff e7 b #-2 <led_roulette::__cortex_m_rt_main::hdb91259dda246b32+0x48>
8000232: 03 a8 add r0, sp, #12
8000234: 4f f4 fa 71 mov.w r1, #500
; delay.delay_ms(half_period);
8000238: 02 f0 2a fc bl #10324
800023c: ff e7 b #-2 <led_roulette::__cortex_m_rt_main::hdb91259dda246b32+0x54>
[remainder deleted]