Git Product home page Git Product logo

tock's Introduction

TockOS

tock-ci slack book

Tock is an embedded operating system designed for running multiple concurrent, mutually distrustful applications on Cortex-M and RISC-V based embedded platforms. Tock's design centers around protection, both from potentially malicious applications and from device drivers. Tock uses two mechanisms to protect different components of the operating system. First, the kernel and device drivers are written in Rust, a systems programming language that provides compile-time memory safety and type safety. Tock uses Rust to protect the kernel (e.g. the scheduler and hardware abstraction layer) from platform specific device drivers as well as isolate device drivers from each other. Second, Tock uses memory protection units to isolate applications from each other and the kernel.

TockWorld 2024!

Join the community of industry professionals, operating system developers, academics, and interested developers for the annual TockWorld conference. This event in San Diego, CA will take place June 26-28, 2024. Get your tickets today!

Tock 2.x!

Tock is now on its second major release! Tock 2.x includes significant changes from Tock 1.x, including:

  • Revamped system call interface.
  • Support for 11 new hardware platforms.
  • Updated kernel types.
  • Many new and improved HILs.

For a summary of the latest new features and improvements, check out the changelog.

Learn More

How would you like to get started?

Learn How Tock Works

Tock is documented in the Tock Book. Read through the guides there to learn about the overview and design of Tock, its implementation, and much more.

Use Tock

Follow our getting started guide to set up your system to compile Tock.

Head to the hardware page to learn about the hardware platforms Tock supports. Also check out the Tock Book for a step-by-step introduction to getting Tock up and running.

A book on how to use Tock with the micro:bit v2 and Raspberry Pi Pico boards is Getting Started with Secure Embedded Systems.

Find example applications that run on top of the Tock kernel written in both Rust and C.

Develop Tock

Read our getting started guide to get the correct version of the Rust compiler, then look through the /kernel, /capsules, /chips, and /boards directories. There are also generated source code docs.

We encourage contributions back to Tock and are happy to accept pull requests for anything from small documentation fixes to whole new platforms. For details, check out our Contributing Guide. To get started, please do not hesitate to submit a PR. We'll happily guide you through any needed changes.

Keep Up To Date

Check out the blog where the Talking Tock post series highlights what's new in Tock. Also, follow @talkingtock on Twitter.

You can also browse our email group and our Slack to see discussions on Tock development.

Code of Conduct

The Tock project adheres to the Rust Code of Conduct.

All contributors, community members, and visitors are expected to familiarize themselves with the Code of Conduct and to follow these standards in all Tock-affiliated environments, which includes but is not limited to repositories, chats, and meetup events. For moderation issues, please contact members of the @tock/core-wg.

Cite this Project

Tock was presented at SOSP'17

Amit Levy, Bradford Campbell, Branden Ghena, Daniel B. Giffin, Pat Pannuto, Prabal Dutta, and Philip Levis. 2017. Multiprogramming a 64kB Computer Safely and Efficiently. In Proceedings of the 26th Symposium on Operating Systems Principles (SOSP ’17). Association for Computing Machinery, New York, NY, USA, 234–251. DOI: https://doi.org/10.1145/3132747.3132786

Bibtex
@inproceedings{levy17multiprogramming,
      title = {Multiprogramming a 64kB Computer Safely and Efficiently},
      booktitle = {Proceedings of the 26th Symposium on Operating Systems Principles},
      series = {SOSP'17},
      year = {2017},
      month = {10},
      isbn = {978-1-4503-5085-3},
      location = {Shanghai, China},
      pages = {234--251},
      numpages = {18},
      url = {http://doi.acm.org/10.1145/3132747.3132786},
      doi = {10.1145/3132747.3132786},
      acmid = {3132786},
      publisher = {ACM},
      address = {New York, NY, USA},
      conference-url = {https://www.sigops.org/sosp/sosp17/},
      author = {Levy, Amit and Campbell, Bradford and Ghena, Branden and Giffin, Daniel B. and Pannuto, Pat and Dutta, Prabal and Levis, Philip},
}

This is the primary paper that describes the design considerations of Tock.

Other Tock-related papers

There are two shorter papers that look at potential limitations of the Rust language for embedded software development. The earlier PLOS paper lays out challenges and the later APSys paper lays out potential solutions. Some persons describing work on programming languages and type theory may benefit from these references, but generally, most work should cite the SOSP paper above.

@inproceedings{levy17rustkernel,
	title = {The Case for Writing a Kernel in Rust},
	booktitle = {Proceedings of the 8th Asia-Pacific Workshop on Systems},
	series = {APSys '17},
	year = {2017},
	month = {9},
	isbn = {978-1-4503-5197-3},
	location = {Mumbai, India},
	pages = {1:1--1:7},
	articleno = {1},
	numpages = {7},
	url = {http://doi.acm.org/10.1145/3124680.3124717},
	doi = {10.1145/3124680.3124717},
	acmid = {3124717},
	publisher = {ACM},
	address = {New York, NY, USA},
	conference-url = {https://www.cse.iitb.ac.in/~apsys2017/},
	author = {Levy, Amit and Campbell, Bradford and Ghena, Branden and Pannuto, Pat and Dutta, Prabal and Levis, Philip},
}
@inproceedings{levy15ownership,
	title = {Ownership is Theft: Experiences Building an Embedded {OS} in {R}ust},
	booktitle = {Proceedings of the 8th Workshop on Programming Languages and Operating Systems},
	series = {PLOS 2015},
	year = {2015},
	month = {10},
	isbn = {978-1-4503-3942-1},
	doi = {10.1145/2818302.2818306},
	url = {http://dx.doi.org/10.1145/2818302.2818306},
	location = {Monterey, CA},
	publisher = {ACM},
	address = {New York, NY, USA},
	conference-url = {http://plosworkshop.org/2015/},
	author = {Levy, Amit and Andersen, Michael P and Campbell, Bradford and Culler, David and Dutta, Prabal and Ghena, Branden and Levis, Philip and Pannuto, Pat},
}

There is also a paper on the Tock security model. The threat model documentation in the docs/ folder is the source of truth for the current Tock threat model, but this paper represents a snapshot of the reasoning behind the Tock threat model and details how it compares to those in similar embedded OSes.

@inproceedings{10.1145/3517208.3523752,
	author = {Ayers, Hudson and Dutta, Prabal and Levis, Philip and Levy, Amit and Pannuto, Pat and Van Why, Johnathan and Watson, Jean-Luc},
	title = {Tiered Trust for Useful Embedded Systems Security},
	year = {2022},
	isbn = {9781450392556},
	publisher = {Association for Computing Machinery},
	address = {New York, NY, USA},
	url = {https://doi.org/10.1145/3517208.3523752},
	doi = {10.1145/3517208.3523752},
	booktitle = {Proceedings of the 15th European Workshop on Systems Security},
	pages = {15–21},
	numpages = {7},
	keywords = {security, embedded systems, operating systems, IoT},
	location = {Rennes, France},
	series = {EuroSec '22}
}

License

Licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

tock's People

Contributors

ajnam12 avatar alevy avatar alexandruradovici avatar alistair23 avatar bbbert avatar bors[bot] avatar bradjc avatar brghena avatar cosmindanielradu19 avatar cpluss avatar daniel-scs avatar gendx avatar hudson-ayers avatar ioan-cristian avatar jettr avatar jrvanwhy avatar krady21 avatar lebakassemmerl avatar lschuermann avatar mciantyre avatar mihai-negru avatar niklasad1 avatar phil-levis avatar ppannuto avatar rajivr avatar teodoramiu avatar thebutterminecutter avatar twilfredo avatar tyler-potyondy avatar valexandru avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tock's Issues

Incorrect pin assignment for external I2C

In src/platform/storm/lib.rs, on line 195, ESCL is assigned to PB02. According to the ATSAM4L datasheet, this should actually be at PB01 (the peripheral function is TWIMS1 TCLK).

This issue would make the external I2C (ESCL/ESDA) appear to be broken. The I2C bus connected to the Firestorm sensors is unaffected.

Changing line 195 to PB[01] should be the only necessary change.

Get LTO working in user space generic apps

We don't use LTO right now. I just added it and it emptied the whole application. Likely some additional stuff needs to be marked as kept (i.e. non-traditional _start), but not worth digging into now.

RTC on nRF51822

There are currently 2 RTC implementations in the nRF; rtc.rs uses RTC1 for an underlying timer and systick.rs (in the nrf_pc10001) uses RTC0 for systick. We should integrate these two so the same RTC, RTC1, is used both for systick as well as the underlying timer clock. We need to use RTC0 for the BLE stack. Since they share a single NVIC entry this means a capsule that exposes all 3 and demultiplexes their events in software.

Explain directory structure

Add a document explaining the directory structure:

  • What are the different crates and what is there purpose?
  • How are files organized?
  • I want to add something, where does it go?

Option to have apps in an external repo?

I imagine that the plan long-term is to not have the apps folder in with the kernel, and I think it makes sense for it to stay there for quick testing now, but what would it take to have a separate repo with apps that we can upload to a firestorm that already has the kernel?

I ask because my ble-serialization app will need a bunch of nordic sources in the short-term and I don't want to complicate the kernel build with the external dependency.

nRF51: Rewrite code generator in Rust

Python code: tools/nRF51_codegen.py

This will drop the only reason for depending on Python. Rust probably has the necessary crates for this task.

nRF51822: Implement timer support

Initial user for timers will be the sample "c_blinky" app.

Tasks

  • Implement basic interrupt support (fix ISR vector, NVIC etc.)
  • Implement Alarm interface for at least one hardware timer (nRF51822 has 3 high-frequency TIMERs + 2 low-frequency RTCs), like src/chips/sam4l/ast.rs
  • Implement platform support in src/platform/nrf_pca10001/lib.rs
  • Abstract GPIO pin assignment for LED on application library

Rewrite (part of) crt1.c in Rust

There are a couple of "bare metal" projects that implement their reset handlers and ISR vectors in Rust as well. The generated code may not be super optimized as C or hand coded assembly, but this code is usually run/loaded once and thus not on the hot path.

  • SAM4L
  • nrf51822

rustc expects gcc to have __aeabi_memcpy (libc)

Not sure if this is due to my gcc installation being different, or a common problem.

phoenix:tock pal$ git log | head -1
commit 61d90bb

phoenix:tock pal$ make
Linking build/main.elf
arm-none-eabi-gcc -g -O3 -std=gnu99 -mcpu=cortex-m4 -mthumb -nostdlib -Tsrc/chips/sam4l/loader.ld build/crt1.o build/arch.o build/main.o -o build/main.elf -ffreestanding -lgcc -lc
build/main.o: In function main': main.0.rs:(.text.main+0x426): undefined reference to__aeabi_memcpy'
collect2: error: ld returned 1 exit status
make: *** [build/main.elf] Error 1

phoenix:tock pal$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GCC) 4.8.3
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

What memory manager are you using?

I have written a ultra lightweight memory manager for microcontrollers that completely avoids issues with fragmentation

https://github.com/vitiral/tinymem

It's currently written in C and has a known bug, but I've been itching to rewrite it in rust. Would it be useful to you?

To get it to work transparently, I think it would require a compiler plugin - as it uses indirection of pointers to allow it to move memory around safely. But from what I know about rust, it should be possible to implement.

Move temporary register stacking to kernel

Registers r4-r11 are currently stacked in user space. This won't work when we want to prioritize capsules. If we switch to the kernel without the knowledge of user-space, the registers simply wouldn't be saved.

Use MPU to protect applications

Need to actually enforce memory protection to allow applications access to their own memory and code, but nothing else (including memory lent to the kernel).

Background

Memory Layout

Application memory is already laid out to support protection. The application code section lives in one of the .app.N sections. The application memory lives in a discreet element of process::MEMORIES and process::Process#exposed_memory_start notes the location memory (within the bounds of the application's memory) where exposed memory begins.

Cortex-M4 MPU

The sam4l supports the ARM MPU extension, allowing up to 8 potentially overlapping regions, and up to 8 sub-regions (depending on the size of a region).

Isolating applications with the MPU should be simply defined in three regions:

  1. A base region that covers all of memory and turns off all access.
  2. A region for the application code section, marked read and execute (not write).
  3. A region for the application memory marked read/write/execute.

NRF51 MPU

The NRF51 MPU works differently. There only two memory regions, and two code regions with pre-defined access control.

Need to investigate how to best use this mechanism to isolate an app. Luckily, we likely only want to fit a single app on the NRF51 anyway.

Tasks

  • Implement MPU for Cortex-M4
  • Investigate how to use the NRF51 MPU
  • Make interface for protecting an application hardware-agnostic (e.g. an api call into the chip implementation).

Watch for #[naked] support to come into Rust

Our interrupt handlers are currently emitting function prologues that they should not, e.g:

00016b9e <reset_handler::h0a16a35074fed14diQc>:
   16b9e:       b580            push    {r7, lr}
   16ba0:       466f            mov     r7, sp

The way to fix this is to mark the functions as naked, but that hasn't quite made it into rust yet: rust-lang/rfcs#1201

We should monitor this though and add it to the list of things worth updating rust versions for whenever it lands.

Timer system call interface buggy when interval=1

If you pass 1ms to the timer interface, you miss callbacks. This likely has to do with the possibility that the counter is read, then the compare is set to read value +1. If the counter incremented between that read and set, no interrupt will be issued.

Two typical solutions (you generally want both): have the underlying counter at a higher precision (so a timer of 1 is, say, 1000 counter increments), and also check whether the counter has passed the compare value before returning. I.e., set the prescalar in ast.rs so it's higher than 1kHz (e.g., 32kHz), then have the system call interface translate ms to ticks of a 32kHz clock).

TMP006 Driver

A driver for this already exists, but it's not very complete. @brghena is working on improving it significantly. Notably, rely on the TMP006 interrupt pin to learn when new measurements are available, instead of using a timer.

Tasks

  • Interrupt pin for new measurement notification
  • Calculate accurate temperature using formulas from the TMP006 datasheet

Hurdles

Floating point

Many Cortex-M's (including the sam4l) do not support floating point operations in hardware, and Rust doesn't know how to replace those calls with software implementations. Could in principal expose software floating point implementation from libgcc in the kernel. For now, just pushing the floating point computations to user-land.

Unsubscribe

How does an app unsubscribe to a subscription?

Buffers should be adjusted for different boards

Firestorm has 64K RAM , while nRF51822 based boards have "only" 16K. Tock is able to run fine on smaller systems, as long as we are able to scale down static buffers or limit memory possibly using modular designs.

One example is per app memory reservation. Current master uses a hard-coded 8K limit, but that seems too much for 16K systems.

FXOS8700CQ (Accelerometer + Magnetometer) Driver

A driver on top of I2C for the the FXOS8700CQ accelerometer and magnetometer driver.

Tasks

  • Basic accelerometer operation modelled off the TMP006 driver (using a timer)
  • Basic magnetometer operation
  • Provide access to both accel and magnetometer readings at once

Generating libcore for architecture

Makefile for libcore is currently broken if you build for more than one platform There are two platforms, let's just say one is cortex-m0 and cortex-m4 (different thumb versions). Triple does not match for core lib. The error output:

./tock/src/process/lib.rs:1:1: 1:1 error: couldn't find crate `core` with expected target triple ./tock/src/chips/nrf51822/target.json [E0461]
./tock/src/process/lib.rs:1 #![crate_name = "process"]
                                              ^
./tock/src/process/lib.rs:1:1: 1:1 note: crate `core`, path #1, triple ./tock/src/chips/sam4l/target.json: \\?\C:\Code\github\rust\tock\build\libcore.rlib
error: aborting due to previous error
make: *** [build/libprocess.rlib] Error 101

This is caused by copying libcore to build directory without appending any triple specific value. A quick fix would be to copy libcore to a platform specific build directory or just define libcore.rlib as phony target.

A better one might be to come up with a schema from target.json file. What shall we consider, arch, llvm-target?

Add Ability to Restart Applications

It would be great to be able to restart apps if they crash (or upon demand if the kernel detects they aren't working).

An extra fancy option might be to add the ability to configure the board in one of three modes:

  1. stop: What we do now, where any hardfault prints the registers and stops.
  2. print_and_reboot: Print the hardfault error and then restart the MCU.
  3. reboot: Immediately restart the MCU on any failure.

Tutorial K4: Loopback SPI

Tutorial K4: Set up SPI to be loopback, write a driver with a command to send to SPI and an event on completion, with a buffer for received string (allow/subscribe).

Goal: show allow/subscribe, non-blocking nature of kernel, buffer management.

GPIO Driver for apps

Provide applications access to exposed GPIO pins.

Tasks

  • GPIO output
  • Input change interrupts

GPIO Output

The GPIO driver provides a system call interface for setting the output of the GPIO pin. There are three command with the following command numbers:

Command number Functionality
0 Enable output
2 Set
3 Clear
4 Toggle

In each command the first argument to the system call (register r2) marks which GPIO pin the command is referencing.

Virtualization

Is it possible to virtualize GPIO output? Probably not. I.e. if one application wants the pin high, and the other low, who wins?

One option is just to allow this as a free-for-all. Another is to restrict application access to particular pins --- so only allowed applications can change the output of a particular pin.

What does Linux do for, e.g., raspberry pi and other platforms with GPIO?

GPIO Input

Input should be done via interrupts/callbacks. An app can subscribe to a change in value on a particular pin, specifying whether it is interested in the rising edge, falling edge or both.

Virtualization

Virtualization for input is easier than output, since we can simply keep track of which applications subscribed to what kind of change.

nRF51822: Refactor platform init()

See src/platform/storm/lib.rs for inspiration. static_init!() macro (ideally after moved to a common location) should be used for static buffer allocations.

At a minimum, mutable annotations should be removed where not necessary.

Original discussion: #17 (diff)

Non-reentrant problem with putstr (and also all other synchronous I/O)

With the current implementation of wait and wait_for, an app that mixes synchronous and asynchronous calls can easily run into trouble.

The high-level problem is that a call to a synchronous function (such as putstr) might be interleaved with a callback for that calls the same function. Of course, if that function is non-reentrant, this is a problem, but it's actually not possible to make a function reentrant while using wait_for "correctly".

There is a solution to this. the tl;dr is to change wait_for to wait for a boolean flag to flip to true rather than using a unique value of the return pointer. But first some background and an example of the problem before a detailed proposal for the solution.

Background

First, a review of how wait and wait_for currently work. If you feel like you have a good grasp on this, you can skip down.

There are three related calls:

  1. int __wait(void) is a system call that blocks execution of the app until a new event is ready. At that point, the kernel signals the event by pushing a frame onto the app's stack and jumping to a callback function specified in a corresponding subscribe syscall. When the callback returns, execution is resumed at the point where __wait was called, and the return value of the callback becomes the return for the __wait call.
  2. wait_for(int) is a library wrapper around __wait that keeps yielding until a callback of a particular type (specified by the argument) has been invoked. Any event that doesn't match is put onto a queue so that other calls to wait_for or wait (see point 3) see it (in case it corresponds to the event they are waiting for). This is meant to correspond to a particluar event, such as putstr completion, has occured. To do this, all callbacks have to agree to use their return value to signal which event they responded to. To manage this, we currently have a global enum containing each event type in apps/lib/firestorm.h.
  3. wait is a library wrapper around __wait that first checks queue populated by wait_for and only actually calls the system call if the queue was empty.

Why can't we make putstr reentrant

From a library writer's perspective, making putstr reentrant should be straight forward. I have a data sink (e.g. the console driver) that can only knows how to deal with one outstanding write request at a time, so I just need to buffer concurrent calls to putstr. The callback putstr uses to get notified that the console has finished doing it's thing will process the next buffered string to print et voila.

The problem is that this doesn't let us differentiate in wait_for between different calls to putstr. This means that when calls to the same synchronous function are interleaved, we can't be sure that the action has completed when we return. This maybe isn't so terrible with putstr, but this can definitely be a problem with order dependent operations. For example:

timer_subscribe(my_callback, NULL);
timer_oneshot(1); // a very short timer
spi_write_sync("blahblah", 8);

CB_TYPE my_callback(...) {
  // Here, we're not sure if the following command will be buffered or not,
  // because "blahblah" may not have completed yet.
  spi_write_sync("cmd", 3);
  // Maybe "cmd" completed but only maybe "blahblah" completed...

  some_call_that_should_only_be_invoked_after_cmd_has_completed();

  return TIMER;
}

As a hack explore what was possible for putstr, I generated a unique return value for each call (just by incrementing a global counter), and waiting on that value instead of PUTSTR in wait for. With some slight modifications to wait_for (have to check if the callback is in the queue aftrer each call to __wait). That functionally works, but is a problem since return values to callbacks should be unique, and it's not clear how to make sure they don't overlap

Proposed Solution

The core problem is waiting on a something unique for each invocation of a synchronous call. It's hard to generate globally unique values, but it's not hard to generate globally unique pointers.

Instead of waiting on a return value in wait_for, wait on a particular boolean variable flipping to true. The callback doesn't have to return anything particular, instead it flips the boolean. The boolean can be a global (in the case of a non-reentrant function or if we're only ever processing the head of a globally stored list, e.g.) or can be passed in as the user-data parameter to the callback.

Benefits

The implementations for wait and wait_for are much much simpler (almost not worth implementing):

void wait() {
  __wait();
}

void wait_for(bool* cond) {
  while(!*cond) {
    __wait();
  }
}

Writing callbacks that don't correspond to a wait_for is totally straight forward since you don't have worry about which value you are returning.

Disadvantages

These implementations discard the return value completely, even though in principal they could be repurposed (for example to return the length of the written to the console), but that would be a pretty complex implementation and that can always be simulated, again, by modifying another shared variable passed through the callback's user-data.

It requires changes to all functions that currently use wait_for. So far, i've ported most of them relatively easily. Porting them illuminated that many functions are non-reentrant, and maybe some should be.

Finally, in some cases (like Phil's rf233 code), where synchronous calls are not explicitly broken out, it becomes subtle where to set global boolean flags to false before waiting (it needs to be before the first wait that might result in a callback, not just the corresponding wait_for).

Fix Userland libs

Basically there are too many things in firestorm.c that are not specific to firestorm. We should also figure out at some point what we want to do with regard to callbacks and async/sync. Some libraries hide the async-ness and others don't (probably because it's faster to write).

Some things that need to be straightened out (there may be others):

  • Remove delay from firestorm.h/c
  • Remove timers from tock_str.h/c

nRF51822: Investigate using new() method in struct GPIO

Currently, a GPIO() private function is used for wrapping the unsafe transmutation of the register base address, which is not the "canonical" way of returning struct instances. But the canonical way may have some disadvantages (see original discussion for details).

Note: this is not a priority given the function is a private implementation detail.

Original discussion: #17 (diff)

Special type for handling buffers in drivers

For chip drivers, it is sometimes useful to use a buffer twice (say to handle two reads) before computing a value with the entire buffer. However, if you slice a buffer and pass it to a peripheral (say the I2C driver), then on the callback you get just that slice back and not the entire buffer. If we had a type that wrapped this, then we could re-use a single buffer for a more complicated driver while avoiding this issue.

Investigate need for built-in function replacements in crt1.c

There is a TODO on the crt1.c but it is easier to track here.

Currently, we implement replacements for several built-in functions that could be provided by some runtime library (GCC or LLVM). It is not clear (at least for me), why they are needed. Are we missing linking to some library that could provide those functions?

HFCLK on nRF51822

The BLE stack requires the high frequency clock (HFCLK) for timestamps. It uses the clock to both trigger transmission/reception through the peripheral interconnect (PPI) without going through software as well as capture timestamps on address decoding.

Respawn processes on HardFault

When an MPU violation, or other hard fault occurs (e.g. divide-by-zero) from user-space, respawn the offending processes.

Revamp build system

The current build system is pretty cobbled together and is pretty hard to understand (and therefore change). We would like the system to allow at least:

  • More modular build system (modeled after ??? )
  • Ability to build app in external repo
  • Generate articfacts for multiple boards/apps/chips without having to do a clean-all
  • Per-board or per-chip variables that show up in different crates (e.g. memory sizes for apps).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.