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 {}
     })