Shorthand notes #1

Open
opened 2020-07-10 01:47:18 +00:00 by coolaj86 · 1 comment

Prerequisites (long download + compile)

IMPORTANT!! These steps can easily take 30 MINUTES of downloading and compiling

1. Install basic compiler tools

Mac

# Install XCode Command-Line Tools, if you haven't already
xcode-select --install

Linux

sudo apt install -y git build-essential pkg-config

Windows 10

# Install git, if you don't have it
curl -A MS https://webinstall.dev/git | powershell

# Install vcpkg
git clone https://github.com/microsoft/vcpkg
.\vcpkg\bootstrap-vcpkg.bat

2. Install rust

Mac, Linux:

  1. Install Rust
    curl https://webinstall.dev/rust | bash
    
    export PATH="$HOME/.local/bin:$PATH"
    
    pathman add ~/.cargo/bin
    
    export PATH="$HOME/.cargo/bin:$PATH"
    
  2. Close and re-open your terminal

Note: Follow any on-screen instructions from the rust installer.

We want to make sure that we're all on the same version:

rustup update
rustup toolchain install stable
rustup toolchain install 1.59.0
rustup default 1.59.0

Note: see https://rustup.rs for Windows 10.

FYI: Toolchain Version Locking

Each directory can have its own Rust config. You can explicitly set the version of rust to use for that code.

Let's say you're going to run all of these examples from ~/blue_pill:

mkdir -p ~/blue_pill/
pushd ~/blue_pill/

For this workshop we'll use v1.59.0:

rustup override set 1.59.0

Also, you can explicitly compile a rust program with a particular rust version:

rustup run 1.59.0 \
	cargo install cargo-flash --version 0.12.1

3. Add the ARM Cortex-M toolchain

rustup target install thumbv7m-none-eabi

4. Install the ftdi USB driver

Mac

# Install brew, if you haven't already
curl -sS https://webinstall.dev/brew | bash

# Install libftdi
brew install libftdi

Linux

sudo apt install -y pkg-config libusb-dev libusb-1.0 libftdi1-dev

Windows 10

# Install ftdi
vcpkg install libftdi1:x64-windows-static-md libusb:x64-windows-static-md

5. Install cargo flash for Rust 1.59.0

rustup run 1.59.0 \
	cargo install cargo-flash --version 0.12.1
rustup run 1.59.0 \
	cargo install cargo-embed --version 0.12.0

STOP

Did you read the prerequisites ^^?

Workshop (NOT Prerequisites)

1. Download and Print the schematics

2. Clone the docs repository

mkdir ~/blue_pill/
pushd ~/blue_pill/

git clone https://cgit.pinealservo.com/BluePill_Rust/resources.git ./resources

3. Clone the code repository

mkdir ~/blue_pill/
pushd ~/blue_pill/

git clone https://cgit.pinealservo.com/BluePill_Rust/blue_pill_base ./base/
pushd ./base/

# NOTE: we probably don't need this step now
git reset --hard 5db28da

4. Connect the pill to programmer

The pin order on the programmer may not exactly match the pin order on the board

In most of the parts in the kit, this is what the PIN order looks like:

Blue Pill Programmer (Kit)
GND 3.3v (7,8)
SWCLK GND (5,6)
SWDIO SWDIO (4)
3.3v SWCLK (2)

Example only of programmer pinout (not the same as yours):

DOUBLE CHECK!!!

  • the same color power wire is going to a pin marked 3.3v on both the programmer and the blue pill
  • the same color ground wire is going into a pin marked GND on both

Failure to double check == fried board!

If you're on Windows 10, be sure to install the STLink driver:

Connect Programmer to Computer

Uncap the programmer and plug into a USB port on your computer.

Again: bad 3.3v or GND connection == fried board!

How to know if it worked?

The blue pill should boot up with both

  • red power light
  • blinking green light

If it does not, it could be that it was not programmed with the "hello, world" application.

--list-probes

cargo flash --list-probes
The following devices were found:
[0]: STLink V2 (VID: 0483, PID: 3748, Serial: nGS8LN, STLink)

Note: If you have multiple STLinks connected, you'll want to edit Embed.toml (or maybe it was Cargo.toml with those values.

Console.app on Mac

If you're on Mac you can open Console.app and searching icdd and stm32 from the top-level logs (your computer name).

Unplug and re-plug the programmer device and you should see something like this:

default	20:01:35.105575 -0600	icdd	#ICDebug - 23:{ICWiredBrowser.m} (USB Device first match)
default	20:01:35.106397 -0600	icdd	#ICDebug - 388:{ICWiredBrowser.m} (8 USB Descriptions Managed)
default	20:01:35.109018 -0600	icdd	#ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0x0/0x0/0x0 - 0x14200000 - ICDeviceDescriptionSUQuery)
default	20:01:35.172790 -0600	icdd	#ICDebug - 205:{ICResourceManager.m} (6E009300-0800-0100-1000-130047005300|STM32 STLink|MANUFACTURER:STMicroelectronics;MODEL:STM32 STLink|SW=FALSE|)
default	20:01:35.179788 -0600	icdd	#ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0x0/0x0/0x0 - 0x14200000 - ICDeviceDescriptionAdded)
default	20:01:36.620079 -0600	icdd	#ICDebug - 37:{ICWiredBrowser.m} (USB Interface first match)
default	20:01:36.621099 -0600	icdd	#ICDebug - 388:{ICWiredBrowser.m} (9 USB Descriptions Managed)
default	20:01:36.626026 -0600	icdd	#ICDebug - 205:{ICResourceManager.m} (00000000-0000-0000-0000-000004833748|STM32 STLink|(null)|SW=FALSE|)
default	20:01:36.626032 -0600	icdd	#ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0xff/0xff/0xff - 0x14200000 - ICDeviceDescriptionSUQuery)
default	20:01:36.630364 -0600	icdd	#ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0xff/0xff/0xff - 0x14200000 - ICDeviceDescriptionUndefined)

5. Build the sample code

pushd utah-rust-blue-pill-code/

# You have two options:

# A) cargo flash (will build and deploy)
cargo flash --release --chip STM32F103C8

# B) cargo embed (will open debug console)
#    (relies on the Embed.toml)
cargo embed --release
#    (you will need to hit ctrl+c to quit)

Peripherals

When you want to answer the question "How do I make x do y?", you'll be looking here:

I2C

Beginning of each transaction sends the address. Only the listener listens.

I2C I Squared C (like USB for microcontrollers)
SDAx Data
SCLx Clock 100kHz (slow) - 400kHz (fast)

SPI

Has chip select.

CS
0x1
1x2
2x4
3x8

Rotary Encoder: Search: stm32 hal rust rotary encoder

Timers

Each timer has certain constraints

TxCxN

Libraries

Lib Desc
rtt_target Real-Time Trace - allows debug even whether or not a debugger is connected
stm32f1xx_hal::pac (SoC Peripherals) Peripheral Access Crate - autogenerated from SVD (like ARM-standardized XML description
cortex_m (core peripherals) pac-style crate defining functionality common to all Cortex-M

Terms

Term Desc
HAL Hardware-Abstraction Layer
SVD XML-description of CPU (such as ARM Cortex-M) or SoC (such as STM32)
NVIC "Nested Vector" Interrupt Controller is how you get a notification to change control. Interrupts bubble up for dispatch.
SYST SysTick (System Timer) a timer in all ARM processors for measuring intervals, sleeping, delaying, etc (OS-level)
---- ---
FPU Changes or observes the way that Math happens. Useful for really low-level debugging. On some CPUs this could be for directly writing numbers and reading results
rcc Reset & Clock Control (reset peripheral is responsible for putting the hardware in a clean state, required even on boot)
push_pull_output Actively tries to pull a signal high or low

Rust / HAL conventions.

Term Desc
take() there's only one of something and can only be had once
constrain() change the shape of an API
freeze() committing to a configuration, for the life of the program
split() tracks pin ownership - rather than all 16 bits, for example
block! used on synchronous calls that could be async (legacy?)

Sometimes random, seemingly unrelated things must be passed around.

  • Why does the clock need access to the clock?

Although the devices know what they need (as they have 1:1 types - such as apb2), it is explicit for the sake avoiding race or locking conditions, and for documentation to the reader.

Cleaning Up

Set the default rust toolchain version back to stable:

rustup default stable

Errors

Probe could not be created

cargo-flash 0.9.0 gives me this error. The instructions have been updated to use cargo-flash 0.8.0:

    Finished release [optimized + debuginfo] target(s) in 1.15s
    Flashing /Users/aj/BluePill_Rust/utah-rust-blue-pill-code/target/thumbv7m-none-eabi/release/blue_pill_base
       Error Probe could not be created

Caused by:
    0: Pipe error
    1: Pipe error

Solution: Use cargo-flash 0.8.0.

Error The config 'default' could not be loaded.

       Error The config 'default' could not be loaded.

             Caused by:
                 enum Level does not have variant constructor Warn

Solution: Use cargo-embed 0.8.0, and update the config

diff --git a/Embed.toml b/Embed.toml
index 8a45ee4..e53456a 100644
--- a/Embed.toml
+++ b/Embed.toml
@@ -13,21 +13,25 @@ protocol = "Swd"
 [default.flashing]
 # Whether or not the target should be flashed.
 enabled = true
-# Whether or not the target should be halted after flashing.
-halt_afterwards = false
 # Whether or not bytes erased but not rewritten with data from the ELF
 # should be restored with their contents before erasing.
 restore_unwritten_bytes = false
 # The path where an SVG of the assembled flash layout should be written to.
 # flash_layout_output_path = "out.svg"

+[default.reset]
+# Whether or not the target should be reset.
+enabled = true
+# Whether or not the target should be halted after flashing.
+halt_afterwards = false
+
 [default.general]
 # The chip name of the chip to be debugged.
 chip = "stm32f103C8"
 # A list of chip descriptions to be loaded during runtime.
 chip_descriptions = []
 # The default log level to be used.
-log_level = "Warn"
+log_level = "WARN"

 [default.rtt]
 # Whether or not an RTTUI should be opened after flashing.

Prior Versions

The last time we did this workshop we used these versions:

  • Rust v1.46.0
  • cargo-flash v0.8.0
  • cargo-embed v0.8.0
[![](https://i.imgur.com/sLh3oU8.jpg)](https://www.youtube.com/watch?v=2tGSJpbZVS8&list=PLDWmoWFf46givBRQmh5DyE27OsXMJPfag) # Prerequisites (long download + compile) IMPORTANT!! These steps can easily take **30 MINUTES** of downloading and compiling ### 1. Install basic compiler tools **Mac** ```bash # Install XCode Command-Line Tools, if you haven't already xcode-select --install ``` **Linux** ```bash sudo apt install -y git build-essential pkg-config ``` **Windows 10** ```pwsh # Install git, if you don't have it curl -A MS https://webinstall.dev/git | powershell # Install vcpkg git clone https://github.com/microsoft/vcpkg .\vcpkg\bootstrap-vcpkg.bat ``` ### 2. Install `rust` Mac, Linux: 1. Install Rust ```bash curl https://webinstall.dev/rust | bash export PATH="$HOME/.local/bin:$PATH" pathman add ~/.cargo/bin export PATH="$HOME/.cargo/bin:$PATH" ``` 2. Close and re-open your terminal Note: Follow any on-screen instructions from the rust installer. We want to make sure that we're all on the same version: ```bash rustup update rustup toolchain install stable rustup toolchain install 1.59.0 rustup default 1.59.0 ``` Note: see https://rustup.rs for Windows 10. #### FYI: Toolchain Version Locking Each directory can have its own Rust config. You can explicitly set the version of rust to use for that code. Let's say you're going to run all of these examples from `~/blue_pill`: ```bash mkdir -p ~/blue_pill/ pushd ~/blue_pill/ ``` For this workshop we'll use v1.59.0: ```bash rustup override set 1.59.0 ``` Also, you can explicitly compile a rust program with a particular rust version: ```bash rustup run 1.59.0 \ cargo install cargo-flash --version 0.12.1 ``` ### 3. Add the ARM Cortex-M toolchain ```bash rustup target install thumbv7m-none-eabi ``` ### 4. Install the ftdi USB driver **Mac** ```bash # Install brew, if you haven't already curl -sS https://webinstall.dev/brew | bash # Install libftdi brew install libftdi ``` **Linux** ```bash sudo apt install -y pkg-config libusb-dev libusb-1.0 libftdi1-dev ``` **Windows 10** ```pwsh # Install ftdi vcpkg install libftdi1:x64-windows-static-md libusb:x64-windows-static-md ``` ### 5. Install `cargo flash` for Rust 1.59.0 ```bash rustup run 1.59.0 \ cargo install cargo-flash --version 0.12.1 rustup run 1.59.0 \ cargo install cargo-embed --version 0.12.0 ``` # STOP Did you read the prerequisites ^^? # Workshop (NOT Prerequisites) ## 1. Download and Print the schematics - https://cgit.pinealservo.com/BluePill_Rust/resources/raw/branch/master/The-Generic-STM32F103-Pinout-Diagram.pdf - https://cgit.pinealservo.com/BluePill_Rust/resources/raw/branch/master/STM32F103C8T620Schematic.pdf ## 2. Clone the docs repository ```bash mkdir ~/blue_pill/ pushd ~/blue_pill/ git clone https://cgit.pinealservo.com/BluePill_Rust/resources.git ./resources ``` ## 3. Clone the code repository ```bash mkdir ~/blue_pill/ pushd ~/blue_pill/ git clone https://cgit.pinealservo.com/BluePill_Rust/blue_pill_base ./base/ pushd ./base/ # NOTE: we probably don't need this step now git reset --hard 5db28da ``` ## 4. Connect the pill to programmer The pin order on the programmer **may not exactly match** the pin order on the board In _most_ of the parts in the kit, this is what the PIN order looks like: | Blue Pill | Programmer (Kit) | | --------- | ---------- | | GND | 3.3v (7,8) | | SWCLK | GND (5,6) | | SWDIO | SWDIO (4) | | 3.3v | SWCLK (2) | **Example only** of programmer pinout (not the same as yours): ![](https://cgit.pinealservo.com/BluePill_Rust/resources/raw/branch/master/stm32-st-link-v2-arduino.png) DOUBLE CHECK!!! - the same color power wire is going to a pin marked 3.3v on both the programmer and the blue pill - the same color ground wire is going into a pin marked GND on both Failure to double check == fried board! ### Windows 10 STLink Driver If you're on Windows 10, be sure to install the STLink driver: - https://www.st.com/en/development-tools/stsw-link009.html ### Connect Programmer to Computer Uncap the programmer and plug into a USB port on your computer. Again: bad 3.3v or GND connection == fried board! ### How to know if it worked? The blue pill should boot up with both - **red power light** - **blinking green light** If it does not, it could be that it was not programmed with the "hello, world" application. #### `--list-probes` ```bash cargo flash --list-probes ``` ```txt The following devices were found: [0]: STLink V2 (VID: 0483, PID: 3748, Serial: nGS8LN, STLink) ``` Note: If you have multiple STLinks connected, you'll want to edit `Embed.toml` (or maybe it was `Cargo.toml` with those values. #### Console.app on Mac If you're on Mac you can open Console.app and searching `icdd` and `stm32` from the top-level logs (your computer name). Unplug and re-plug the programmer device and you should see something like this: ```txt default 20:01:35.105575 -0600 icdd #ICDebug - 23:{ICWiredBrowser.m} (USB Device first match) default 20:01:35.106397 -0600 icdd #ICDebug - 388:{ICWiredBrowser.m} (8 USB Descriptions Managed) default 20:01:35.109018 -0600 icdd #ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0x0/0x0/0x0 - 0x14200000 - ICDeviceDescriptionSUQuery) default 20:01:35.172790 -0600 icdd #ICDebug - 205:{ICResourceManager.m} (6E009300-0800-0100-1000-130047005300|STM32 STLink|MANUFACTURER:STMicroelectronics;MODEL:STM32 STLink|SW=FALSE|) default 20:01:35.179788 -0600 icdd #ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0x0/0x0/0x0 - 0x14200000 - ICDeviceDescriptionAdded) default 20:01:36.620079 -0600 icdd #ICDebug - 37:{ICWiredBrowser.m} (USB Interface first match) default 20:01:36.621099 -0600 icdd #ICDebug - 388:{ICWiredBrowser.m} (9 USB Descriptions Managed) default 20:01:36.626026 -0600 icdd #ICDebug - 205:{ICResourceManager.m} (00000000-0000-0000-0000-000004833748|STM32 STLink|(null)|SW=FALSE|) default 20:01:36.626032 -0600 icdd #ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0xff/0xff/0xff - 0x14200000 - ICDeviceDescriptionSUQuery) default 20:01:36.630364 -0600 icdd #ICDebug - 457:{ICDDMessageCenter.m} (+Add STM32 STLink - 0xff/0xff/0xff - 0x14200000 - ICDeviceDescriptionUndefined) ``` ## 5. Build the sample code ```bash pushd utah-rust-blue-pill-code/ # You have two options: # A) cargo flash (will build and deploy) cargo flash --release --chip STM32F103C8 # B) cargo embed (will open debug console) # (relies on the Embed.toml) cargo embed --release # (you will need to hit ctrl+c to quit) ``` # Peripherals When you want to answer the question "How do I make _x_ do _y_?", you'll be looking here: - [(RM0008) STM32F10xxx Reference manual](https://cgit.pinealservo.com/BluePill_Rust/resources/src/branch/master/STM32%20Manuals/STM32F10xxx_ReferenceManual.pdf) - [stm32f1xx_hal::pac](https://docs.rs/stm32f1xx-hal/0.2.1/stm32f1xx_hal/pac/index.html) ### I2C Beginning of each transaction sends the address. Only the listener listens. | I2C | I Squared C (like USB for microcontrollers) | | ---- | ------------------------------------------- | | SDAx | Data | | SCLx | Clock 100kHz (slow) - 400kHz (fast) | - 0.96 OLED Display: [Search: rust hal stm32 0.96 oled](https://www.google.com/search?q=rust+hal+stm32+0.96+oled) (hint: SSD1306) - Bonus: [Search: rust embedded graphics](https://www.google.com/search?q=rust+embedded+graphics) ### SPI Has chip select. | CS | | --- | | 0x1 | | 1x2 | | 2x4 | | 3x8 | Rotary Encoder: [Search: stm32 hal rust rotary encoder](https://www.google.com/search?q=stm32+hal+rust+rotary+encoder) ### Timers Each timer has certain constraints TxCxN # Libraries | Lib | Desc | | --- | --- | | [`rtt_target`][rt] | Real-Time Trace - allows debug even whether or not a debugger is connected| | [`stm32f1xx_hal::pac`][halp] | (SoC Peripherals) **P**eripheral **A**ccess **C**rate - autogenerated from SVD (like ARM-standardized XML description | | [`cortex_m`][cm] | (core peripherals) *pac*-style crate defining functionality common to all Cortex-M | [halp]: https://docs.rs/stm32f1xx-hal/0.2.1/stm32f1xx_hal/pac/index.html [rt]: https://crates.io/crates/rtt_target [cm]: https://crates.io/crates/cortex-m # Terms | Term | Desc | | ---- | ----- | | HAL | Hardware-Abstraction Layer | | SVD | XML-description of CPU (such as ARM Cortex-M) or SoC (such as STM32) | | NVIC | "Nested Vector" Interrupt Controller is how you get a notification to change control. Interrupts bubble up for dispatch. | | SYST | _SysTick_ (System Timer) a timer in all ARM processors for measuring intervals, sleeping, delaying, etc (OS-level) | | ---- | --- | | FPU | Changes or observes the way that Math happens. Useful for _really_ low-level debugging. On some CPUs this could be for directly writing numbers and reading results | | `rcc` | Reset & Clock Control (reset peripheral is responsible for putting the hardware in a clean state, required even on boot) | | push_pull_output | Actively tries to pull a signal high or low | Rust / HAL conventions. | Term | Desc | | ----------- | ----- | | take() | there's only one of something and can only be had once | | constrain() | change the shape of an API | | freeze() | committing to a configuration, for the life of the program | | split() | tracks pin ownership - rather than all 16 bits, for example | | block! | used on synchronous calls that could be async (legacy?) | Sometimes random, seemingly unrelated things must be passed around. - Why does the clock need access to the clock? Although the devices know what they need (as they have 1:1 types - such as `apb2`), it is explicit for the sake avoiding race or locking conditions, and for documentation to the reader. ## Cleaning Up Set the default rust toolchain version back to `stable`: ``` rustup default stable ``` # Errors ## Probe could not be created `cargo-flash 0.9.0` gives me this error. The instructions have been updated to use `cargo-flash 0.8.0`: ``` Finished release [optimized + debuginfo] target(s) in 1.15s Flashing /Users/aj/BluePill_Rust/utah-rust-blue-pill-code/target/thumbv7m-none-eabi/release/blue_pill_base Error Probe could not be created Caused by: 0: Pipe error 1: Pipe error ``` #### Solution: Use `cargo-flash 0.8.0`. ## Error The config 'default' could not be loaded. ```txt Error The config 'default' could not be loaded. Caused by: enum Level does not have variant constructor Warn ``` #### Solution: Use `cargo-embed 0.8.0`, and update the config ```diff diff --git a/Embed.toml b/Embed.toml index 8a45ee4..e53456a 100644 --- a/Embed.toml +++ b/Embed.toml @@ -13,21 +13,25 @@ protocol = "Swd" [default.flashing] # Whether or not the target should be flashed. enabled = true -# Whether or not the target should be halted after flashing. -halt_afterwards = false # Whether or not bytes erased but not rewritten with data from the ELF # should be restored with their contents before erasing. restore_unwritten_bytes = false # The path where an SVG of the assembled flash layout should be written to. # flash_layout_output_path = "out.svg" +[default.reset] +# Whether or not the target should be reset. +enabled = true +# Whether or not the target should be halted after flashing. +halt_afterwards = false + [default.general] # The chip name of the chip to be debugged. chip = "stm32f103C8" # A list of chip descriptions to be loaded during runtime. chip_descriptions = [] # The default log level to be used. -log_level = "Warn" +log_level = "WARN" [default.rtt] # Whether or not an RTTUI should be opened after flashing. ``` ## Prior Versions The last time we did this workshop we used these versions: - Rust v1.46.0 - cargo-flash v0.8.0 - cargo-embed v0.8.0

@neuberfran You may have better luck with the instructions in the wiki here: https://cgit.pinealservo.com/BluePill_Rust/resources/wiki/Software-Setup

@neuberfran You may have better luck with the instructions in the wiki here: https://cgit.pinealservo.com/BluePill_Rust/resources/wiki/Software-Setup
Sign in to join this conversation.
No Label
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: BluePill_Rust/resources#1
There is no content yet.