Skip to content
Snippets Groups Projects
Commit e63482af authored by Jean-Michel Picod's avatar Jean-Michel Picod
Browse files

Revamp deploy.py

Now the script supports more flashing methods:
- JLink (with tockloader)
- OpenOCD (with tockloader)
- pyOCD
- Nordic DFU
- none (will produce an IntelHex file)

Also merged the contributions from:
- Yihui Xiong to support the Makerdiary USB dongle board
- Dennis Geurts to support Nordic DFU

Doc updated accordingly.

Imported 2 patches for Tock kernel:
- 06-add-set_vector_table_offset.patch (upstream tock/tock#1579)
- 07-nrf52-bootloader.patch (upstream tock/tock#1681)
parent 8b146440
No related branches found
No related tags found
No related merge requests found
# Target configuration for the CTAP2 app on the nRF52840 chip
[target.thumbv7em-none-eabi]
rustflags = [
"-C", "link-arg=-Tnrf52840dk_layout.ld",
"-C", "relocation-model=static",
"-D", "warnings",
]
......@@ -19,8 +19,9 @@ successfully tested on the following boards:
## Disclaimer
This project is proof-of-concept and a research platform. It's still under
development and as such comes with a few limitations:
This project is **proof-of-concept and a research platform**. It is **NOT**
meant for a day to day usage. It's still under development and as such comes
with a few limitations:
### FIDO2
......@@ -53,25 +54,17 @@ For a more detailed guide, please refer to our
./setup.sh
```
2. If Tock OS is already installed on your board, move to the next step.
Otherwise, just run one of the following commands, depending on the board
you have:
2. Next step is to install Tock OS as well as the OpenSK application on your
board (**Warning**: it will erase the locally stored credentials). Run:
```shell
# Nordic nRF52840-DK board
./deploy.py os --board=nrf52840_dk
./deploy.py --board=nrf52840dk --opensk
# Nordic nRF52840-Dongle
./deploy.py os --board=nrf52840_dongle
./deploy.py --board=nrf52840_dongle --opensk
```
3. Next step is to install/update the OpenSK application on your board
(**Warning**: it will erase the locally stored credentials). Run:
```shell
./deploy.py app --opensk
```
4. On Linux, you may want to avoid the need for `root` privileges to interact
3. On Linux, you may want to avoid the need for `root` privileges to interact
with the key. For that purpose we provide a udev rule file that can be
installed with the following command:
......
[package]
name = "nrf52840_dongle_dfu"
version = "0.1.0"
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
build = "build.rs"
edition = "2018"
[profile.dev]
panic = "abort"
lto = false
opt-level = "z"
debug = true
[profile.release]
panic = "abort"
lto = true
opt-level = "z"
debug = true
[[bin]]
path = "../../third_party/tock/boards/nordic/nrf52840_dongle/src/main.rs"
name = "nrf52840_dongle_dfu"
[dependencies]
components = { path = "../../third_party/tock/boards/components" }
cortexm4 = { path = "../../third_party/tock/arch/cortex-m4" }
capsules = { path = "../../third_party/tock/capsules" }
kernel = { path = "../../third_party/tock/kernel" }
nrf52840 = { path = "../../third_party/tock/chips/nrf52840" }
nrf52dk_base = { path = "../../third_party/tock/boards/nordic/nrf52dk_base" }
fn main() {
println!("cargo:rerun-if-changed=layout.ld");
println!("cargo:rerun-if-changed=../../third_party/tock/boards/kernel_layout.ld");
}
MEMORY
{
rom (rx) : ORIGIN = 0x00001000, LENGTH = 188K
prog (rx) : ORIGIN = 0x00030000, LENGTH = 832K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 256K
}
MPU_MIN_ALIGN = 8K;
INCLUDE ../../third_party/tock/boards/kernel_layout.ld
[package]
name = "nrf52840_mdk_dfu"
version = "0.1.0"
authors = ["Yihui Xiong <yihui.xiong@hotmail.com>"]
build = "build.rs"
edition = "2018"
[profile.dev]
panic = "abort"
lto = false
opt-level = "z"
debug = true
[profile.release]
panic = "abort"
lto = true
opt-level = "z"
debug = true
[dependencies]
components = { path = "../../third_party/tock/boards/components" }
cortexm4 = { path = "../../third_party/tock/arch/cortex-m4" }
capsules = { path = "../../third_party/tock/capsules" }
kernel = { path = "../../third_party/tock/kernel" }
nrf52840 = { path = "../../third_party/tock/chips/nrf52840" }
nrf52dk_base = { path = "../../third_party/tock/boards/nordic/nrf52dk_base" }
fn main() {
println!("cargo:rerun-if-changed=layout.ld");
println!("cargo:rerun-if-changed=../../third_party/tock/boards/kernel_layout.ld");
}
MEMORY
{
rom (rx) : ORIGIN = 0x00001000, LENGTH = 188K
prog (rx) : ORIGIN = 0x00030000, LENGTH = 832K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 256K
}
MPU_MIN_ALIGN = 8K;
INCLUDE ../../third_party/tock/boards/kernel_layout.ld
use core::fmt::Write;
use core::panic::PanicInfo;
use cortexm4;
use kernel::debug;
use kernel::debug::IoWrite;
use kernel::hil::led;
use kernel::hil::uart::{self, Configure};
use nrf52840::gpio::Pin;
use crate::CHIP;
use crate::PROCESSES;
struct Writer {
initialized: bool,
}
static mut WRITER: Writer = Writer { initialized: false };
impl Write for Writer {
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
self.write(s.as_bytes());
Ok(())
}
}
impl IoWrite for Writer {
fn write(&mut self, buf: &[u8]) {
let uart = unsafe { &mut nrf52840::uart::UARTE0 };
if !self.initialized {
self.initialized = true;
uart.configure(uart::Parameters {
baud_rate: 115200,
stop_bits: uart::StopBits::One,
parity: uart::Parity::None,
hw_flow_control: false,
width: uart::Width::Eight,
});
}
for &c in buf {
unsafe {
uart.send_byte(c);
}
while !uart.tx_ready() {}
}
}
}
#[cfg(not(test))]
#[no_mangle]
#[panic_handler]
/// Panic handler
pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! {
// The nRF52840 Dongle LEDs (see back of board)
const LED1_PIN: Pin = Pin::P0_23;
let led = &mut led::LedLow::new(&mut nrf52840::gpio::PORT[LED1_PIN]);
let writer = &mut WRITER;
debug::panic(
&mut [led],
writer,
pi,
&cortexm4::support::nop,
&PROCESSES,
&CHIP,
)
}
//! Tock kernel for the Makerdiary nRF52840 MDK USB dongle.
//!
//! It is based on nRF52840 SoC (Cortex M4 core with a BLE transceiver) with
//! many exported I/O and peripherals.
#![no_std]
#![no_main]
#![deny(missing_docs)]
use kernel::component::Component;
#[allow(unused_imports)]
use kernel::{debug, debug_gpio, debug_verbose, static_init};
use nrf52840::gpio::Pin;
use nrf52dk_base::{SpiPins, UartChannel, UartPins};
// The nRF52840 MDK USB Dongle LEDs
const LED1_R_PIN: Pin = Pin::P0_23;
const LED1_G_PIN: Pin = Pin::P0_22;
const LED1_B_PIN: Pin = Pin::P0_24;
// The nRF52840 Dongle button
const BUTTON_PIN: Pin = Pin::P0_18;
const BUTTON_RST_PIN: Pin = Pin::P0_02;
const UART_RTS: Pin = Pin::P0_21;
const UART_TXD: Pin = Pin::P0_20;
const UART_CTS: Pin = Pin::P0_03;
const UART_RXD: Pin = Pin::P0_19;
const SPI_MOSI: Pin = Pin::P0_05;
const SPI_MISO: Pin = Pin::P0_06;
const SPI_CLK: Pin = Pin::P0_07;
/// UART Writer
pub mod io;
// State for loading and holding applications.
// How should the kernel respond when a process faults.
const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic;
// Number of concurrent processes this platform supports.
const NUM_PROCS: usize = 8;
// RAM to be shared by all application processes.
#[link_section = ".app_memory"]
static mut APP_MEMORY: [u8; 0x3C000] = [0; 0x3C000];
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] =
[None, None, None, None, None, None, None, None];
// Static reference to chip for panic dumps
static mut CHIP: Option<&'static nrf52840::chip::Chip> = None;
/// Dummy buffer that causes the linker to reserve enough space for the stack.
#[no_mangle]
#[link_section = ".stack_buffer"]
pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
/// Entry point in the vector table called on hard reset.
#[no_mangle]
pub unsafe fn reset_handler() {
// Loads relocations and clears BSS
nrf52840::init();
let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES));
// GPIOs
let gpio = components::gpio::GpioComponent::new(board_kernel).finalize(
components::gpio_component_helper!(
&nrf52840::gpio::PORT[Pin::P0_04],
&nrf52840::gpio::PORT[Pin::P0_05],
&nrf52840::gpio::PORT[Pin::P0_06],
&nrf52840::gpio::PORT[Pin::P0_07],
&nrf52840::gpio::PORT[Pin::P0_08]
),
);
let button = components::button::ButtonComponent::new(board_kernel).finalize(
components::button_component_helper!((
&nrf52840::gpio::PORT[BUTTON_PIN],
capsules::button::GpioMode::LowWhenPressed,
kernel::hil::gpio::FloatingState::PullUp
)),
);
let led = components::led::LedsComponent::new().finalize(components::led_component_helper!(
(
&nrf52840::gpio::PORT[LED1_R_PIN],
capsules::led::ActivationMode::ActiveLow
),
(
&nrf52840::gpio::PORT[LED1_G_PIN],
capsules::led::ActivationMode::ActiveLow
),
(
&nrf52840::gpio::PORT[LED1_B_PIN],
capsules::led::ActivationMode::ActiveLow
)
));
let chip = static_init!(nrf52840::chip::Chip, nrf52840::chip::new());
CHIP = Some(chip);
nrf52dk_base::setup_board(
board_kernel,
BUTTON_RST_PIN,
&nrf52840::gpio::PORT,
gpio,
LED1_R_PIN,
LED1_G_PIN,
LED1_B_PIN,
led,
UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD)),
&SpiPins::new(SPI_MOSI, SPI_MISO, SPI_CLK),
&None,
button,
true,
&mut APP_MEMORY,
&mut PROCESSES,
FAULT_RESPONSE,
nrf52840::uicr::Regulator0Output::V3_0,
false,
&Some(&nrf52840::usbd::USBD),
chip,
);
}
This diff is collapsed.
......@@ -16,8 +16,9 @@ You will need one the following supported boards:
scenarios as the JTAG probe is already on the board.
* [Nordic nRF52840 Dongle](https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF52840-Dongle)
to have a more practical form factor.
* [Makerdiary nRF52840-MDK USB dongle](https://wiki.makerdiary.com/nrf52840-mdk/).
In the case of the Nordic USB dongle, you will also need the following extra
In the case of the Nordic USB dongle, you may also need the following extra
hardware:
* a [Segger J-Link](https://www.segger.com/products/debug-probes/j-link/) JTAG
......@@ -30,13 +31,18 @@ hardware:
[Tag-Connect TC2050 retainer clip](http://www.tag-connect.com/TC2050-CLIP)
to keep the spring loaded connector pressed to the PCB.
Although [OpenOCD](http://openocd.org/) should be supported we encountered some
issues while trying to flash a firmware with it. Therefore we suggest at the
moment to use a
[Segger J-Link](https://www.segger.com/products/debug-probes/j-link/) probe
instead.
Additionnaly, OpenSK supports other ways to flash your board:
This guide **does not** cover how to setup the JTAG probe on your system.
* [OpenOCD](http://openocd.org/).
* [Segger J-Link](https://www.segger.com/products/debug-probes/j-link/)
(default method).
* [pyOCD](https://pypi.org/project/pyocd/).
* [nrfutil](https://pypi.org/project/nrfutil/) for the USB dongle boards that
supports it, which allows you to directly flash a working board over USB
without additional hardware.
This guide **does not** cover how to setup the JTAG probe and their related
tools on your system.
### Software
......@@ -141,17 +147,17 @@ Our build script `build.rs` is responsible for converting `opensk_cert.pem` and
1. Connect a micro USB cable to the JTAG USB port.
1. Run our script for compiling/flashing Tock OS on your device (_output may
differ_):
1. Run our script for compiling/flashing Tock OS and OpenSK on your device
(_output may differ_):
```shell
$ ./deploy.py os --board=nrf52840_dk
$ ./deploy.py --board=nrf52840dk --opensk
info: Updating rust toolchain to nightly-2020-02-03
info: syncing channel updates for 'nightly-2020-02-03-x86_64-unknown-linux-gnu'
info: checking for self-updates
info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date
info: Rust toolchain up-to-date
info: Installing Tock on board nrf52840_dk
info: Building Tock OS for board nrf52840dk
Compiling tock-registers v0.5.0 (./third_party/tock/libraries/tock-register-interface)
Compiling tock-cells v0.1.0 (./third_party/tock/libraries/tock-cells)
Compiling enum_primitive v0.1.0 (./third_party/tock/libraries/enum_primitive)
......@@ -166,47 +172,17 @@ Our build script `build.rs` is responsible for converting `opensk_cert.pem` and
Compiling nrf52840 v0.1.0 (./third_party/tock/chips/nrf52840)
Compiling components v0.1.0 (./third_party/tock/boards/components)
Compiling nrf52dk_base v0.1.0 (./third_party/tock/boards/nordic/nrf52dk_base)
Finished release [optimized + debuginfo] target(s) in 11.97s
[STATUS ] Flashing binar(y|ies) to board...
[INFO ] Using known arch and jtag-device for known board nrf52dk
[INFO ] Finished in 0.284 seconds
```
1. Run our script for compiling/flashing the OpenSK application on your device
(_output may differ_):
```shell
$ ./deploy.py app --opensk
info: Updating rust toolchain to nightly-2020-02-03
info: syncing channel updates for 'nightly-2020-02-03-x86_64-unknown-linux-gnu'
info: checking for self-updates
info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date
info: Rust toolchain up-to-date
info: Erasing all installed applications
All apps have been erased.
info: Building OpenSK application
Compiling autocfg v1.0.0
Compiling pkg-config v0.3.17
Compiling cc v1.0.50
Compiling libc v0.2.66
Compiling bitflags v1.2.1
Compiling foreign-types-shared v0.1.1
Compiling openssl v0.10.28
Compiling cfg-if v0.1.10
Compiling lazy_static v1.4.0
Compiling byteorder v1.3.2
Compiling linked_list_allocator v0.6.6
Compiling arrayref v0.3.6
Compiling cbor v0.1.0 (./libraries/cbor)
Compiling subtle v2.2.2
Compiling foreign-types v0.3.2
Compiling libtock v0.1.0 (./third_party/libtock-rs)
Compiling crypto v0.1.0 (./libraries/crypto)
Compiling openssl-sys v0.9.54
Compiling ctap2 v0.1.0 (.)
Finished release [optimized] target(s) in 15.34s
info: Flashing padding application
info: Installing Tock application ctap2
Finished release [optimized + debuginfo] target(s) in 13.15s
info: Converting Tock OS file into a binary
info: Building OpenSK application
Finished release [optimized] target(s) in 0.02s
info: Generating Tock TAB file for application/example ctap2
info: Erasing all installed applications
All apps have been erased.
info: Flashing file third_party/tock/boards/nordic/nrf52840dk/target/thumbv7em-none-eabi/release/nrf52840dk.bin.
info: Flashing padding application
info: Installing Tock application ctap2
info: You're all set!
```
1. Connect a micro USB cable to the device USB port.
......@@ -217,6 +193,8 @@ the board in order to see your OpenSK device on your system.
#### Nordic nRF52840 Dongle
##### Using external programmer (JLink, OpenOCD, etc.)
![Nordic dongle](img/dongle_front.jpg)
1. The JTAG probe used for programming won't provide power to the board.
......@@ -232,17 +210,18 @@ the board in order to see your OpenSK device on your system.
![Nordic dongle retainer clip](img/dongle_clip.jpg)
1. Run our script for compiling/flashing Tock OS on your device (_output may
differ_):
1. Depending on the programmer you're using, you may have to adapt the next
command line. Run our script for compiling/flashing Tock OS on your device
(_output may differ_):
```shell
$ ./deploy.py os --board=nrf52840_dongle
$ ./deploy.py os --board=nrf52840_dongle --programmer=jlink
info: Updating rust toolchain to nightly-2020-02-03
info: syncing channel updates for 'nightly-2020-02-03-x86_64-unknown-linux-gnu'
info: checking for self-updates
info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date
info: Rust toolchain up-to-date
info: Installing Tock on board nrf52840_dongle
info: Building Tock OS for board nrf52840_dongle
Compiling tock-cells v0.1.0 (./third_party/tock/libraries/tock-cells)
Compiling tock-registers v0.5.0 (./third_party/tock/libraries/tock-register-interface)
Compiling enum_primitive v0.1.0 (./third_party/tock/libraries/enum_primitive)
......@@ -258,50 +237,39 @@ the board in order to see your OpenSK device on your system.
Compiling components v0.1.0 (./third_party/tock/boards/components)
Compiling nrf52dk_base v0.1.0 (./third_party/tock/boards/nordic/nrf52dk_base)
Finished release [optimized + debuginfo] target(s) in 11.72s
[STATUS ] Flashing binar(y|ies) to board...
[INFO ] Using known arch and jtag-device for known board nrf52dk
[INFO ] Finished in 0.280 seconds
```
1. Run our script for compiling/flashing the OpenSK application on your device
(_output may differ_):
```shell
$ ./deploy.py app --opensk
info: Updating rust toolchain to nightly-2020-02-03
info: syncing channel updates for 'nightly-2020-02-03-x86_64-unknown-linux-gnu'
info: checking for self-updates
info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date
info: Rust toolchain up-to-date
info: Converting Tock OS file into a binary
info: Building OpenSK application
Finished release [optimized] target(s) in 0.02s
info: Generating Tock TAB file for application/example ctap2
info: Erasing all installed applications
All apps have been erased.
info: Building OpenSK application
Compiling autocfg v1.0.0
Compiling pkg-config v0.3.17
Compiling cc v1.0.50
Compiling libc v0.2.66
Compiling bitflags v1.2.1
Compiling foreign-types-shared v0.1.1
Compiling openssl v0.10.28
Compiling cfg-if v0.1.10
Compiling lazy_static v1.4.0
Compiling byteorder v1.3.2
Compiling linked_list_allocator v0.6.6
Compiling arrayref v0.3.6
Compiling cbor v0.1.0 (./libraries/cbor)
Compiling subtle v2.2.2
Compiling foreign-types v0.3.2
Compiling libtock v0.1.0 (./third_party/libtock-rs)
Compiling crypto v0.1.0 (./libraries/crypto)
Compiling openssl-sys v0.9.54
Compiling ctap2 v0.1.0 (.)
Finished release [optimized] target(s) in 15.34s
info: Flashing file third_party/tock/boards/nordic/nrf52840_dongle/target/thumbv7em-none-eabi/release/nrf52840_dongle.bin.
info: Flashing padding application
info: Installing Tock application ctap2
info: You're all set!
```
1. Remove the programming cable and the USB-A extension cable.
### Advanced installation
Although flashing using a Segger JLink probe is the officially supported way,
our tool, `deploy.py` also supports other methods:
* OpenOCD: `./deploy.py --board=nrf52840_dongle --opensk --programmer=openocd`
* pyOCD: `./deploy.py --board=nrf52840_dongle --opensk --programmer=pyocd`
* Nordic DFU: `./deploy.py --board=nrf52840_dongle --opensk
--programmer=nordicdfu`
* Custom: `./deploy.py --board=nrf52840_dongle --opensk --programmer=none`. In
this case, an IntelHex file will be created and how to program a board is
left to the user.
If your board is already flashed with Tock OS, you may skip installing it:
`./deploy.py --board=nrf52840dk --opensk --no-tockos`
For more options, we invite you to read the help of our `deploy.py` script by
running `./deploy.py --help`.
### Installing the udev rule (Linux only)
By default on Linux, a USB device will require root privilege in order interact
......
diff --git a/arch/cortex-m/src/scb.rs b/arch/cortex-m/src/scb.rs
index 8107f16..a271db9 100644
--- a/arch/cortex-m/src/scb.rs
+++ b/arch/cortex-m/src/scb.rs
@@ -9,7 +9,7 @@ use kernel::common::StaticRef;
struct ScbRegisters {
cpuid: VolatileCell<u32>,
icsr: VolatileCell<u32>,
- vtor: VolatileCell<u32>,
+ vtor: VolatileCell<*const ()>,
aircr: VolatileCell<u32>,
scr: VolatileCell<u32>,
ccr: VolatileCell<u32>,
@@ -54,3 +54,8 @@ pub unsafe fn reset() {
let reset = (0x5FA << 16) | (aircr & (0x7 << 8)) | (1 << 2);
SCB.aircr.set(reset);
}
+
+/// relocate interrupt vector table
+pub unsafe fn set_vector_table_offset(offset: *const ()) {
+ SCB.vtor.set(offset);
+}
diff --git a/chips/nrf52/src/crt1.rs b/chips/nrf52/src/crt1.rs
index 9703aac..281ceeb 100644
--- a/chips/nrf52/src/crt1.rs
+++ b/chips/nrf52/src/crt1.rs
@@ -1,4 +1,4 @@
-use cortexm4::{generic_isr, hard_fault_handler, nvic, svc_handler, systick_handler};
+use cortexm4::{generic_isr, hard_fault_handler, nvic, scb, svc_handler, systick_handler};
use tock_rt0;
/*
@@ -168,5 +168,9 @@ pub unsafe extern "C" fn init() {
tock_rt0::init_data(&mut _etext, &mut _srelocate, &mut _erelocate);
tock_rt0::zero_bss(&mut _szero, &mut _ezero);
+ // Ensure that we are compatible with a bootloader.
+ // For this we need to offset our vector table
+ scb::set_vector_table_offset(BASE_VECTORS.as_ptr() as *const ());
+
nvic::enable_all();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment