Merge #250
250: elf2tab: Update to current version r=hudson-ayers a=towoe
Fixes #249
Signed-off-by: Tobias Wölfel <tobias.woelfel@mailbox.org>
Co-authored-by: Tobias Wölfel <tobias.woelfel@mailbox.org>
diff --git a/doc/DesignConsiderations.md b/doc/DesignConsiderations.md
new file mode 100644
index 0000000..8e72eeb
--- /dev/null
+++ b/doc/DesignConsiderations.md
@@ -0,0 +1,121 @@
+Design Considerations
+=====================
+
+This document describes several of the factors that constrain the design of
+`libtock_core`.
+
+## Size impact
+
+Tock is designed to run on hardware with limited program storage and limited
+RAM. On Google's H1 chip, the Tock kernel and apps are limited to a 256 KiB
+flash region. The HiFive1 Rev B board has only 16 KiB of RAM.
+
+Note that a Tock system may have multiple process binaries, each of which uses
+`libtock_core`, so `libtock_core` must minimize its size impact to the extent
+possible.
+
+A process binary is generally stored in non-volatile memory and contains:
+
+ * Runtime headers (the `.crt0_header` section)
+ * Executable code (the `.text` section)
+ * Read-only data (the `.rodata` section)
+ * Non-zero-initialized read-write data (the `.data` section)
+
+A process' memory section is in RAM and contains:
+
+ * Heap memory (if a dynamic memory allocator is present)
+ * Zero-initialized read-write data (the `.bss` section)
+ * Non-zero-initialized read-write data (the `.data` section)
+ * Stack memory
+
+`libtock_core` developers should consider the space usage of their code, and
+where the space usage is (non-volatile memory or RAM). Important note: the
+`.data` section consumes space in both non-volatile memory and RAM!
+
+Most apps will not use all functionality in `libtock_core`. The size impact of
+using `libtock_core` in an app should be commensurate with the `libtock_core`
+functionality that app uses. If done correctly, this will allow `libtock_core`'s
+users to build Tock systems with multiple small, single-purpose apps without
+excessive code duplication.
+
+## Testability
+
+Programmatic tests are important to verify that new functionality works
+correctly and to keep existing functionality working through nontrivial
+refactorings. Different types of tests offer different capabilities:
+
+ * **Host-based unit tests** run on a non-Tock host OS (such as Linux). They
+ can only be used with portable `libtock_core` code, as the code they test
+ must run on both Tock and the host OS. These tests must either test code
+ that does not directly use system calls, or must direct the system calls to
+ a fake Tock kernel. These tests can be fast (compile and run in seconds),
+ and can easily simulate a variety of failure modes (e.g. kernel errors) that
+ may be difficult to generate with a real Tock kernel.
+ * **Emulation tests** run on an emulated Tock system. Currently, emulation
+ tests run in QEMU on an emulated HiFive1 Rev B board. These test
+ `libtock_core`'s interaction with a real Tock kernel, albeit with limited
+ hardware access.
+ * **Hardware tests** run on physical hardware with a real Tock kernel. These
+ are end-to-end tests that test not only `libtock_core`'s functionality but
+ also the Tock kernel's interaction with the real hardware. However,
+ automating these tests is difficult, and currently we do not have a way to
+ run hardware tests in CI.
+
+If `libtock_core` is functional on real hardware with a real kernel, it should
+be able to support emulation tests and hardware tests. However, host-based unit
+tests require more work. In its intended use case, `libtock_core` is not
+supposed to be portable, supporting only the Tock kernel. Hoever, host-based
+unit tests are very valuable, both for rapid development and for testing error
+handling code. To support host-based tests, `libtock_core` must be built out of
+portable pieces that can be unit tested, even though the library as a whole is
+not portable.
+
+Testing pieces of `libtock_core` against a fake kernel can be done using
+dependency injection, but most dependency injection techniques have considerable
+code size and RAM usage costs. `libtock_core` needs either a dependency
+injection technique that has minimal size impact or an alternative mechanism for
+testing `libtock_core`'s system call error handling logic.
+
+## Support multiple asynchronous programming models.
+
+The general Rust ecosystem has converged on futures as its building block for
+interoperable asynchronous APIs, but futures have a [size
+cost](https://github.com/tock/design-explorations/tree/master/size_comparison)
+that makes them impractical for some use cases of `libtock_core`. Although
+`libtock_core` is still a work in progress (see [issue
+217](https://github.com/tock/libtock-rs/issues/217)), it will probably use an
+asynchronous API design based on the [Asynchronous Components using Zero Sized
+Type
+Pointers](https://github.com/tock/design-explorations/tree/master/zst_pointer_async)
+exploration.
+
+In order to interoperate with other libraries as well as the `async`/`await`
+functionality built in to Rust, we need `libtock_core` to interface well with
+futures. In addition, there are several use cases of `libtock_core` that consist
+primarily of synchronous code, so we need to be able to use `libtock_core`'s
+APIs in a synchronous manner.
+
+The `libtock-c` developers are already familiar with some of the complications
+that come up when synchronous code is interfaced to asynchronous code. For
+example, calling `printf` -- an extremely common debugging tool -- causes
+callbacks to run in the background. This causes surprising and hard-to-debug
+reentrancy issues.
+
+## Dependency tree minimization
+
+Some of users of `libtock_core` intend to use it in applications that will
+undergo code audits for security certifications. To make this auditing
+practical, it is important to allow users to use `libtock_core` without pulling
+in a large dependency tree.
+
+As a general rule, a `libtock_core` should avoid having required dependencies
+unless those dependencies are minimal (that is, avoiding the dependency would
+require reimplementing nearly all of it). Dependencies included in the Rust
+toolchain (such as the `core` crate and its dependencies) are an exception, as
+they are a part of the language itself.
+
+## No hard `alloc` dependency
+
+It should be possible to use `libtock_core` without bringing in the `alloc`. Of
+course, it is fine for `libtock_core` to offer a memory allocator as an optional
+feature.
diff --git a/src/sensors/ninedof.rs b/src/sensors/ninedof.rs
index b5e7191..f5c0197 100644
--- a/src/sensors/ninedof.rs
+++ b/src/sensors/ninedof.rs
@@ -47,6 +47,14 @@
Ok(res.res.get())
}
+ pub fn read_gyroscope(&mut self) -> TockResult<NinedofReading> {
+ let res: CbData = Default::default();
+ subscribe(Self::cb, unsafe { mem::transmute(&res) })?;
+ start_gyroscope_reading()?;
+ unsafe { executor::block_on(futures::wait_until(|| res.ready.get())) };
+ Ok(res.res.get())
+ }
+
extern "C" fn cb(x: usize, y: usize, z: usize, ptr: usize) {
let res: &CbData = unsafe { mem::transmute(ptr) };
res.res.set(NinedofReading {
@@ -72,3 +80,8 @@
syscalls::command(DRIVER_NUM, 100, 0, 0)?;
Ok(())
}
+
+pub fn start_gyroscope_reading() -> TockResult<()> {
+ syscalls::command(DRIVER_NUM, 200, 0, 0)?;
+ Ok(())
+}
diff --git a/test_runner/Cargo.toml b/test_runner/Cargo.toml
index 133ff23..66a407a 100644
--- a/test_runner/Cargo.toml
+++ b/test_runner/Cargo.toml
@@ -11,7 +11,10 @@
futures = "0.3.4"
[dependencies.async-std]
-version = "1.5.0"
+# async-std 1.7 pulls in crossbeam_utils 1.8, which does not work with the
+# nightly Rust toolchain we use. Temporarily block async-std 1.7 until we can
+# update our Rust toolchain.
+version = "1.5.0, <1.7"
features = ["attributes"]
[dependencies.tokio]