Merge #125 125: Create stream to stream events from ble scanning functionality merge after #122 r=Woyten a=torfmaster # Summary In this PR I migrate the ble scanning funtionality from callbacks to `futures::stream::Streams`. Only merge after #122 # Questions/Help needed * I decided to make the `BleScanningDriverScanning::stream_values` method to consume `&self` instead of `&mut self`. While I think this is correct it may lead to unexpected behavior when two parallel Tasks consume this stream, i.e. the events are split between the consumers * I only implemented infinite streams as the stream of ble events will be either be stopped at runtime (to a point of time predictable at compile time) or continue to produce values forever. * I removed the possibilty of registering callbacks to the ble driver directly as for me it seemed to be only feasible for trivial business logic. Co-authored-by: torfmaster <briefe@kebes.de>
diff --git a/.travis.yml b/.travis.yml index dae25d0..9a91eaa 100644 --- a/.travis.yml +++ b/.travis.yml
@@ -11,15 +11,42 @@ os: - linux - - osx cache: cargo +# Once Travis supports a version of Ubuntu Disco or newer we can apt install QEMU for RISC-V +# Until then we need to build it ourselves +before_install: +# - sudo apt-get -y install qemu-system-misc +# addons: +# apt: +# update: true + - wget https://download.qemu.org/qemu-4.2.0.tar.xz + - tar xJf qemu-4.2.0.tar.xz + - pushd qemu-4.2.0 + - ./configure --target-list=riscv32-softmmu + - make -j8 + - sudo ln -s $PWD/riscv32-softmmu/qemu-system-riscv32 /usr/bin/ + - popd + install: - rustup target add thumbv7em-none-eabi - rustup target add riscv32imc-unknown-none-elf - rustup component add rustfmt - rustup component add clippy + - cargo install elf2tab --version 0.4.0 + # Build Tock, it needs to be outside of the libtock-rs source + - pushd ../ + - git clone https://github.com/tock/tock.git + - cd tock/boards/hifive1 + # Use a known working version of Tock + - git checkout c94059d3e25dc635e682facff4894ef43b9aca0e + - make + - popd script: - ./run_all_checks.sh + # Run a QEMU instance of the HiFive1 app + - PLATFORM=riscv32 cargo rrv32imac --example hello_world + - timeout --foreground 10s qemu-system-riscv32 -M sifive_e -kernel ../tock/boards/hifive1/target/riscv32imac-unknown-none-elf/release/hifive1 -device loader,file=./target/riscv32imac-unknown-none-elf/tab/riscv32/hello_world/rv32imac.tbf,addr=0x20430000 -nographic | tee serial + - grep "Hello Tock World" serial
diff --git a/Cargo.toml b/Cargo.toml index c94d15f..2fcb4bf 100644 --- a/Cargo.toml +++ b/Cargo.toml
@@ -12,13 +12,13 @@ core = { package = "async-support", path = "async-support" } libtock_codegen = { path = "codegen" } linked_list_allocator = { optional = true, version = "=0.6.5", default-features = false } +futures = { version = "0.3.1", default-features = false, features = ["unstable", "cfg-target-has-atomic"] } [dev-dependencies] corepack = { version = "0.4.0", default-features = false, features = ["alloc"] } # We pin the serde version because newer serde versions may not be compatible # with the nightly toolchain used by libtock-rs. serde = { version = "=1.0.84", default-features = false, features = ["derive"] } -futures = { version = "0.3.1", default-features = false, features = ["unstable", "cfg-target-has-atomic"] } [[example]] name = "alloc_error"
diff --git a/examples/hello_world.rs b/examples/hello_world.rs new file mode 100644 index 0000000..4a67404 --- /dev/null +++ b/examples/hello_world.rs
@@ -0,0 +1,17 @@ +// This example just prints "Hello Tock World" to the terminal. + +#![no_std] + +use core::fmt::Write; +use libtock::result::TockResult; + +#[libtock::main] +async fn main() -> TockResult<()> { + let drivers = libtock::retrieve_drivers()?; + + let mut console = drivers.console.create_console(); + + writeln!(console, "Hello Tock World")?; + + Ok(()) +}
diff --git a/layout_riscv32.ld b/layout_riscv32.ld index df7d4b6..e9bd9d0 100644 --- a/layout_riscv32.ld +++ b/layout_riscv32.ld
@@ -10,7 +10,7 @@ * the kernel binary, check for the actual address of APP_MEMORY! */ FLASH (rx) : ORIGIN = 0x20430040, LENGTH = 32M - SRAM (rwx) : ORIGIN = 0x80002400, LENGTH = 512K + SRAM (rwx) : ORIGIN = 0x80002400, LENGTH = 0x1C00 } /*
diff --git a/src/alloc.rs b/src/alloc.rs index ee3de18..523cb64 100644 --- a/src/alloc.rs +++ b/src/alloc.rs
@@ -8,6 +8,7 @@ use core::executor; use core::ptr; use core::ptr::NonNull; +use futures::future; use linked_list_allocator::Heap; pub static mut HEAP: Heap = Heap::empty(); @@ -40,6 +41,8 @@ if let (Ok(leds_driver), Ok(timer_driver)) = (leds_driver, timer_driver) { let _ = cycle_all_leds(&leds_driver, &timer_driver).await; + } else { + future::pending::<()>().await } loop {} })
diff --git a/src/entry_point/mod.rs b/src/entry_point/mod.rs index ae43a19..09044bd 100644 --- a/src/entry_point/mod.rs +++ b/src/entry_point/mod.rs
@@ -85,7 +85,7 @@ /// into the rustc-generated main(). This cannot use mutable global variables or /// global references to globals until it is done setting up the data segment. #[no_mangle] -unsafe extern "C" fn rust_start(app_start: usize, stacktop: usize, app_heap_break: usize) -> ! { +unsafe extern "C" fn rust_start(app_start: usize, stacktop: usize, _app_heap_break: usize) -> ! { extern "C" { // This function is created internally by `rustc`. See // `src/lang_items.rs` for more details. @@ -125,8 +125,9 @@ // make the corresponding change here. const HEAP_SIZE: usize = 1024; - // we could have also bss_end for app_heap_start - let app_heap_start = app_heap_break; + // Make the heap start exactly at bss_end. The suggested _app_heap_break + // is almost always going to be too big and leads to us wasting memory. + let app_heap_start = bss_end; let app_heap_end = app_heap_start + HEAP_SIZE; // Tell the kernel the new app heap break.
diff --git a/src/entry_point/start_item_riscv32.rs b/src/entry_point/start_item_riscv32.rs index cabfd66..d2c5fd1 100644 --- a/src/entry_point/start_item_riscv32.rs +++ b/src/entry_point/start_item_riscv32.rs
@@ -50,8 +50,7 @@ // Otherwise after the first syscall (the memop to set the brk), the return // will use a stack that is outside of the process accessible memory. // - add t2, t0, t1 // t2 = stacktop + appdata_size - bgt t2, a3, skip_set_sp // Compare `app_heap_break` with new brk. + bgt t1, a3, skip_set_sp // Compare `app_heap_break` with new brk. // If our current `app_heap_break` is larger // then we need to move the stack pointer // before we call the `brk` syscall. @@ -64,7 +63,7 @@ // memop(0, stacktop + appdata_size); li a0, 4 // a0 = 4 // memop syscall li a1, 0 // a1 = 0 - mv a2, t2 // a2 = stacktop + appdata_size + mv a2, t1 // a2 = appdata_size ecall // memop // // Debug support, tell the kernel the stack location @@ -80,7 +79,7 @@ // memop(11, stacktop + appdata_size); li a0, 4 // a0 = 4 // memop syscall li a1, 11 // a1 = 10 - mv a2, t2 // a2 = stacktop + appdata_size + mv a2, t1 // a2 = appdata_size ecall // memop // // Setup initial stack pointer for normal execution
diff --git a/src/lang_items.rs b/src/lang_items.rs index 9c301eb..91a20a1 100644 --- a/src/lang_items.rs +++ b/src/lang_items.rs
@@ -25,6 +25,7 @@ use crate::timer::ParallelSleepDriver; use core::executor; use core::panic::PanicInfo; +use futures::future; #[lang = "start"] extern "C" fn start<T>(main: fn() -> T, _argc: isize, _argv: *const *const u8) -> bool @@ -71,6 +72,8 @@ if let (Ok(leds_driver), Ok(timer_driver)) = (leds_driver, timer_driver) { let _ = blink_all_leds(&leds_driver, &timer_driver).await; + } else { + future::pending::<()>().await } loop {} })