Skip to content

Commit

Permalink
boards: add tutorial board for HOTP tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
bradjc committed Jun 12, 2024
1 parent 9aa754d commit 09821f3
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ members = [
"boards/weact_f401ccu6/",
"boards/configurations/nrf52840dk/nrf52840dk-test-appid-sha256",
"boards/configurations/nrf52840dk/nrf52840dk-test-kernel",
"boards/tutorials/nrf52840dk-hotp-tutorial",
"boards/tutorials/nrf52840dk-thread-tutorial",
"capsules/aes_gcm",
"capsules/core",
Expand Down
19 changes: 19 additions & 0 deletions boards/tutorials/nrf52840dk-hotp-tutorial/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2024.

[package]
name = "nrf52840dk-hotp-tutorial"
version.workspace = true
authors.workspace = true
build = "../../build.rs"
edition.workspace = true

[dependencies]
kernel = { path = "../../../kernel" }
nrf52840 = { path = "../../../chips/nrf52840" }
nrf52840dk = { path = "../../nordic/nrf52840dk" }
capsules-core = { path = "../../../capsules/core" }
capsules-extra = { path = "../../../capsules/extra" }
capsules-system = { path = "../../../capsules/system" }
components = { path = "../../components" }
9 changes: 9 additions & 0 deletions boards/tutorials/nrf52840dk-hotp-tutorial/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2022.

TARGET=thumbv7em-none-eabi
PLATFORM=nrf52840dk-hotp-tutorial

include ../../Makefile.common
include ../../configurations/nrf52840dk/nrf52840dk.mk
9 changes: 9 additions & 0 deletions boards/tutorials/nrf52840dk-hotp-tutorial/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
nRF52840DK Board Definition for the Tock HOTP Tutorial
========================================================

This is the board definition for the nRF52840DK target used in the
[HOTP tutorial](https://book.tockos.org/course/usb-security-key/key-overview).

Please follow the instructions in that tutorial. You may also want to look at
the documentation of the base nRF52840DK board definition
[here](../../nordic/nrf52840dk/README.md).
6 changes: 6 additions & 0 deletions boards/tutorials/nrf52840dk-hotp-tutorial/layout.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* Licensed under the Apache License, Version 2.0 or the MIT License. */
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
/* Copyright Tock Contributors 2023. */

INCLUDE ../../nordic/nrf52840_chip_layout.ld
INCLUDE ../../kernel_layout.ld
201 changes: 201 additions & 0 deletions boards/tutorials/nrf52840dk-hotp-tutorial/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2024.

//! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK).

#![no_std]
// Disable this attribute when documenting, as a workaround for
// https://github.com/rust-lang/rust/issues/62184.
#![cfg_attr(not(doc), no_main)]
#![deny(missing_docs)]

use core::ptr::addr_of_mut;
use kernel::component::Component;
use kernel::debug;
use kernel::hil::usb::Client;
use kernel::platform::{KernelResources, SyscallDriverLookup};
use kernel::static_init;
use kernel::{capabilities, create_capability};
use nrf52840dk_lib::{self, PROCESSES};

// State for loading and holding applications.
// How should the kernel respond when a process faults.
const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
capsules_system::process_policies::PanicFaultPolicy {};

// USB Keyboard HID - for nRF52840dk
type UsbHw = nrf52840::usbd::Usbd<'static>; // For any nRF52840 board.
type KeyboardHidDriver = components::keyboard_hid::KeyboardHidComponentType<UsbHw>;

// HMAC
type HmacSha256Software = components::hmac::HmacSha256SoftwareComponentType<
capsules_extra::sha256::Sha256Software<'static>,
>;
type HmacDriver = components::hmac::HmacComponentType<HmacSha256Software, 32>;

struct Platform {
keyboard_hid_driver: &'static KeyboardHidDriver,
hmac: &'static HmacDriver,
base: nrf52840dk_lib::Platform,
}

const KEYBOARD_HID_DRIVER_NUM: usize = capsules_core::driver::NUM::KeyboardHid as usize;

impl SyscallDriverLookup for Platform {
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
where
F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
{
match driver_num {
capsules_extra::hmac::DRIVER_NUM => f(Some(self.hmac)),
KEYBOARD_HID_DRIVER_NUM => f(Some(self.keyboard_hid_driver)),
_ => self.base.with_driver(driver_num, f),
}
}
}

type Chip = nrf52840dk_lib::Chip;

impl KernelResources<Chip> for Platform {
type SyscallDriverLookup = Self;
type SyscallFilter = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SyscallFilter;
type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<Chip>>::ProcessFault;
type Scheduler = <nrf52840dk_lib::Platform as KernelResources<Chip>>::Scheduler;
type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SchedulerTimer;
type WatchDog = <nrf52840dk_lib::Platform as KernelResources<Chip>>::WatchDog;
type ContextSwitchCallback =
<nrf52840dk_lib::Platform as KernelResources<Chip>>::ContextSwitchCallback;

fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
self
}
fn syscall_filter(&self) -> &Self::SyscallFilter {
self.base.syscall_filter()
}
fn process_fault(&self) -> &Self::ProcessFault {
self.base.process_fault()
}
fn scheduler(&self) -> &Self::Scheduler {
self.base.scheduler()
}
fn scheduler_timer(&self) -> &Self::SchedulerTimer {
self.base.scheduler_timer()
}
fn watchdog(&self) -> &Self::WatchDog {
self.base.watchdog()
}
fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
self.base.context_switch_callback()
}
}

/// Main function called after RAM initialized.
#[no_mangle]
pub unsafe fn main() {
let main_loop_capability = create_capability!(capabilities::MainLoopCapability);

// Create the base board:
let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
nrf52840dk_lib::start();

//--------------------------------------------------------------------------
// HMAC-SHA256
//--------------------------------------------------------------------------

let sha256_sw = components::sha::ShaSoftware256Component::new()
.finalize(components::sha_software_256_component_static!());

let hmac_sha256_sw = components::hmac::HmacSha256SoftwareComponent::new(sha256_sw).finalize(
components::hmac_sha256_software_component_static!(capsules_extra::sha256::Sha256Software),
);

let hmac = components::hmac::HmacComponent::new(
board_kernel,
capsules_extra::hmac::DRIVER_NUM,
hmac_sha256_sw,
)
.finalize(components::hmac_component_static!(HmacSha256Software, 32));

//--------------------------------------------------------------------------
// KEYBOARD
//--------------------------------------------------------------------------

// Create the strings we include in the USB descriptor.
let strings = static_init!(
[&str; 3],
[
"Nordic Semiconductor", // Manufacturer
"nRF52840dk - TockOS", // Product
"serial0001", // Serial number
]
);

let usb_device = &nrf52840_peripherals.usbd;

// Generic HID Keyboard component usage
let (keyboard_hid, keyboard_hid_driver) = components::keyboard_hid::KeyboardHidComponent::new(
board_kernel,
capsules_core::driver::NUM::KeyboardHid as usize,
usb_device,
0x1915, // Nordic Semiconductor
0x503a,
strings,
)
.finalize(components::keyboard_hid_component_static!(UsbHw));

keyboard_hid.enable();
keyboard_hid.attach();

//--------------------------------------------------------------------------
// PLATFORM SETUP, SCHEDULER, AND START KERNEL LOOP
//--------------------------------------------------------------------------

let platform = Platform {
base: base_platform,
keyboard_hid_driver,
hmac,
};

// These symbols are defined in the linker script.
extern "C" {
/// Beginning of the ROM region containing app images.
static _sapps: u8;
/// End of the ROM region containing app images.
static _eapps: u8;
/// Beginning of the RAM region for app memory.
static mut _sappmem: u8;
/// End of the RAM region for app memory.
static _eappmem: u8;
}

let process_management_capability =
create_capability!(capabilities::ProcessManagementCapability);

kernel::process::load_processes(
board_kernel,
chip,
core::slice::from_raw_parts(
core::ptr::addr_of!(_sapps),
core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
),
core::slice::from_raw_parts_mut(
core::ptr::addr_of_mut!(_sappmem),
core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
),
&mut *addr_of_mut!(PROCESSES),
&FAULT_RESPONSE,
&process_management_capability,
)
.unwrap_or_else(|err| {
debug!("Error loading processes!");
debug!("{:?}", err);
});

board_kernel.kernel_loop(
&platform,
chip,
Some(&platform.base.ipc),
&main_loop_capability,
);
}

0 comments on commit 09821f3

Please sign in to comment.