Skip to content

Commit bba57d7

Browse files
committed
Embedded test via qemu
1 parent 4826d0c commit bba57d7

File tree

7 files changed

+156
-0
lines changed

7 files changed

+156
-0
lines changed

.github/workflows/rust.yml

+21
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,24 @@ jobs:
5757
override: true
5858
- name: Create Doc
5959
run: cargo doc
60+
Embedded:
61+
runs-on: ubuntu-latest
62+
steps:
63+
- name: Checkout
64+
uses: actions/checkout@v2
65+
- name: Set up QEMU
66+
run: sudo apt update && sudo apt install qemu-system-arm gcc-arm-none-eabi
67+
- name: Checkout Toolchain
68+
uses: actions-rs/toolchain@v1
69+
with:
70+
profile: minimal
71+
toolchain: nightly
72+
override: true
73+
components: rust-src
74+
target: thumbv7m-none-eabi
75+
- name: Run
76+
env:
77+
RUSTFLAGS: "-C link-arg=-Tlink.x"
78+
CARGO_TARGET_THUMBV7M_NONE_EABI_RUNNER: "qemu-system-arm -cpu cortex-m3 -machine mps2-an385 -m 1G -nographic -semihosting-config enable=on,target=native -kernel"
79+
run: cd embedded && cargo run --target thumbv7m-none-eabi
80+

embedded/Cargo.toml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
authors = ["Riccardo Casatta <[email protected]>", "Dev Random <[email protected]>"]
3+
edition = "2018"
4+
readme = "README.md"
5+
name = "embedded"
6+
version = "0.1.0"
7+
8+
[dependencies]
9+
cortex-m = "0.6.0"
10+
cortex-m-rt = "0.6.10"
11+
cortex-m-semihosting = "0.3.3"
12+
panic-halt = "0.2.0"
13+
alloc-cortex-m = "0.4.1"
14+
bitcoin = { path="../", default-features = false, features = ["no-std", "secp-lowmemory"] }
15+
16+
[[bin]]
17+
name = "embedded"
18+
test = false
19+
bench = false
20+
21+
[profile.release]
22+
codegen-units = 1 # better optimizations
23+
debug = true # symbols are nice and they don't increase the size on Flash
24+
lto = true # better optimizations

embedded/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Running
2+
3+
To run the embedded test, first prepare your environment:
4+
5+
```shell
6+
sudo ./scripts/install-deps
7+
rustup target add thumbv7m-none-eabi
8+
```
9+
10+
Then:
11+
12+
```shell
13+
source ./scripts/env.sh && cargo run --target thumbv7m-none-eabi
14+
```
15+
16+
Output should be something like:
17+
18+
```text
19+
heap size 524288
20+
secp buf size 66240
21+
Seed WIF: L1HKVVLHXiUhecWnwFYF6L3shkf1E12HUmuZTESvBXUdx3yqVP1D
22+
Address: bc1qpx9t9pzzl4qsydmhyt6ctrxxjd4ep549np9993
23+
```
24+
25+
Note that this heap size is required because of the amount of stack used by libsecp256k1 when initializing a context.

embedded/memory.x

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
MEMORY
2+
{
3+
FLASH : ORIGIN = 0x00000000, LENGTH = 512K
4+
RAM : ORIGIN = 0x20000000, LENGTH = 512K
5+
}

embedded/scripts/env.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export RUSTFLAGS="-C link-arg=-Tlink.x"
2+
export CARGO_TARGET_THUMBV7M_NONE_EABI_RUNNER="qemu-system-arm -cpu cortex-m3 -machine mps2-an385 -m 1G -nographic -semihosting-config enable=on,target=native -kernel"

embedded/scripts/install-deps

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
apt install gcc-arm-none-eabi qemu-system-arm gdb-multiarch

embedded/src/main.rs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#![feature(alloc_error_handler)]
2+
#![feature(panic_info_message)]
3+
#![no_std]
4+
#![no_main]
5+
6+
extern crate alloc;
7+
extern crate bitcoin;
8+
9+
use alloc::string::ToString;
10+
use alloc::vec;
11+
use core::alloc::Layout;
12+
use core::panic::PanicInfo;
13+
14+
use alloc_cortex_m::CortexMHeap;
15+
// use panic_halt as _;
16+
use bitcoin::{Address, Network, PrivateKey};
17+
use bitcoin::secp256k1::ffi::types::AlignedType;
18+
use bitcoin::secp256k1::Secp256k1;
19+
20+
use cortex_m::asm;
21+
use cortex_m_rt::entry;
22+
use cortex_m_semihosting::{debug, hprintln};
23+
24+
// this is the allocator the application will use
25+
#[global_allocator]
26+
static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
27+
28+
const HEAP_SIZE: usize = 1024 * 512; // 512 KB
29+
30+
#[entry]
31+
fn main() -> ! {
32+
hprintln!("heap size {}", HEAP_SIZE).unwrap();
33+
34+
unsafe { ALLOCATOR.init(cortex_m_rt::heap_start() as usize, HEAP_SIZE) }
35+
36+
let size = Secp256k1::preallocate_size();
37+
hprintln!("secp buf size {}", size*16).unwrap();
38+
39+
// Load a private key
40+
let raw = "L1HKVVLHXiUhecWnwFYF6L3shkf1E12HUmuZTESvBXUdx3yqVP1D";
41+
let pk = PrivateKey::from_wif(raw).unwrap();
42+
hprintln!("Seed WIF: {}", pk).unwrap();
43+
44+
let mut buf_ful = vec![AlignedType::zeroed(); size];
45+
let secp = Secp256k1::preallocated_new(&mut buf_ful).unwrap();
46+
47+
// Derive address
48+
let pubkey = pk.public_key(&secp);
49+
let address = Address::p2wpkh(&pubkey, Network::Bitcoin).unwrap();
50+
hprintln!("Address: {}", address).unwrap();
51+
52+
assert_eq!(address.to_string(), "bc1qpx9t9pzzl4qsydmhyt6ctrxxjd4ep549np9993".to_string());
53+
// exit QEMU
54+
// NOTE do not run this on hardware; it can corrupt OpenOCD state
55+
debug::exit(debug::EXIT_SUCCESS);
56+
57+
loop {}
58+
}
59+
60+
// define what happens in an Out Of Memory (OOM) condition
61+
#[alloc_error_handler]
62+
fn alloc_error(_layout: Layout) -> ! {
63+
hprintln!("alloc error").unwrap();
64+
debug::exit(debug::EXIT_FAILURE);
65+
asm::bkpt();
66+
67+
loop {}
68+
}
69+
70+
#[inline(never)]
71+
#[panic_handler]
72+
fn panic(info: &PanicInfo) -> ! {
73+
hprintln!("panic {:?}", info.message()).unwrap();
74+
debug::exit(debug::EXIT_FAILURE);
75+
loop {}
76+
}

0 commit comments

Comments
 (0)