Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTT logging, probe-run #358

Merged
merged 10 commits into from
May 13, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "gdb-multiarch -q -x openocd.gdb"
runner = "probe-run --chip STM32H743ZITx --speed 30000"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does probe-run spin up a GDB server as well? Or is this just a command to program the chip?

Copy link
Member

@ryan-summers ryan-summers May 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I'd prefer if we kept around an easy way to spin up GDB, which was previously cargo run. The command-line way to flash was previously just cargo embed --bin dual-iir, and cargo run --bin dual-iir was meant for interactive debug

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still two ways to flash and while still getting gdb access as before. Just the command to start gdb changes.

You can still use cargo embed to flash in the same way. That doesn't change. The command to start GDB becomes a bit longer.
The tooling for GDB+openocd is (a) significantly more complex to install (b) we don't test it, (c) doesn't provide usable logging, and (d) it isn't used as frequently compared to "just" flashing. Therefore I'd rather have a low entry barrier, streamlined runner that gives me backtraces and convenient logging for debugging.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, probe-run gives a logging interface. That's no issue - I can get gdb set up locally or see if I can make a custom cargo profile or something.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A cargo profile might be nice for gdb.

# runner = "gdb-multiarch -q -x openocd.gdb"
rustflags = [
"-C", "link-arg=-Tlink.x",
# The target (below) defaults to cortex-m4
# There currently are two different options to go beyond that:
# 1. cortex-m7 has the right flags and instructions (FPU) but no instruction schedule yet
# "-C", "target-cpu=cortex-m7",
# 2. cortex-m4 with the additional fpv5 instructions and a potentially
# better-than-nothing instruction schedule
"-C", "target-feature=+fp-armv8d16",
# When combined they are equivalent to (1) alone
"-C", "link-arg=--nmagic",
"-C", "target-cpu=cortex-m7",
]

[build]
Expand Down
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added

* Telemetry
* RTT logging

### Changed

* Const generics bumping the MSRV to 1.51.0
* Const generics, bumping the MSRV to 1.51.0
* `lockin-internal` and `lockin-external` have been merged into `lockin`
* Set target CPU to cortex-m7, effectively bumping the MSRV to 1.52.0

### Fixed

Expand Down
60 changes: 28 additions & 32 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ members = ["ad9959", "dsp"]
[dependencies]
cortex-m = { version = "0.6", features = ["const-fn"] }
cortex-m-rt = { version = "0.6", features = ["device"] }
cortex-m-log = { version = "0.7", features = ["log-integration"] }
log = "0.4"
panic-semihosting = { version = "0.5", optional = true }
log = { version = "0.4", features = ["max_level_trace", "release_max_level_info"] }
rtt-target = { version = "0.2.1", features = ["cortex-m"] }
rtt-logger = { version = "0.1" }
serde = { version = "1.0", features = ["derive"], default-features = false }
heapless = { version = "0.6", features = ["serde"] }
cortex-m-rtic = "0.5.6"
Expand Down Expand Up @@ -69,7 +69,6 @@ git = "https://github.com/quartiq/minimq.git"
rev = "d2ec3e8"

[features]
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]
bkpt = [ ]
nightly = ["cortex-m/inline-asm", "dsp/nightly"]
pounder_v1_1 = [ ]
Expand Down
43 changes: 27 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

## Applications

The Stabilizer firmware offeres a library of hardware and software functionality
exposing input/output, timing, and digital signal processing features.
An application can compose and configure these hardware and software components
to implement different use cases. Several applications are provides by default
This firmware offers a library of hardware and software functionality targeting the use of the Stabilizer hardware in various digital signal processing applications commonly occurring in Quantum Technology.
It provides abstractions over the fast analog inputs and outputs, time stamping, Pounder DDS interfaces and a collection of tailored and optimized digital signal processing algorithms (IIR, FIR, Lockin, PLL, reciprocal PLL, Unwrapper, Lowpass, Cosine-Sine, Atan2).
An application can compose and configure these hardware and software components to implement different use cases.
Several applications are provides by default:

### Dual-IIR

Expand All @@ -31,23 +31,34 @@ to implement different use cases. Several applications are provides by default

### Lockin

* Up to 800 kHz sampling
* Up to 400 kHz modulation frequency
* Reciprocal PLL for external reference
* Internal reference
* Adjustable PLL and locking time constants
* Adjustable phase offset and harmonic index
* Different output modes (in-phase, quadrature, magnitude, log2 power, phase, frequency)

## Minimal bootstrapping documentation

* Clone or download this
* Get [rustup](https://rustup.rs/)
* `rustup target add thumbv7em-none-eabihf`
* `cargo build --release`
* Minimum supported Rust version (MSRV) is 1.51.0
* Minimum supported Rust version (MSRV) is 1.52.0
* Install target support: `rustup target add thumbv7em-none-eabihf`
* Install `probe-run`: `cargo install probe-run`
* `cargo run --release --bin dual-iir`
* When using debug (non `--release`) mode, increase the sample interval significantly.
The added error checking code and missing optimizations may lead to the code
missing deadlines and panicing.

### Using Cargo-embed
## Alternative flashing tools

### Cargo-embed

* Install `cargo-embed`: `cargo install cargo-embed`
* Program the device: `cargo embed --bin dual-iir --release`

### Using GDB/OpenOCD
### GDB/OpenOCD

* Get a recent openocd, a JTAG adapter ("st-link" or some clone) and
everything connected and permissions setup. Most
Expand All @@ -57,24 +68,24 @@ to implement different use cases. Several applications are provides by default
* `openocd -f stabilizer.cfg` and leave it running
* `cargo run --release`

### Using USB-DFU
### USB-DFU

* Get [cargo-binutils](https://github.com/rust-embedded/cargo-binutils/)
* `cargo objcopy --release --bin dual-iir -- -O binary dual-iir.bin` or `arm-none-eabi-objcopy -O binary target/thumbv7em-none-eabihf/release/dual-iir dual-iir.bin`
* Install the DFU USB tool (`dfu-util`)
* Connect to the Micro USB connector below the RJ45
* Short JC2/BOOT
* Get [cargo-binutils](https://github.com/rust-embedded/cargo-binutils/)
* `cargo objcopy --release --bin dual-iir -- -O binary dual-iir.bin` or `arm-none-eabi-objcopy -O binary target/thumbv7em-none-eabihf/release/dual-iir dual-iir.bin`
* `dfu-util -a 0 -s 0x08000000:leave -D dual-iir.bin`

### Using ST-Link virtual mass storage
### ST-Link virtual mass storage

* Get [cargo-binutils](https://github.com/rust-embedded/cargo-binutils/)
* `cargo objcopy --release --bin dual-iir -- -O binary dual-iir.bin` or `arm-none-eabi-objcopy -O binary target/thumbv7em-none-eabihf/release/dual-iir dual-iir.bin`
* Prepare `dual-iir.bin` like above
* Connect the ST-Link debugger
* copy `dual-iir.bin` to the `NODE_H743ZI` USB disk
* Copy `dual-iir.bin` to the `NODE_H743ZI` virtual mass storage device

## Protocol

Stabilizer can be configured via MQTT. Refer to
[`miniconf`](https://github.com/quartiq/miniconf) for more information about topics.
A basic command line interface is available in [`miniconf.py`](miniconf.py).
Telemetry is published via MQTT as well.
7 changes: 5 additions & 2 deletions hitl/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ python3 -m venv --system-site-packages py
. py/bin/activate
python3 -m pip install -r requirements.txt

cargo flash --elf target/thumbv7em-none-eabihf/release/dual-iir --chip STM32H743ZITx
probe-run --chip STM32H743ZITx target/thumbv7em-none-eabihf/release/dual-iir &

# Before attempting to ping the device, sleep to allow Stabilizer to boot.
# Sleep to allow flashing, booting, DHCP, MQTT
sleep 30

# Test pinging Stabilizer. This exercises that:
Expand All @@ -30,3 +30,6 @@ ping -c 5 -w 20 stabilizer-hitl
python3 miniconf.py dt/sinara/dual-iir/04-91-62-d9-7e-5f afe/0='"G2"'
python3 miniconf.py dt/sinara/dual-iir/04-91-62-d9-7e-5f afe/0='"G1"' iir_ch/0/0=\
'{"y_min": -32767, "y_max": 32767, "y_offset": 0, "ba": [1.0, 0, 0, 0, 0]}'

kill $(jobs -p)
wait || true
25 changes: 14 additions & 11 deletions src/hardware/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,19 +145,19 @@ pub fn setup(
.pll2_q_ck(100.mhz())
.freeze(vos, &device.SYSCFG);

#[cfg(feature = "semihosting")]
// Set up RTT logging
{
use cortex_m_log::log::{init as init_log, Logger};
use cortex_m_log::printer::semihosting::{hio::HStdout, InterruptOk};
use log::LevelFilter;
static mut LOGGER: Option<Logger<InterruptOk<HStdout>>> = None;
let logger = Logger {
inner: InterruptOk::<_>::stdout().unwrap(),
level: LevelFilter::Info,
};
let logger = unsafe { LOGGER.get_or_insert(logger) };
// Enable debug during WFE/WFI-induced sleep
device.DBGMCU.cr.modify(|_, w| w.dbgsleep_d1().set_bit());

use rtt_logger::RTTLogger;

init_log(logger).unwrap();
static LOGGER: RTTLogger = RTTLogger::new(log::LevelFilter::Info);
rtt_target::rtt_init_print!(NoBlockSkip, 1024);
log::set_logger(&LOGGER)
.map(|()| log::set_max_level(log::LevelFilter::Trace))
.unwrap();
log::info!("starting...");
}

// Set up the system timer for RTIC scheduling.
Expand Down Expand Up @@ -537,6 +537,7 @@ pub fn setup(
&mut eeprom_i2c,
&mut delay,
));
log::info!("EUI48: {}", mac_addr);

let network_devices = {
// Configure the ethernet controller
Expand Down Expand Up @@ -673,6 +674,7 @@ pub fn setup(
let pounder_pgood = gpiob.pb13.into_pull_down_input();
delay.delay_ms(2u8);
let pounder = if pounder_pgood.is_high().unwrap() {
log::info!("Found Pounder");
let ad9959 = {
let qspi_interface = {
// Instantiate the QUADSPI pins and peripheral interface.
Expand Down Expand Up @@ -935,6 +937,7 @@ pub fn setup(
// info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap());
// info!("Built on {}", build_info::BUILT_TIME_UTC);
// info!("{} {}", build_info::RUSTC_VERSION, build_info::TARGET);
log::info!("setup() complete");

// Enable the instruction cache.
core.SCB.enable_icache();
Expand Down
39 changes: 28 additions & 11 deletions src/hardware/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use stm32h7xx_hal as hal;
// Re-export for the DigitalInputs below:
pub use embedded_hal::digital::v2::InputPin;

#[cfg(feature = "semihosting")]
use panic_semihosting as _;

mod adc;
mod afe;
mod configuration;
Expand Down Expand Up @@ -59,17 +56,37 @@ pub use configuration::{setup, PounderDevices, StabilizerDevices};

#[inline(never)]
#[panic_handler]
#[cfg(all(not(feature = "semihosting")))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
let gpiod = unsafe { &*hal::stm32::GPIOD::ptr() };
fn panic(info: &core::panic::PanicInfo) -> ! {
use core::{
fmt::Write,
sync::atomic::{AtomicBool, Ordering},
};
use cortex_m::asm;
use rtt_target::{ChannelMode, UpChannel};

cortex_m::interrupt::disable();

// Recursion protection
static PANICKED: AtomicBool = AtomicBool::new(false);
while PANICKED.load(Ordering::Relaxed) {
asm::bkpt();
}
PANICKED.store(true, Ordering::Relaxed);

// Turn on both red LEDs, FP_LED_1, FP_LED_3
let gpiod = unsafe { &*hal::stm32::GPIOD::ptr() };
gpiod.odr.modify(|_, w| w.odr6().high().odr12().high());
loop {
// Halt
core::sync::atomic::compiler_fence(
core::sync::atomic::Ordering::SeqCst,
);

// Analogous to panic-rtt-target
if let Some(mut channel) = unsafe { UpChannel::conjure(0) } {
channel.set_mode(ChannelMode::BlockIfFull);
writeln!(channel, "{}", info).ok();
}

// Abort
asm::udf();
// Halt
// loop { core::sync::atomic::compiler_fence(Ordering::SeqCst); }
}

#[cortex_m_rt::exception]
Expand Down