Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ba80d5e0b | ||
|
|
d6b866a4dd | ||
|
|
e957a7ccc1 | ||
|
|
c7c004bc20 | ||
|
|
ea52aa2ea6 | ||
|
|
ded6d7f3d8 | ||
|
|
037bcc3c64 | ||
|
|
707ad39a62 | ||
|
|
ec972af59a | ||
|
|
389e30a0cd |
@@ -3,7 +3,7 @@
|
|||||||
> Create a time delay.
|
> Create a time delay.
|
||||||
|
|
||||||
Another piece of information you will need is how to create a time delay before moving to the next row.
|
Another piece of information you will need is how to create a time delay before moving to the next row.
|
||||||
We want the time spent switching LED lines on and off to be much shorter than the time spent waiting with LEDs on.
|
we want the time spent switching LED lines on and off to be much shorter than the time spent waiting with LEDs on.
|
||||||
|
|
||||||
### For loop
|
### For loop
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ executing the binary usually has the operating system start by executing the C r
|
|||||||
This in turn invokes the Rust runtime, as marked by the `start` language item,
|
This in turn invokes the Rust runtime, as marked by the `start` language item,
|
||||||
which in turn invokes the main function.
|
which in turn invokes the main function.
|
||||||
|
|
||||||
Having enabled `no_std`, as we are targeting a microcontroller,
|
Having enabled `no_std`, as we are targeting on a microcontroller,
|
||||||
neither the crt0 nor the rust runtime are available,
|
neither the crt0 nor the rust runtime are available,
|
||||||
so even implementing `start` would not help us.
|
so even implementing `start` would not help us.
|
||||||
We need to replace the operating system entry point.
|
We need to replace the operating system entry point.
|
||||||
@@ -149,8 +149,6 @@ Note, you would also need to disable [name mangling][nm]:
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
extern crate panic_halt;
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Flashing is the process of moving our program into the microcontroller's (persistent) memory. Once flashed, the microcontroller will execute the flashed program every time it is powered on.
|
Flashing is the process of moving our program into the microcontroller's (persistent) memory. Once flashed, the microcontroller will execute the flashed program every time it is powered on.
|
||||||
|
|
||||||
In this case, our `microrust-start` program will be the only program in the microcontroller memory. By this I mean that there's nothing else running on the microcontroller: no OS, no daemon, nothing. `microrust-start` has full control over the device. This is what is meant by *bare-metal* programming.
|
In this case, our `rustled` program will be the only program in the microcontroller memory. By this I mean that there's nothing else running on the microcontroller: no OS, no daemon, nothing. `rustled` has full control over the device. This is what is meant by *bare-metal* programming.
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>OS</dt>
|
<dt>OS</dt>
|
||||||
@@ -71,9 +71,8 @@ available.
|
|||||||
I mentioned that OpenOCD provides a GDB server so let's connect to that right now:
|
I mentioned that OpenOCD provides a GDB server so let's connect to that right now:
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
# On Ubuntu use `gdb-mutliarch -q target/thumbv6m-none-eabi/debug//microrust-start`
|
$ arm-none-eabi-gdb -q target/thumbv6m-none-eabi/debug/rustled
|
||||||
$ arm-none-eabi-gdb -q target/thumbv6m-none-eabi/debug/microrust-start
|
Reading symbols from target/thumbv6m-none-eabi/debug/rustled...done.
|
||||||
Reading symbols from target/thumbv6m-none-eabi/debug/microrust-start...done.
|
|
||||||
(gdb)
|
(gdb)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -158,9 +157,9 @@ set print asm-demangle on
|
|||||||
# Load your program, breaks at entry
|
# Load your program, breaks at entry
|
||||||
load
|
load
|
||||||
# (optional) Add breakpoint at function
|
# (optional) Add breakpoint at function
|
||||||
break main
|
break rustled::main
|
||||||
# Continue with execution
|
# Continue with execution
|
||||||
continue
|
continue
|
||||||
```
|
```
|
||||||
|
|
||||||
Now we can learn how to debug code on the micro:bit.
|
Now we can learn how to debug code on the micro:bit.
|
||||||
@@ -6,7 +6,7 @@ Before we start, let's add some code to debug:
|
|||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
// -- snip --
|
// -- snip --
|
||||||
#[entry]
|
entry!(main);
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
let _y;
|
let _y;
|
||||||
let x = 42;
|
let x = 42;
|
||||||
@@ -28,14 +28,14 @@ At this time, we are not interested in that "pre-main" part so let's skip right
|
|||||||
the `main` function. We'll do that using a breakpoint:
|
the `main` function. We'll do that using a breakpoint:
|
||||||
|
|
||||||
```
|
```
|
||||||
(gdb) break main
|
(gdb) break rustled::main
|
||||||
Breakpoint 1 at 0x8000218: file src/main.rs, line 8.
|
Breakpoint 1 at 0x8000218: file src/main.rs, line 8.
|
||||||
|
|
||||||
(gdb) continue
|
(gdb) continue
|
||||||
Continuing.
|
Continuing.
|
||||||
Note: automatically using hardware breakpoints for read-only addresses.
|
Note: automatically using hardware breakpoints for read-only addresses.
|
||||||
|
|
||||||
Breakpoint 1, main () at src/microrust-start/src/main.rs:13
|
Breakpoint 1, rustled::main () at src/rustled/src/main.rs:13
|
||||||
13 let x = 42;
|
13 let x = 42;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -87,15 +87,15 @@ $1 = 42
|
|||||||
$2 = (i32 *) 0x10001fdc
|
$2 = (i32 *) 0x10001fdc
|
||||||
|
|
||||||
(gdb) print _y
|
(gdb) print _y
|
||||||
$3 = -1
|
$3 = 134219052
|
||||||
|
|
||||||
(gdb) print &_y
|
(gdb) print &_y
|
||||||
$4 = (i32 *) 0x10001fd8
|
$4 = (i32 *) 0x10001fd8
|
||||||
```
|
```
|
||||||
|
|
||||||
As expected, `x` contains the value `42`.
|
As expected, `x` contains the value `42`.
|
||||||
`_y` however, contains the value `-1` (?).
|
`_y` however, contains the value `134219052` (?).
|
||||||
Because `_y` has not been initialized yet, it contains `-1`.
|
Because `_y` has not been initialized yet, it contains some garbage value.
|
||||||
|
|
||||||
The command `print &x` prints the address of the variable `x`.
|
The command `print &x` prints the address of the variable `x`.
|
||||||
The interesting bit here is that GDB output shows the type of the reference:
|
The interesting bit here is that GDB output shows the type of the reference:
|
||||||
@@ -108,7 +108,7 @@ Instead of printing the local variables one by one, you can also use the `info l
|
|||||||
```
|
```
|
||||||
(gdb) info locals
|
(gdb) info locals
|
||||||
x = 42
|
x = 42
|
||||||
_y = -1
|
_y = 134219052
|
||||||
```
|
```
|
||||||
|
|
||||||
OK. With another `step`, we'll be on top of the `loop {}` statement:
|
OK. With another `step`, we'll be on top of the `loop {}` statement:
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
In this chapter, we will discuss the basic I/O of embedded development in rust.
|
In this chapter, we will discuss the basic I/O of embedded development in rust.
|
||||||
|
|
||||||
After this chapter, you should have all the neccesary basic knowledge to do embedded development in Rust,
|
After this chapter,you should have all the neccesary basic knowledge to do embedded development in Rust,
|
||||||
with anything remaining being solution specific.
|
with anything remaining being solution specific.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Here are the installation commands for a few Linux distributions.
|
|||||||
``` shell
|
``` shell
|
||||||
$ sudo apt-get install \
|
$ sudo apt-get install \
|
||||||
gcc-arm-none-eabi \
|
gcc-arm-none-eabi \
|
||||||
gdb-multiarch \
|
gdb-arm-none-eabi \
|
||||||
minicom \
|
minicom \
|
||||||
openocd
|
openocd
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Bus 002 Device 033: ID 0d28:0204 NXP ARM mbed
|
|||||||
```
|
```
|
||||||
|
|
||||||
In my case, the micro:bit got connected to the bus #2 and got enumerated as the device #33.
|
In my case, the micro:bit got connected to the bus #2 and got enumerated as the device #33.
|
||||||
This means the file `/dev/bus/usb/002/033` is the micro:bit.
|
This means the file `/dev/bus/usb/002/033` *is* the Fmicro:bit3.
|
||||||
Let's check its permissions:
|
Let's check its permissions:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
|
|||||||
Reference in New Issue
Block a user