Skip to content

Commit 6a791e0

Browse files
Merge #302
302: Tweak 05-led-roulette r=therealprof a=winksaville After doing 06-hello-world I felt some tweaks and cleanup were needed in debug-it.md and the-led-and-delay-abstractions.md. Co-authored-by: Wink Saville <wink@saville.com>
2 parents 102d90d + d5e17f5 commit 6a791e0

File tree

2 files changed

+52
-29
lines changed

2 files changed

+52
-29
lines changed

src/05-led-roulette/debug-it.md

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,55 @@ Continuing.
2020
2121
Breakpoint 1, led_roulette::__cortex_m_rt_main_trampoline () at src/05-led-roulette/src/main.rs:7
2222
7 #[entry]
23-
24-
(gdb) step
25-
led_roulette::__cortex_m_rt_main () at src/05-led-roulette/src/main.rs:10
26-
10 let x = 42;
2723
```
2824

2925
Breakpoints can be used to stop the normal flow of a program. The `continue` command will let the
3026
program run freely *until* it reaches a breakpoint. In this case, until it reaches `#[entry]`
31-
which is a trampoline to to the main function and where `break main` set the breakpoint.
27+
which is a trampoline to the main function and where `break main` sets the breakpoint.
3228

33-
Note that GDB output says "Breakpoint 1". Remember that our processor can only use six of these
34-
breakpoints so it's a good idea to pay attention to these messages.
29+
> **Note** that GDB output says "Breakpoint 1". Remember that our processor can only use six of these
30+
> breakpoints so it's a good idea to pay attention to these messages.
3531
32+
OK. Since we are stopped at `#[entry]` and using the `disassemble /m` we see the code
33+
for entry, which is a trampoline to main. What that means it sets up the stack and then
34+
invokes a subroutine call to the `main` function using an ARM branch and link instruction, `bl`.
35+
```
36+
(gdb) disassemble /m
37+
Dump of assembler code for function main:
38+
8 #[entry]
39+
0x080001ec <+0>: push {r7, lr}
40+
0x080001ee <+2>: mov r7, sp
41+
=> 0x080001f0 <+4>: bl 0x80001f6 <hello_world::__cortex_m_rt_main>
42+
0x080001f4 <+8>: udf #254 ; 0xfe
3643
37-
OK. Since we are stopped at `#[entry]`. We can advance the program statement by statement using
38-
the `step` command. So let's use that twice times to reach the `_y = x` statement. Once you've typed `step`
39-
once you can just hit enter to run it again, but below we type step twice.
44+
End of assembler dump.
45+
```
4046

47+
Next we need to issue a `step` gdb command which will advance the program statement
48+
by statement stepping into functions/procedures. So after this first `step` command we're
49+
inside `main` and are positioned at the first executable `rust` statement, line 10, but it is
50+
**not** executed:
4151
```
4252
(gdb) step
4353
led_roulette::__cortex_m_rt_main () at src/05-led-roulette/src/main.rs:10
4454
10 let x = 42;
55+
```
56+
57+
Next we'll issue a second `step` which executes line 10 and stops at
58+
line `11 _y = x;`, again line 11 is **not** executed.
59+
60+
> **Note** we could have pressed enter at the second `<gdb> ` prompt and
61+
> it would have reissued the previous statement, `step`, but for clarity in this tutorial
62+
> we'll generally retype the command.
63+
64+
```
4565
(gdb) step
4666
11 _y = x;
4767
```
4868

49-
If you are not using the TUI mode, on each `step` call GDB will print back the current statement
50-
along with its line number.
69+
As you can see, in this mode, on each `step` command GDB will print the current statement along
70+
along with its line number. As you'll see later in the TUI mode you'll not the see the statement
71+
in the command area.
5172

5273
We are now "on" the `_y = x` statement; that statement hasn't been executed yet. This means that `x`
5374
is initialized but `_y` is not. Let's inspect those stack/local variables using the `print` command:
@@ -63,13 +84,13 @@ $3 = 536870912
6384
$4 = (*mut i32) 0x20009fe4
6485
```
6586

66-
As expected, `x` contains the value `42`. `_y`, however, contains the value `536870912` (?). Because
67-
`_y` has not been initialized yet, it contains some garbage value.
87+
As expected, `x` contains the value `42`. `_y`, however, contains the value `536870912` (?). This
88+
is because `_y` has not been initialized yet, it contains some garbage value.
6889

6990
The command `print &x` prints the address of the variable `x`. The interesting bit here is that GDB
70-
output shows the type of the reference: `*mut i32`, a mutable pointer to an `i32` value. Another interesting
71-
thing is that the addresses of `x` and `_y` are very close to each other: their addresses are just
72-
`4` bytes apart.
91+
output shows the type of the reference: `*mut i32`, a mutable pointer to an `i32` value. Another
92+
interesting thing is that the addresses of `x` and `_y` are very close to each other: their
93+
addresses are just `4` bytes apart.
7394

7495
Instead of printing the local variables one by one, you can also use the `info locals` command:
7596

@@ -97,9 +118,9 @@ If we use `step` again on top of the `loop {}` statement, we'll get stuck becaus
97118
never pass that statement.
98119

99120
> **NOTE** If you used the `step` or any other command by mistake and GDB gets stuck, you can get
100-
it unstuck by hitting `Ctrl+C`.
121+
> it unstuck by hitting `Ctrl+C`.
101122
102-
You can also use the `disassemble /m` command to disassemble the program around the
123+
As introduced above the `disassemble /m` command can be used to disassemble the program around the
103124
line you are currently at. You might also want to `set print asm-demangle on`
104125
so the names are demangled, this only needs to be done once a debug session. Later
105126
this and other commands will be placed in an initialization file which will simplify
@@ -131,11 +152,11 @@ End of assembler dump.
131152

132153
See the fat arrow `=>` on the left side? It shows the instruction the processor will execute next.
133154

134-
As mentioned above if you were to execute the `step` command GDB gets stuck because it
155+
Also, as mentioned above if you were to execute the `step` command GDB gets stuck because it
135156
is executing a branch instruction to itself and never gets past it. So you need to use
136-
`Ctrl+C`. But you can use the `stepi` GDB command, which steps one instruction, and GDB will print
137-
the address **and** line number of the statement the processor will execute next and
138-
it won't get stuck.
157+
`Ctrl+C` to regain control. An alternative is to use the `stepi` GDB command, which steps
158+
one asm instruction, and GDB will print the address **and** line number of the statement
159+
the processor will execute next and it won't get stuck.
139160

140161
```
141162
(gdb) stepi
@@ -154,11 +175,13 @@ Unable to match requested speed 1000 kHz, using 950 kHz
154175
adapter speed: 950 kHz
155176
target halted due to debug-request, current mode: Thread
156177
xPSR: 0x01000000 pc: 0x08000194 msp: 0x2000a000
178+
157179
(gdb) continue
158180
Continuing.
159181
160182
Breakpoint 1, led_roulette::__cortex_m_rt_main_trampoline () at src/05-led-roulette/src/main.rs:7
161183
7 #[entry]
184+
162185
(gdb) disassemble /m
163186
Dump of assembler code for function main:
164187
7 #[entry]
@@ -170,11 +193,11 @@ Dump of assembler code for function main:
170193
End of assembler dump.
171194
```
172195

173-
We are now back at the beginning of `main`!
196+
We are now back at the beginning of `#[entry]`!
174197

175-
`monitor reset halt` will reset the microcontroller and stop it right at the program entry point.
176-
The following `continue` command will let the program run freely until it reaches the `main`
177-
function that has a breakpoint on it.
198+
`monitor reset halt` will reset the microcontroller and stop it right at the beginning of the program.
199+
The `continue` command will then let the program run freely until it reaches a breakpoint, in
200+
this case it is the breakpoint at `#[entry]`.
178201

179202
This combo is handy when you, by mistake, skipped over a part of the program that you were
180203
interested in inspecting. You can easily roll back the state of your program back to its very

src/05-led-roulette/the-led-and-delay-abstractions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ fn main() -> ! {
344344
let (mut delay, mut leds): (Delay, LedArray) = aux5::init();
345345

346346
let mut half_period = 500_u16;
347-
let v_half_period= Volatile::new(&mut half_period);
347+
let v_half_period = Volatile::new(&mut half_period);
348348

349349
loop {
350350
leds[0].on().ok();
@@ -455,7 +455,7 @@ Dump of assembler code for function _ZN12led_roulette18__cortex_m_rt_main17he1f2
455455
0x08000234 <+38>: strh.w r0, [r7, #-6]
456456
0x08000238 <+42>: subs r0, r7, #6
457457

458-
13 let v_half_period= Volatile::new(&mut half_period);
458+
13 let v_half_period = Volatile::new(&mut half_period);
459459
0x0800023a <+44>: bl 0x800033e <volatile::Volatile<&mut u16, volatile::access::ReadWrite>::new<&mut u16>>
460460
0x0800023e <+48>: str r0, [sp, #68] ; 0x44
461461
0x08000240 <+50>: b.n 0x8000242 <led_roulette::__cortex_m_rt_main+52>

0 commit comments

Comments
 (0)