Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Simpler and more robust component interface #1618

Closed
wants to merge 9 commits into from

Conversation

gendx
Copy link
Contributor

@gendx gendx commented Feb 21, 2020

Pull Request Overview

Context

While writing my first components in #1556, I hit some difficulties in how to design things.

This pull request is an RFC to refactor the components interface, with the goals of (1) being less verbose and (2) more difficult to use incorrectly. It contains:

  • New ways of initializing static objects, in kernel/src/common/utils.rs.
  • An example of how the refactoring would look like on the component side (boards/components/src/alarm.rs) as well as the board side (boards/imix/src/main.rs). I picked the alarm component, which uses the static_init_half pattern, and therefore things should generalize well to the other components as far as I understand it. But please let me know if there are more complex cases that components can handle.

Refactoring of static_init

Current rationale for static_init_half

In principle, static objects in kernel boards are initialized with the static_init macro.

However, this relies on defining a static buffer inline in the current function, which doesn't work in Rust when the static type depends on a generic type of the function (because the compiler would somehow have to instantiate a distinct static object for each type of the function - which may not be well-defined in general).

This led to splitting static_init into *_helper macros defined in components to create static buffers with concrete types, and a static_init_half macro that initializes the buffer with some value. Besides creating some confusion about what this and that half mean, I don't think exposing the internal details of static_init in this way is very robust, as it relies on too many assumptions.

  • static_init_half expects a MaybeUninit<T> buffer that contains uninit. Giving it an already initialized buffer would be incorrect as it would erase the previous value without notice. However, the current API of static_init_half just takes a MaybeUninit<T>.
  • The *_helper macros return a &mut MaybeUninit<T>, which doesn't prevent the buffer from being used directly, or passed to various static_init_half. The API should only allow to pass such a buffer to static_init_half and only once.
  • static_init_half doesn't have to be a macro, it can be implemented as a function. The only part that needs to be in a macro is the static mut BUF: MaybeUninit<$T> = MaybeUninit::uninit();, because that cannot be put in a function generic on $T (due to Rust rules). But this part is already in the *_helper macros.

Proposed new API for static initialization

Instead, I propose the following API (see the changes in kernel/src/common/utils.rs).

  • An uninit_static_buf macro, which takes a type and instantiates inline a static mut buffer, containing MaybeUninit::uninit(). The role of this macro is similar to the *_helper macros in components.
  • The result of it is stored in a new UninitBuf type, that privately wraps the uninitialized MaybeUninit - preventing anyone else from initializing it. This wrapper is repr(transparent), and just here to guarantee that the contents really are uninitialized. The only way to construct it is via a new() function which takes care of calling MaybeUninit::uninit().
  • Another new type is StaticUninitRef, which privately wraps an UninitBuf into a &'static mut reference. This is so that uninit_static_buf returns this wrapper instead of a plain &mut BUF that could be misused.
  • The StaticUninitRef wrapper has a single public method, initialize, which consumes the uninitialized self, stores a value in it, and returns the &'static mut T reference. This provides the same functionality as the previous static_init_half (i.e. doing the actual initialization), but:
    • this prevents double initialization, because self is consumed,
    • this prevents non-initialization, because the only way to get a &'static mut T reference is to actually initialize it via StaticUninitRef::initialize.

Then, the *_helper macros in components can use uninit_static_buf instead of directly using MaybeUninit. This removes some code duplication as the components don't have to create a MaybeUninit::uninit() and cast the reference, they just need to call uninit_static_buf!($T). I also suggest to rename *_helper macros into *_buf macros, because all that these helpers really do is creating uninitialized static buffers.

The static_init macro is also a straightforward combination of the uninit_static_buf macro and the initialize function.

Refactoring in components

I find the Component trait itself quite weird.

  • The idea is that it is generic with a finalize() method. But in practice components need to add a new() method as well to pass arbitrary parameters, and this new() method is not part of the interface.
    • This leads to expressions of the form ComponentFoo::new(some, parameters).finalize(other, parameters) instead of a more straightforward single-function call ComponentFoo::create(some, parameters, other, parameters).
    • When defining the components themselves, a lot of verbosity happens as well in copying things in new() and finalize(). Defining a single create() function instead would decrease the number of lines of code.
  • The finalize method in Component is ill-defined. It takes a &mut self parameter, but the documentation explains that this method may only be called once. A better API to enforce this constraint is to consume the component by taking a self parameter instead of a reference. This is an issue I've hit while trying to define my own components (Refactor Segger RTT and add a usb_debugging mode on the nRF52840-DK board #1556 (comment)).
  • The Component trait doesn't mean much in itself. It requires a finalize method taking an arbitrary input type and returning an arbitrary output type, without any constraints on the input and output. Pretty much any function can be turned into this finalize interface.
  • Although the Component trait brings genericity, it's never called in a generic context. Combined with the previous remark, I think that this trait mostly adds verbosity.
  • The component objects are only constructed (new()) and finalized() (thereby returning a reference to something else). Other than that their value isn't used as an object. The only reason to have an object is so that it implements the Component trait.

Alarm example

As an example, I refactored the alarm component to get rid of the component interface, and this divides the number of lines by two.

A simpler API can also make it easier for everyone to define components. I was quite confused when defining my own components for the first time about what should be put in new() vs. in finalized() - and I think making it easy for anyone to get acquainted to the concept of components so that they can write their own components is important.

Misc

Testing Strategy

Not much at this stage. It's mostly an RFC on the design.

TODO or Help Wanted

This pull request still needs comments on the design.

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make formatall.

@bradjc
Copy link
Contributor

bradjc commented Feb 21, 2020

I think it's great to have another look at components after they became generic. It took so long just to make components generic that I was excited about anything that worked.

What enforces that components are created with ::create()? Having the component trait ensures at least some sort of consistent implementation of components. A new component author, who doesn't know about the new()/finalize() roots of components may want to add additional functions, which complicates using components.

Now I wrote the static_init_half! macro, but I am partial to the naming relationship between that macro and static_init! as it provides an immediate connection between the two. And perhaps Rust has already sailed this ship, but I dislike how confusing "uninit" is. Is that supposed to be an adjective or verb? Is it uninitializing already initialized memory, or is the memory just uninitialized? The easy fix is just spelling it out, and I don't see why Rust wanted to save the few characters.

For components, is it important that the the type be something like UninitializedStaticBuffer versus just StaticBuffer? Would we ever need both types? I think what I find confusing is does the uninit part have any meaning to the component author, or is that just an artifact of how it is implemented in rust?

Copy link
Member

@ppannuto ppannuto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really exciting to see. I was just trying to teach someone new the component / initialization interface in the last few weeks and complexity of the explanation yielded a mental TODO that you've just checked off my list :)


I think I want to go farther than Brad on renaming things, as much as static_init has served us well, it's pretty Rust-y thing to read that and intuit what's going on. I might suggest:

  • static_init -> create_and_initialize_static
  • uninit_static_buf -> create_uninitialized_static
  • UninitBuf -> UninitializedBuffer
  • UninitStaticBuf -> UninitializedStaticBuffer

I don't really have a solution here, but losing the Component trait is unfortunate. Not because the trait itself was terribly valuable, but because it created a common interface for components [although, the absence of new in the trait lessens that argument].

What's missing with this then is some (ideally compiler-enforced) guidance of what a create method looks like, or really what a Component looks like.

The only thing I came to was that components themselves look pretty procedural, and possibly replaced by yet-another-macro, which could then present a structured interface, but would likely be prohibitively complex.


I think my current takeaway is that this has some easy wins (the buffer wrapping) that is strictly better and helps people to 'do the right thing', but the actual creation part may need more iteration.

@phil-levis
Copy link
Contributor

A bit of history. I looked back, and initial approach with components was:

  • new took no parameters, or sometimes a reference to the kernel
  • finalize took no parameters
  • dependency was a call to add an additional dependency to the component.

E.g..:


pub struct GpioComponent {
    pins: Option<&'static [PinHandle]>,
    board_kernel: &'static kernel::Kernel,
}

impl GpioComponent {
    pub fn new(board_kernel: &'static kernel::Kernel) -> Self {
        GpioComponent {
            pins: None,
            board_kernel: board_kernel
        }
    }
}

impl Component for GpioComponent {
    type Output = &'static capsules::gpio::GPIO<'static, mk66::gpio::Gpio<'static>>;

    unsafe fn finalize(&mut self) -> Option<Self::Output> {
        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);

        if self.pins.is_none() {
            return None;
        }

        let gpio = static_init!(
                capsules::gpio::GPIO<'static, mk66::gpio::Gpio<'static>>,
                capsules::gpio::GPIO::new(self.pins.unwrap(), self.board_kernel.create_grant(&grant_cap))
            );

        for pin in self.pins.unwrap().iter() {
            pin.set_client(gpio);
        }

        Some(gpio)
    }
}

impl ComponentWithDependency<&'static [PinHandle]> for GpioComponent {
    fn dependency(&mut self, pins: &'static [PinHandle]) -> &mut Self {
        self.pins = Some(pins);

        self
    }
}

I think that we realized that dependency could be merged into finalize, such that finalize takes parameters. As for the reason for dependency, the original comment read:

/// If component A requires a reference to component B, and B
/// requires a reference to A, then one of them can implement this
/// trait. For example, A can implement ComponentWithDependency<B>.
/// When A is constructed, B does not exist yet. When B is constructed,
/// A exists, so can be passed to new(). Then, B can be passed to A
/// via a call to dependency(). After both dependencies are resolved,
/// the boot sequence can call finalize() on both of them.

In practice, though, this turned out to not be important (plus it's not exactly clear how finalization will work).

@phil-levis
Copy link
Contributor

I'm in favor of cleaning up components -- the strange overlap between new and finalize is not cleanly defined. But it is important that Component remain a trait. If we just rely on functions named create, if we ever want to layer software we'll need to parameterize by types. Everything standard in the kernel should be a trait.

@gendx
Copy link
Contributor Author

gendx commented Feb 28, 2020

I'm not against a trait, but as mentioned above the trait would not do anything else than enforce a name.

trait Component {
    type InputType;
    type OutputType;
    unsafe fn create(input: InputType) -> OutputType;
}

impl<A: 'static + time::Alarm<'static>> Component for AlarmComponent<A> {
    type InputType = (
        &'static kernel::Kernel,
        &'static MuxAlarm<'static, A>,
        (
            UninitStaticBuf<VirtualMuxAlarm<'static, A>>,
            UninitStaticBuf<AlarmDriver<'static, VirtualMuxAlarm<'static, A>>>,
        ),
    );
    type OutputType = &'static AlarmDriver<'static, VirtualMuxAlarm<'static, A>>;

    unsafe fn create(input: InputType) -> OutputType {
        let (board_kernel, alarm_mux, static_buffer) = input;
        ...
    }
}

I personally don't think the extra verbosity is worth it. I find it less readable to have an InputType tuple rather than named arguments.

As for the benefits, they are limited to a consistent naming. Because each component has its own input/output types there's not much else one can do than to instantiate each component separately.


In any case, the Component part of this RFC can be done independently from the changes in static_init/static_init_half macros. Shall I create a separate PR for these macros first?

@ppannuto
Copy link
Member

ppannuto commented Feb 28, 2020 via email

@gendx
Copy link
Contributor Author

gendx commented Mar 5, 2020

I updated the draft to use a trait. For now it's called CreateComponent to ease prototyping, but should supersede the previous Component trait once there is agreement on the design.

@gendx gendx requested a review from ppannuto March 5, 2020 17:36
@bradjc
Copy link
Contributor

bradjc commented Mar 10, 2020

👍

I would like UninitBuf to be named based on what it is doing for Tock, rather than how it is implemented in Rust.

@gendx
Copy link
Contributor Author

gendx commented Mar 11, 2020

I would like UninitBuf to be named based on what it is doing for Tock, rather than how it is implemented in Rust.

What name would you suggest instead? Uninitialized? Is your concern about the shortcut "uninit" vs. spelling "uninitialized" (I reused "uninit" from MaybeUninit)?

This type is just a wrapper around an uninitialized T, that's what it is, there isn't much more to say about it. I don't see much other meaningful naming option.

Then UninitStaticBuf (or UninitializedStatic?) contains a static reference to such uninitialized T. That's again pretty descriptive.

And the initialize() function actually initializes it and returns a plain static reference to T.

I find these semantics much clearer than the former static_init_half which doesn't describe what "half" it's dealing with.

@bradjc
Copy link
Contributor

bradjc commented Mar 12, 2020

Take a look at the commit I added. I wanted to capture what you wrote in the PR description in the code comments for future readers. That also helped me understand the static initialization design, and I'm a fan. The commit also includes my opinion on the names:

  • static_init!()
  • static_buf!()
  • UninitializedBuffer
  • StaticUninitializedBuffer

My comments might be a little verbose, but I really wanted to capture why we have all of this complexity.

@gendx
Copy link
Contributor Author

gendx commented Mar 12, 2020

The names look good! Thanks for taking the time documenting it as well. I'll take a closer look tomorrow.

@bradjc
Copy link
Contributor

bradjc commented Mar 13, 2020

I'm convinced on the static_init changes.

I'm less sure about the component trait changes. The current component has a relatively familiar feel. The author defines a struct with all of the resources it needs, creates a new() function, and them implements the component trait. The weirdness comes with the component associated types and the macro creation.

This PR keeps that existing weirdness, but also requires the resources to be specified as a tuple, and the struct now has to contain a phatomdata type. That might save a couple lines of code, but adds a bit of complexity to do it. My opinion is this makes components harder to use. But even ignoring that, do you think there is enough benefit to warrant refactoring all of the components?

@gendx
Copy link
Contributor Author

gendx commented Mar 16, 2020

I'm convinced on the static_init changes.
I'm less sure about the component trait changes.

I was quite ambitious in proposing both changes in this pull-request, but they can indeed be split.

One thing to note is that deprecating the former static_init_half macro (which can be done separately than introducing the new static_init implementation) will require to refactor all components, so if we go that way I think it would be better to also rethink the components' design.

The current component has a relatively familiar feel. The author defines a struct with all of the resources it needs, creates a new() function, and them implements the component trait. The weirdness comes with the component associated types and the macro creation.

My concerns, are mainly about:

  • The big layer of verbosity required to write a component. For usually 5-10 lines of actual business logic, one needs to define a struct, then a new function that just copies arguments to this struct, and then a finalize function to use those arguments to construct the actual objects. Additionally, associated types are also redundant with the function's parameter. Adding to that the documentation, which often paraphrases the corresponding capsule, and a component takes 50-100 lines for the 5-10 lines of business logic. That's a big overhead to take into account.
  • I disagree with the "relatively familiar feel". Although components have a familiar feel to a developer who has already written some, I personally found their logic hard to grasp when writing my own for the first time. What should I put in new vs. finalize? When should I use static_init_half? Ultimately, this extra complexity (mostly due to the verbosity) means a steep initial learning curve for someone new to (this part of) the project, so only "experts" will tend to write components. I think that the code patterns should be as simple as possible so that new contributors can easily adopt the code base and make meaningful contributions. Simplification was my goal in proposing to remove the Component trait altogether.

This PR keeps that existing weirdness, but also requires the resources to be specified as a tuple, and the struct now has to contain a phatomdata type. That might save a couple lines of code, but adds a bit of complexity to do it. My opinion is this makes components harder to use.

As mentioned in the previous comments, the extra weirdness (tuple, phantomdata) are necessary if we keep a trait for something that shouldn't be a trait. Given that each component has its own list of parameters of various types, there's no other way of "unifying" all components behind a common trait. I again don't think it's worth having all this extra complexity just to make sure developers use the same function name. Rather than a completely artificial trait, we should use code reviews to make sure that the style is consistent among components.

But even ignoring that, do you think there is enough benefit to warrant refactoring all of the components?

  • Most capsules still don't have a component, so improving the code pattern now will benefit all the currently component-less capsules.
  • It will be beneficial to have a simpler interface for future contributors who will create their components.
  • If the new interface has 5-10x fewer lines of code, migrating existing components will reduce the code base's size accordingly, which I also see as a benefit.
  • On the other side, the migration cost can be spread in time by refactoring components one-by-one if migrating them all is too big of a change.
  • Deprecating static_init_half will already have some refactoring cost, so if we also refactor components to a new pattern at the same time, the total cost will be less than the sum of the two refactorings.

So yes, all in all I think that the benefits outweigh the cost of migration.


All in all, I suggest to split this pull-request into:

  1. Refactoring the static_init implementation (which we now seem to have agreed upon). The static_init_half macro isn't deprecated yet, because all components still use it.
  2. Refactoring of the components, to migrate away from static_init_half, and hopefully we can agree on a simpler pattern for components. The actual migration of all the components can be split into multiple pull-requests if that's easier.

@bradjc
Copy link
Contributor

bradjc commented Mar 16, 2020

I almost suggested separating into multiple PRs, but you are right the re-factoring is a big overhead even with just the static init changes. I don't think it is worth doing that twice.

familiar feel and verbosity

Here I am referring to the use of a struct that holds resources and settings, and is created with a new() function. This pattern happens all over Tock. I'm not necessarily referring to the component trait itself.

I still believe components have to be based on a trait. We are rather terrible at enforcing code consistency in PRs. With multiple reviewers it just will not work to enforce consistency at PR time. And the reason is is that components are going to come in PRs that also include new capsules or peripheral drivers, which often require numerous notes. But there is only so much that human reviewers are willing to request of a PR author, and after so many back-and-forth rounds components will be an easy place to say "eh, good enough".

PhantomData may be obvious to experienced Rust developers, but it is not to average developers or embedded developers. In cases where it exactly solves a problem and can be hidden behind an abstraction it is great. However, requiring it to write the more "user facing" kernel code is not great for tock usability or friendliness. (We expect that capsules and their corresponding components is what a lot of developers will need to write to support particular hardware platforms in the future.)

If both of these issues can be solved with a bit of verbosity, I think it is well worth it.

effects of new static buffer handling

I agree that static_init_half is confusing. I am curious if the refactoring of how static buffers work makes the current new/finalize interface more intuitive. Particularly if we add a guide on what new and finalize should be used for.

  • new: must pass in all resources the component needs
  • finalize: pass in any static buffers and configuration parameters

Or, maybe a third function would be helpful:

  • new: pass in all resources
  • configure: pass in all settings
  • finalize: pass in needed static buffers

Perhaps we should remove static_init from components, so that all components require their static buffers to be passed in. This would make copying a component easier, since you could start from the most similar component without having to worry if it matches your requirement for needing separated buffer creation from initialization.

@gendx
Copy link
Contributor Author

gendx commented Mar 16, 2020

effects of new static buffer handling

I agree that static_init_half is confusing. I am curious if the refactoring of how static buffers work makes the current new/finalize interface more intuitive. Particularly if we add a guide on what new and finalize should be used for.

  • new: must pass in all resources the component needs
  • finalize: pass in any static buffers and configuration parameters

Actually, with the new StaticUninitializedBuffer type, the finalize function can be made more specific (which would also give more sense to a trait):

pub trait Component {
    type StaticInput = ();
    type Output;
    unsafe fn finalize(
        self,
        static_memory: StaticUninitializedBuffer<Self::StaticInput>
    ) -> Self::Output;
}

// ...

impl<A: 'static + time::Alarm<'static>> Component for AlarmMuxComponent<A> {
    type StaticInput = MuxAlarm<'static, A>;
    type Output = &'static MuxAlarm<'static, A>;

    unsafe fn finalize(
        self,
        static_buffer: StaticUninitializedBuffer<Self::StaticInput>
    ) -> Self::Output {
        let mux_alarm = static_buffer.initialize(MuxAlarm::new(self.alarm));
        mux_alarm
    }
}

// ...

impl<A: 'static + time::Alarm<'static>> Component for AlarmDriverComponent<A> {
    type StaticInput = (
        VirtualMuxAlarm<'static, A>,
        AlarmDriver<'static, VirtualMuxAlarm<'static, A>>,
    );
    type Output = &'static AlarmDriver<'static, VirtualMuxAlarm<'static, A>>;

    unsafe fn finalize(
        self,
        static_buffer: StaticUninitializedBuffer<Self::StaticInput>
    ) -> Self::Output {
        // ...
    }
}

One question that arises from the latter example (AlarmDriverComponent) is how to "split" a StaticUninitializedBuffer<(Foo, Bar)> into (StaticUninitializedBuffer<Foo>, StaticUninitializedBuffer<Bar>) (and more generally converting a buffer of tuple into a tuple of buffers).

@ppannuto
Copy link
Member

ppannuto commented Apr 1, 2020

I've been staring at this for a while, and I'm honestly not sure what the most useful feedback I can give is. I think what is proposed thus far is better, but the whole initialization process is still quite verbose and confusing to newcomers.

In the most recent proposal, would only finalize be part of the Component trait? I liked @bradjc's notion of the 'three phases' of component creation.


To what extent is this hard because we are relying on static lifetimes, which would require richer const fn's to directly create objects -- would the adoption of a kernel lifetime, as proposed elsewhere, allow components to more directly initialize themselves by creating their own buffers (now a safe operation) rather than needing to outsource their own allocation to board main files to allocate buffers and resulting in this split-phase initialization complexity?

@gendx
Copy link
Contributor Author

gendx commented Apr 2, 2020

To what extent is this hard because we are relying on static lifetimes, which would require richer const fn's to directly create objects -- would the adoption of a kernel lifetime, as proposed elsewhere, allow components to more directly initialize themselves by creating their own buffers (now a safe operation) rather than needing to outsource their own allocation to board main files to allocate buffers and resulting in this split-phase initialization complexity?

My intuition is that this would be an interesting path to explore, but this would first require quite a bit of untangling of the static lifetimes in the kernel, to be able to prototype it. #1628 would be a step in this direction. Completing #1074 would be another step.

The good news is that if it turns out not working, the more generic lifetime would still be compatible with the current implementation, by setting 'kernel to 'static.

@bradjc
Copy link
Contributor

bradjc commented Apr 10, 2020

PR Summary

This PR right now does two things:

  1. Re-designs how static_init works. There is now a uninitialized buffer type, and the only way to get a &'static mut is to call initialize(), ensuring that memory has been statically allocated and initialized.
  2. Adds an input parameter to the Component trait. This makes it clearer how to pass more parameters to the finalize() function (called create() in this PR) rather than adding them as "static input" (when they really aren't).

Status

The static_init changes have been reviewed and so far the consensus is they are a great improvement.

However, changing static_init means changing every component. So, it is a lot of work to merge just half of this PR, and then make a change to the component trait. Therefore, this is blocking on deciding on what (if any) changes to make to Component.

Component Change Motivation

More details are in this thread, but to summarize:

  • Components provide little framework for users, so it is difficult to know what to pass where.
  • Creating a struct, and writing a new() function, adds a fair bit of verbosity to the code.
  • However, having a trait in the kernel adds at least some structure, and we can't expect code reviews to enforce structure.

@bradjc
Copy link
Contributor

bradjc commented Apr 10, 2020

My thoughts:

Convention vs. Rigorous Traits

I think the more we can do with the Component trait the better. We can have conventions here, but I think they will be difficult to rely on since the component is likely to be the "highest level" code in any PR, and therefore is least likely to receive much scrutiny.

However, it seems to be difficult to enforce much in the component trait, since every type has to be very flexible given the nature of components. Even in the current revision, a component author could still use the new() function and struct fields, and not require PhantomData.

PhantomData

I think that requiring (or expecting) a PhantomData type in /boards adds unnecessary complexity for developers not experienced in Rust. If it was essential for components to be shared I would feel differently, but it just needed to reduce a small amount of duplicated code. If the component only needs one "resource" (e.g. something that implements the i2c HIL), then it saves very little code.

My Proposed Component Trait

pub trait Component {
    /// A type or tuple of types that includes all of the hardware resources
    /// that this component requires. Hardware resources are generally objects
    /// that implement kernel HILs.
    type InputResources;

    /// A type or tuple of types that represents any configuration options this
    /// capsule provides. For example, this could include setting a baud rate,
    /// or the start and end addresses of a writeable flash region.
    type InputConfiguration;

    /// A type or tuple of types of static, uninitialized buffers that will be
    /// used as the memory to store the objects created by this component. This
    /// _must_ be either empty or one or more `StaticUninitializedBuffer` types.
    /// All other inputs must be include in the other associated types.
    type InputStatic;

    /// A type or tuple of types of additional objects that the component needs
    /// to successfully create the output type. An example is a reference to the
    /// kernel for creating a grant region.
    type InputHelpers;

    /// The `&'static` reference type the component will create.
    type Output;

    /// Creates and returns the component struct object.
    fn new(resources: Self::InputResources) -> Self;

    /// Setup the static buffers for this component.
    unsafe fn finalize(self,
                       configuration: Self::InputConfiguration,
                       static_memory: Self::InputStatic,
                       helpers: Self::InputHelpers) -> Self::Output;
}

This provides as much structure as I can some up with, while still, of course, not really providing any structure at all since everything is based on associated types. But, my goal is that the associated types map well to what needs to be passed to a component, and that it would make sense to implements what needs to be passed to what.

It also enforces that there has to be a new() function.

  • An implementer using new() as intended would also have to create a struct and save references to all hardware resources (as the current component convention requires). I think it is useful to note that our components use very few hardware resources, and I don't think any components would require storing more than two in their struct. Also, if a type/lifetime needs to be referenced, the minimum is one.
  • Next, by making new() part of the trait and having an associated type as its parameter, one copy of writing out the types is removed relative to the current design.
  • Finally, I want to weakly make the argument that this approach with new() in the trait would impose more structure than the version that passes everything to finalize(). The version in this PR, for example, does not suggest that keeping a struct and a new() function (as is the current convention, and used throughout Tock) is not recommended. By making new() in the trait an implementer could still make it a no-op, but at least would have to ignore the descriptions of the associated types to do so.

@ppannuto
Copy link
Member

ppannuto commented Apr 13, 2020

I think I'm actually pro PhantomData. It helps in its way to crystallize a somewhat subtle concept. When you look at something like an AlarmMuxComponent, the actual thing, the Alarm Mux, is not the struct AlarmMuxComponent rather the mux is made up of the static buffers that are passed in. The "component" here is nothing, it's just wasted space when we make a struct for it.

What the PhantomData helps make clear is that AlarmMuxComponent is not actually a component, it's a factory for making components (and in the common case, that factory doesn't need anything -- i.e. the factory has no objects or state, it's just a non-thing to implement methods on). Indeed, I might suggest renaming the trait to something like Factory and then having an AlarmMuxFactory, as that's better suited to what is happening.

I think what @gendx's refactor makes clear is that there is no purpose to ever actually creating a AlarmMuxComponent object, and hence there is no need for a new method.


That said, I do like the types and descriptions you've provided for them, I think that's much clearer. Given the above, I might propose something like:

pub trait ComponentFactory {
    /// A type or tuple of types that includes all of the hardware resources
    /// that this component requires. Hardware resources are generally objects
    /// that implement kernel HILs.
    ///
    /// These are resources the component will have access to forever.
    type ComponentResources;

    /// A type or tuple of types that represents any configuration options this
    /// capsule provides. For example, this could include setting a baud rate,
    /// or the start and end addresses of a writeable flash region.
    ///
    /// These should generally be enums or other plain-old-data types that do
    /// not have any lifetime considerations.
    type InputConfiguration;

    /// A type or tuple of types of static, uninitialized buffers that will be
    /// used as the memory to store the objects created by this component. This
    /// _must_ be either empty or one or more `StaticUninitializedBuffer` types.
    /// All other inputs must be include in the other associated types.
    ///
    /// These buffers must last for the lifetime of the component.
    type BuffersToBecomeComponent;

    /// A type or tuple of types of additional objects that the component needs
    /// to successfully create the output type. An example is a reference to the
    /// kernel for creating a grant region.
    ///
    /// These are ephemeral references that are only available to a component
    /// during its creation.
    type CreationHelpers;

    /// The `&'static` reference type the component will create.
    type Output;

    /// Setup the static buffers for this component.
    unsafe fn create(self,
                       configuration: Self::InputConfiguration,
                       static_resources: Self::ComponentResources,
                       static_memory: Self::BuffersToBecomeComponent,
                       helpers: Self::InputHelpers) -> Self::Output;
}

(Edited by Branden to add syntax highlighting to Pat's example)

@gendx
Copy link
Contributor Author

gendx commented Apr 15, 2020

Although putting more associated types may sound appealing in terms of giving semantics, I worry about the additional bloat created by forcing components into boxes. To me, this is the trap of creating a trait for a trait's sake, when there's no programming reason to do so.

With this, we end up with associated types that have no use for the majority of components (so we'll end up calling ComponentFoo::create((), (), meaningful_parameter, (), ())), with artificial grouping of function parameters in tuples to fit multiple values in an InputFoo type (ComponentFoo::create((foo, bar), other_parameter, buffer), and with the developers of components having to use PhantomData to fit their components in the pre-defined boxes. All of this with additional verbosity in the code.

As a newcomer, I'd probably spend quite some time figuring out what all the types in the component trait are supposed to mean, and what to set for each of them.


As I understand it, the main motivation for having a Component trait is still to force a consistent naming of a create function, along with a certain order of parameters.

However, we can also have clear conventions that are not enforced by any code. For example, it's common for Rust structs to implement a new function that returns Self. This is some kind of "constructor", even though the Rust language itself doesn't have any concept of constructor. Each struct is free to name such constructors new or something else, yet in practice there is broad consistency in the ecosystem of calling them new.

This T::new(foo, bar) pattern works well across the Rust ecosystem, so in the same way I don't see why a ComponentFoo::create(foo, bar) pattern wouldn't work well for Tock. Ultimately, all of the components are instantiated in boards, so inconsistent naming would be easy to spot in code reviews, without requiring an immense amount of in-depth scrutiny by the code reviewer.

The difference is that creating a component is much simpler if it boils down to writing one utility function, rather than splitting it between multiple functions (new, finalize, etc.) and having to define a bunch of associated types and copying data between function parameters and member fields.


Ultimately, it should be easy for anyone to create their own components. It would be useful to have feedback from other people who have written them, or who haven't written any yet. For now, I've seen @alevy, @alexandruradovici, @bradjc, @hudson-ayers (in alphabetical order) creating new components in boards/components.

In contrast, a recent pull request to add an HMAC capsule doesn't have a component yet (https://github.com/tock/tock/pull/1702/files#r408097390). It would be interesting to know whether that's because components are too cumbersome to create, and whether any of the proposed designs in this thread would be better to grasp in that respect.

@bradjc
Copy link
Contributor

bradjc commented Apr 15, 2020

I don't see a component trait as a tool for component authors, but rather a tool for component users. A component author probably doesn't need a component, they know what types need to be created, what set_client calls need to be called, and how to quickly debug if things don't work as expected. It's users later on that have the difficult task. I know from experience how annoying it is to track down why a capsule isn't working because I forgot the set_client() call. The trait provides structure for users who don't have to learn how individual component authors structured their components.

I don't see how it is possible to both enforce convention but not encode it in some sort of trait. It's not really fair for someone to copy an existing component, modify it, and then be told during a review that they didn't quite capture the spirit of the convention, when there isn't a good way to write what that convention is down. If we want complete flexibility for component authors, what conventions would we even have? Further, I stand by my argument that components are difficult to nitpick and review in PRs, and use a recently merged component that doesn't quite follow the existing convention as evidence.

@gendx
Copy link
Contributor Author

gendx commented Apr 15, 2020

I don't see a component trait as a tool for component authors, but rather a tool for component users.

I definitely agree.

And that's why I think it should be as easy as possible for capsules authors to write components. If writing a component is unnecessarily complex, developers will write capsules without components (possible example: https://github.com/tock/tock/pull/1702/files#r408097390). So users won't have the any component tool at all - which would be a net negative for component users.

The trait provides structure for users who don't have to learn how individual component authors structured their components.

I don't think it's that complicated to use a component. If the component consists of a single create() function, users simply have to learn which parameters to pass to this function (all the set_client magic happens inside the component so they don't have to worry about that).

I don't see a lot of difference between learning to write:

let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm)
    .finalize(components::alarm_component_helper!(sam4l::ast::Ast));

versus:

let alarm = components::alarm::AlarmDriverComponent::create(
    board_kernel,
    mux_alarm,
    components::alarm_component_buf!(sam4l::ast::Ast)
);

but the latter is simpler to write for a component developer: essentially move a block of code from a board into some create function with the suitable parameters - without any extra verbosity nor headache in figuring out the associated types.

I don't see how it is possible to both enforce convention but not encode it in some sort of trait.

I've given an example with "constructors" in Rust - functions of the form new(...) -> Self - that are a convention without any sort of trait.

Another example is the component_foo_helper macros. These aren't encoded in any sort of trait, yet are a convention for components. Has there ever been any issue with these?

It's not really fair for someone to copy an existing component, modify it, and then be told during a review that they didn't quite capture the spirit of the convention, when there isn't a good way to write what that convention is down.

Can't we write this convention down in some documentation, for example in boards/kernel/README.md (or any other suitable location)?

If we want complete flexibility for component authors, what conventions would we even have?

I don't think we need a lot of conventions, because components are in essence not that complex. Here are my thoughts.

  • A function named create to initialize the component.
  • The inputs to create should be, in order:
    • The board's kernel (if needed).
    • Dependencies from other components (e.g. an alarm).
    • A static buffer (if needed). This should be of type StaticUninitializedBuffer<T> (or a tuple of such StaticUninitializedBuffers). The caller should provide it via a component_foo_buf macro that creates a suitable static buffer.

In these example conventions, one thing that cannot be enforced by any trait is that there is a macro named component_foo_buf to create a suitable static buffer. This is currently not part of the Component trait, yet there is already such convention, and as far as I see things, this convention works.

Further, I stand by my argument that components are difficult to nitpick and review in PRs, and use a recently merged component that doesn't quite follow the existing convention as evidence.

Do you have any example of what could go wrong in a component, which wouldn't follow the convention(s). I don't see many ways of getting the API wrong if it's just a create function with a certain order of parameters.

Documenting the convention would avoid the nitpicking, and on the other side of things, also help developers to prepare their code and write good components before sending their pull request.

@ppannuto
Copy link
Member

I think part of what makes this different than the simple new -> Self convention is that component creation is necessarily unsafe (due to the static....) and thus trading a little structure for correctness can be valuable.

I don't think it's that complicated to use a component. If the component consists of a single create() function, users simply have to learn which parameters to pass to this function

(emphasis mine); in the case of the more complex and possibly unsafe interface, this learning is a possibly higher bar.

With components, I think we are trying to impose a little bit more structure than an arbitrary block of code that could be moved freely between a board main file and create function. Specifically, the four types proposed above make very clear the lifetime and access expectations of each list of things -- in a free-form create method, this structure is lost.


Regarding the interface:

The inputs to create should be, in order:

  • The board's kernel (if needed).
  • Dependencies from other components (e.g. an alarm).
  • A static buffer (if needed). This should be of type StaticUninitializedBuffer (or a tuple of such StaticUninitializedBuffers). The caller should provide it via a component_foo_buf macro that creates a suitable static buffer.

I think this bulleted list is illustrative, as it helps demonstrate that there are categories of things used during component creation. In the simple create function approach, the categories all munge together. In contrast, the types are used to bin arguments into one of four categories:

// This requires authors to understand how each argument is used by create
//
// We could impose a convention of commenting use
let alarm = components::alarm::AlarmDriverComponent::create(
    // objects this component will have references to
    board_kernel,
    mux_alarm,
    // buffers that will make up this component
    components::alarm_component_buf!(sam4l::ast::Ast)
);

versus using the type system to identify and enforce the four types of things component creation might require:

let alarm = components::alarm::AlarmDriverComponent::create(
    (board_kernel, mux_alarm),                         // the first argument (the ComponentResources) is list of things this component will have references to
    (),                                                // the second argument (the InputConfiguration) is any configuration required, here there is none
    components::alarm_component_buf!(sam4l::ast::Ast)  // the third argument (the BuffersToBecomeComponent), defines what will make up the component
    (),                                                // the fourth argument (the CreationHelpers) is anything emphemeral
);

This means the type signature of create is effectively a series of four lists, which are sometimes empty, but consistent and clear across all invocations of create, regardless of the size of each individual list for each use of create.


Again, this structure certainly could be done by convention alone, but I think this is a case where we can use the type system a bit to help automatically enforce things.

As a newcomer, I'd probably spend quite some time figuring out what all the types in the component trait are supposed to mean, and what to set for each of them.

Do you think the proposed doc comments are unclear? Would examples for each help?

We could/should also encode the purpose a bit in a top-level doc-comment:

/// Components are used to make instantiating capsules easier for board authors.
///
/// A `ComponentFactory` is similar to a constructor, however, unlike an open-ended new()
/// method, we provide some structure to create() to help ensure consistency across
/// components. The associated types below describe the four classes of arguments
/// that are valid for a component constructor to use. Not all components will need
/// arguments from each class.
pub trait ComponentFactory {
     ...

@gendx
Copy link
Contributor Author

gendx commented Apr 17, 2020

While working on #1765, I also realized that it's not clear to me what should go in finalize today.

For some components, e.g. alarm, the finalized argument (StaticInput) is a (tuple of) &'static mut MaybeUninit type (coming from component_foo_helper! macro), on which static_init_half! is applied by the component to finish its initialization.

For other components, e.g. button, the StaticInput is an slice, coming from a component_foo_helper! macro as well, but which doesn't have the same purpose. This slice isn't MaybeUninit and isn't here to be consumed by static_init_half!. This slice is indeed &'static but not mut nor MaybeUninit.

So the current component interface is already somewhat blurry in that regard.

@bradjc
Copy link
Contributor

bradjc commented May 7, 2020

@tock/core-wg We should make progress on this. I'm pretty supportive of @ppannuto's ComponentFactory approach which I think is clear and well-matched to the purpose of components. I'm hopeful that the required types provide some guidance and structure, and they also provide a place for documentation.

@bradjc bradjc added the P-Significant This is a substancial change that requires review from all core developers. label May 18, 2020
@ppannuto
Copy link
Member

This was discussed on the core call today.

The major results:

  • This week, @tock/core-wg members and others should weigh in on the proposed design with a goal of settling on component design by next week's call.
  • Path the implementation: Phased vs flag? Phased in should be viable. Proposal: (1) Add a PR with the new static init, in a new namespace; (2) Update components to new interface; (3) Remove legacy interface

@hudson-ayers
Copy link
Contributor

I support the ComponentFactory approach.

In terms of implementation approach, I think it makes the most sense to add just the static_init!() changes in this PR, then let updates to components trickle in individually, then remove static_init_half!() once all of the old components have been updated.

I am happy to convert a number of components to the ComponentFactory approach.

@gendx
Copy link
Contributor Author

gendx commented May 25, 2020

So is my following understanding correct?

  • The changes in kernel/src/common/utils.rs (uninitialized buffer types + static_buf! macro + migrating static_init! implementation to use static_buf!) are agreed upon. I can make a pull request focused on these changes.
  • The exact component design, which builds on top of it, as well as the migration process to new components, is still pending discussion.
  • The removal of static_init_half! can be deferred to when the migration will be complete.

@ppannuto
Copy link
Member

  • buffer types + new static_buf! agreed upon
  • The removal of static_init_half! can be deferred to when the migration will be complete.

Yes and yes. The idea I think is that the new interface is preferred, but since it's named differently can co-exist with the old static_init! during migration. Once everything is moved over, static_init! will be removed.

  • exact component design still pending discussion

Yes; on the call, only a few of us (@hudson-ayers, @bradjc, and myself) had read this deeply. We are currently in favor of the ComponentFactory (as described in this comment), but wanted more folks to weigh in. So during this week, @tock/core-wg (and anyone else interested) will review this thread and the proposed design.

gendx added a commit to gendx/tock that referenced this pull request Jun 9, 2020
bors bot added a commit that referenced this pull request Jun 12, 2020
1924: Import changes in kernel/src/common/utils.rs from #1618. r=ppannuto a=gendx

### Pull Request Overview

This pull request adds a new `static_buf!` macros and related types, as previously discussed in #1618 and agreed upon in #1618 (comment).

This essentially imports the changes in `kernel/src/common/utils.rs` from #1618, as well as the necessary rebasing of the code.

Changes to the components themselves should further be discussed and agreed upon in #1618, and then a separate pull request (or multiple PRs) can migrate the code to new components.


### Testing Strategy

This pull request was tested by CI.


### TODO or Help Wanted

N/A - This part was extensively discussed in #1618.


### Documentation Updated

- [x] Updated the relevant files in `/docs`, or no updates are required.

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Guillaume Endignoux <guillaumee@google.com>
@alevy alevy added the triage-0 label Jan 11, 2021
@bradjc
Copy link
Contributor

bradjc commented Jan 11, 2021

Half of this PR (the static init changes) have been merged. The remainder is re-vamping the component interface, and the discussion here lead to a good design for components. However, it is a fair bit of effort to update all of the components to it. If anyone is motivated to do the update, we would be happy to have the component interface updated to the design presented here.

@bradjc bradjc closed this Jan 11, 2021
semialf-kanas-krzysztof pushed a commit to semialf-kanas-krzysztof/tock that referenced this pull request Jan 28, 2021
This CL merges upstream/master at 126d7110 to master.
Conflicts resolved during merge:
 arch/rv32i/src/pmp.rs        | 39 ++++++++++++++++----------------
 capsules/src/virtual_uart.rs | 13 +++++------
 kernel/src/process.rs        | 25 --------------------
 kernel/src/tbfheader.rs      | 54 --------------------------------------------
 4 files changed, 25 insertions(+), 106 deletions(-)

Changes from upstream/master:
 389 files changed, 19865 insertions(+), 4833 deletions(-)
   3.7% boards/nordic/
   3.6% boards/redboard_artemis_nano/ambiq/
  10.2% boards/
  10.1% capsules/src/
   4.5% chips/apollo3/src/
   9.4% chips/
   5.8% doc/wg/core/notes/
   7.9% doc/wg/opentitan/notes/
  35.3% doc/
   3.0% kernel/src/

857912ba ci: Add missing echo suppress
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

0a694a14 Makefile: Update the OpenTitan boot ROM
 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

9a2c2e0f ci: make capsules their own job
 Makefile | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

a836f46b add core notes 2020-06-12
 doc/wg/core/notes/core-2020-06-12.md | 230 +++++++++++++++++++++++++++++++++++
 1 file changed, 230 insertions(+)

347c2fbb run unit tests in capsules as part of ci-job-kernel
 Makefile | 2 ++
 1 file changed, 2 insertions(+)

311fec5b Work in progress to fix doc tests in capsules.
 capsules/src/adc.rs                           |  4 ++-
 capsules/src/aes_ccm.rs                       |  5 ++-
 capsules/src/ambient_light.rs                 |  8 +++--
 capsules/src/analog_comparator.rs             |  4 ++-
 capsules/src/app_flash_driver.rs              |  4 ++-
 capsules/src/ble_advertising_driver.rs        | 31 ++++++++++-------
 capsules/src/button.rs                        |  6 ++--
 capsules/src/buzzer_driver.rs                 |  6 ++--
 capsules/src/console.rs                       |  5 ++-
 capsules/src/crc.rs                           | 13 ++++---
 capsules/src/dac.rs                           |  2 ++
 capsules/src/debug_process_restart.rs         |  2 ++
 capsules/src/fm25cl.rs                        |  2 ++
 capsules/src/fxos8700cq.rs                    |  2 ++
 capsules/src/gpio.rs                          |  2 ++
 capsules/src/gpio_async.rs                    |  8 +++--
 capsules/src/humidity.rs                      |  4 ++-
 capsules/src/ieee802154/framer.rs             |  4 ++-
 capsules/src/ieee802154/virtual_mac.rs        |  2 ++
 capsules/src/ieee802154/xmac.rs               |  2 ++
 capsules/src/isl29035.rs                      |  3 ++
 capsules/src/led.rs                           |  2 ++
 capsules/src/lps25hb.rs                       |  2 ++
 capsules/src/ltc294x.rs                       |  2 ++
 capsules/src/max17205.rs                      |  2 ++
 capsules/src/mcp230xx.rs                      | 16 +++++----
 capsules/src/mx25r6435f.rs                    |  5 +++
 capsules/src/net/ipv6/ipv6.rs                 |  2 ++
 capsules/src/net/sixlowpan/sixlowpan_state.rs |  6 ++--
 capsules/src/net/stream.rs                    |  7 +++-
 capsules/src/net/thread/tlv.rs                | 22 ++++++------
 capsules/src/net/udp/driver.rs                |  1 -
 capsules/src/ninedof.rs                       |  1 +
 capsules/src/nonvolatile_storage_driver.rs    |  4 ++-
 capsules/src/nonvolatile_to_pages.rs          |  4 ++-
 capsules/src/nrf51822_serialization.rs        |  4 +++
 capsules/src/pca9544a.rs                      |  2 ++
 capsules/src/process_console.rs               |  9 +++--
 capsules/src/rng.rs                           |  4 ++-
 capsules/src/sdcard.rs                        |  3 ++
 capsules/src/segger_rtt.rs                    | 49 ++++++++++++---------------
 capsules/src/si7021.rs                        |  3 ++
 capsules/src/temperature.rs                   |  4 ++-
 capsules/src/usb/usb_user.rs                  | 14 ++++----
 capsules/src/virtual_flash.rs                 |  2 ++
 capsules/src/virtual_pwm.rs                   |  2 ++
 capsules/src/virtual_uart.rs                  | 12 ++++---
 47 files changed, 201 insertions(+), 102 deletions(-)

c66230af Fix capsules/examples/traitobj_list.rs so that it compiles with cargo test.
 capsules/examples/traitobj_list.rs | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

3192cd24 Add simple unit test in virtual_alarm capsule.
 capsules/src/virtual_alarm.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)

2a12e924 boards: make: rename to RUSTC_FLAGS_FOR_BIN
 boards/Makefile.common | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

f10d8726 capsules/README: Document MLX90614 sensor
 capsules/README.md | 1 +
 1 file changed, 1 insertion(+)

ad2a270a virtual_i2c: Ensure that the MuxI2C supports SMBus
 capsules/src/virtual_i2c.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

87939836 components: Initial support for MLX90614 IR temp sensor
 boards/components/src/lib.rs      |  1 +
 boards/components/src/mlx90614.rs | 67 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

71d4ab0a capsules: Initial support for MLX90614 IR temp sensor
 capsules/src/driver.rs   |   1 +
 capsules/src/lib.rs      |   1 +
 capsules/src/mlx90614.rs | 220 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 222 insertions(+)

aa87f2b1 artemis_nano: Init the Qwiic I2C device
 boards/redboard_artemis_nano/src/main.rs | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

ce51bed3 chips:apollo3: pwrctrl: Add support for enabling I2C2
 chips/apollo3/src/pwrctrl.rs | 6 ++++++
 1 file changed, 6 insertions(+)

6e7352c0 chips/apollo3: gpio: Add support for I2C pins
 chips/apollo3/src/gpio.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 3 deletions(-)

7de52a0b chips: apollo3: Initial commit of I2C driver
 chips/apollo3/src/chip.rs |   7 +
 chips/apollo3/src/iom.rs  | 747 ++++++++++++++++++++++++++++++++++++++++++++++
 chips/apollo3/src/lib.rs  |   1 +
 3 files changed, 755 insertions(+)

4391bd04 virtual_i2c: Add support for deferred calls
 boards/acd52832/src/main.rs         |  2 +-
 boards/components/src/i2c.rs        | 17 ++++++++++--
 boards/hail/src/main.rs             |  5 +++-
 boards/imix/src/main.rs             |  5 +++-
 boards/stm32f3discovery/src/main.rs |  8 ++++--
 capsules/src/virtual_i2c.rs         | 55 +++++++++++++++++++++++++++++++++++--
 6 files changed, 82 insertions(+), 10 deletions(-)

08adc124 capsules: virtual_smbus: Initial commit
 boards/acd52832/src/main.rs         |   2 +-
 boards/components/src/i2c.rs        |  14 ++-
 boards/hail/src/main.rs             |   2 +-
 boards/imix/src/main.rs             |   2 +-
 boards/stm32f3discovery/src/main.rs |   2 +-
 capsules/src/virtual_i2c.rs         | 192 +++++++++++++++++++++++++++++++++---
 6 files changed, 195 insertions(+), 19 deletions(-)

02602c1b Update doc/wg/core/notes/core-notes-2020-06-05.md
 doc/wg/core/notes/core-notes-2020-06-05.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

120f057c Import changes in kernel/src/common/utils.rs from #1618.
 kernel/src/common/utils.rs | 132 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 119 insertions(+), 13 deletions(-)

82bf995e hil: i2c: Add SMBus read/write functions
 capsules/src/i2c_master_slave_driver.rs |   1 +
 kernel/src/hil/i2c.rs                   | 126 +++++++++++++++++++++++++++++++-
 2 files changed, 125 insertions(+), 2 deletions(-)

7df578b5 chips: ibex: Enable low power state
 chips/ibex/src/chip.rs       |  14 +++++-
 chips/ibex/src/interrupts.rs |   2 +
 chips/ibex/src/lib.rs        |   1 +
 chips/ibex/src/pwrmgr.rs     |   7 +++
 chips/lowrisc/src/lib.rs     |   1 +
 chips/lowrisc/src/pwrmgr.rs  | 110 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 133 insertions(+), 2 deletions(-)

e8c7160f chips: ibex: Add a loop with interrupts function
 chips/ibex/src/chip.rs | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

58817791 Core working group notes from June 05
 doc/wg/core/notes/core-notes-2020-06-05.md | 96 ++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

ddb04fb8 opentitan: Connect the I2C master device
 boards/opentitan/src/main.rs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

c19db059 chips: Update lowrisc documentation
 chips/README.md | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

d59a403f chips/ibex: Map the I2C device
 chips/ibex/src/i2c.rs | 9 +++++++++
 chips/ibex/src/lib.rs | 1 +
 2 files changed, 10 insertions(+)

444c4501 chips/lowrisc: Initial commit of I2C master driver
 chips/lowrisc/src/i2c.rs | 496 +++++++++++++++++++++++++++++++++++++++++++++++
 chips/lowrisc/src/lib.rs |   1 +
 2 files changed, 497 insertions(+)

4c8d8b8d hil: ble_advertising: Pass the transmit buffer on callback
 capsules/src/ble_advertising_driver.rs |  7 +++----
 chips/nrf52/src/ble_radio.rs           | 15 +++++++--------
 kernel/src/hil/ble_advertising.rs      |  9 ++-------
 3 files changed, 12 insertions(+), 19 deletions(-)

d7cb67d2 deleted sudo from documentation for make program
 boards/nucleo_f429zi/README.md | 2 +-
 boards/nucleo_f446re/README.md | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

fa7b2900 Update capsules/src/test/aes_ccm.rs
 capsules/src/test/aes_ccm.rs | 1 -
 1 file changed, 1 deletion(-)

b45d3f74 no more move closures!
 capsules/src/ieee802154/framer.rs | 6 +++---
 capsules/src/sdcard.rs            | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

7d2c901c capsules: usbc_client_ctrl: also update comment here
 capsules/src/usb/usbc_client_ctrl.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

3f2a4664 capsules: usbc_client_ctrl: rename packed to serialization
 capsules/src/usb/usbc_client_ctrl.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

a9dc6343 capsules: usbc_client_ctrl: clarify comment
 capsules/src/usb/usbc_client_ctrl.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

d4b8f060 OpenTitan: Document and support flashing apps
 boards/opentitan/Makefile  |  7 ++++++-
 boards/opentitan/README.md | 40 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 3 deletions(-)

a3e397d5 no more shared initialization of nordic boards
 boards/acd52832/Cargo.toml                         |   2 +-
 boards/acd52832/src/main.rs                        |   2 +-
 boards/nordic/README.md                            |   7 +-
 boards/nordic/nrf52840_dongle/Cargo.toml           |   2 +-
 boards/nordic/nrf52840_dongle/src/main.rs          | 220 +++++++++++--
 boards/nordic/nrf52840dk/Cargo.toml                |   2 +-
 boards/nordic/nrf52840dk/src/main.rs               | 261 +++++++++++++--
 .../{nrf52dk_base => nrf52_components}/Cargo.toml  |   2 +-
 .../src}/ble.rs                                    |   0
 boards/nordic/nrf52_components/src/lib.rs          |   9 +
 .../src}/startup.rs                                |  69 ++++
 boards/nordic/nrf52dk/Cargo.toml                   |   2 +-
 boards/nordic/nrf52dk/README.md                    |   2 +-
 boards/nordic/nrf52dk/build.rs                     |   1 -
 boards/nordic/nrf52dk/src/main.rs                  | 202 ++++++++++--
 boards/nordic/nrf52dk_base/README.md               |   5 -
 boards/nordic/nrf52dk_base/src/lib.rs              | 352 ---------------------
 .../nrf52dk_base/src/nrf52_components/mod.rs       |   5 -
 chips/nrf52832/src/lib.rs                          |   2 +-
 19 files changed, 703 insertions(+), 444 deletions(-)

0fbed0ae capsules: usbc_client_ctrl: improve comment
 capsules/src/usb/usbc_client_ctrl.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

8d11802f capsules: USB: fix descriptor settings
 capsules/src/usb/cdc.rs         | 6 +++---
 capsules/src/usb/usbc_client.rs | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

3b0dfa99 sam4l: usb: update comment on endpoint resumption
 chips/sam4l/src/usbc/mod.rs | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

bd820c6a doc: core: notes 2020-05-15
 doc/wg/core/notes/core-notes-2020-05-15.md | 89 ++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

015d7d5f doc: ot: add 2020-06-04
 doc/wg/opentitan/notes/2020-06-04.md | 68 ++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

45ddf27d doc: ot: add 2020-05-28
 doc/wg/opentitan/notes/2020-05-28.md | 58 ++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

7333ebb3 doc: ot: add 2020-5-21
 doc/wg/opentitan/notes/2020-05-21.md               |  58 +++++++++++++++++++++
 doc/wg/opentitan/notes/2020-05-21_Ti50_on_Tock.pdf | Bin 0 -> 111682 bytes
 2 files changed, 58 insertions(+)

5527c718 doc: OT: add 2020-05-14 notes
 doc/wg/opentitan/notes/2020-05-14.md | 71 ++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

b09680c6 fix clippy error by inserting empty slice directly
 capsules/src/test/aes_ccm.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

c4f25dbd fix bugs involving move closures exposed by latest nightly, asm --> llvm_asm
 capsules/src/ieee802154/framer.rs | 3 ++-
 capsules/src/sdcard.rs            | 6 +++---
 chips/apollo3/src/lib.rs          | 4 ++--
 3 files changed, 7 insertions(+), 6 deletions(-)

917f140b fix some clippy warnings
 tools/run_clippy.sh | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

fa4f0197 nrf52: uart: remove unecessary debug use
 chips/nrf52/src/uart.rs | 1 -
 1 file changed, 1 deletion(-)

1f57f87f nrf52: uart: only disable tx at init
 chips/nrf52/src/uart.rs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

01877d18 nrf52: uart: remove misleading debug!()
 chips/nrf52/src/uart.rs | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

fe3d7462 nrf52: uart: make sure tx interrupt is cleared
 chips/nrf52/src/uart.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

9cec27c7 tools: don't leave .bak files around in update
 tools/update_rust_version.sh | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

6ffc1bbb tools: fix in-place sed to be x-platform
 tools/update_rust_version.sh | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

7ce418a9 Remove warned parentheses.
 chips/nrf52/src/clock.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

2c1d3517 Migrate away from deprecated asm feature.
 arch/cortex-m/src/lib.rs        |  2 +-
 arch/cortex-m/src/scb.rs        |  4 ++--
 arch/cortex-m/src/support.rs    |  8 ++++----
 arch/cortex-m0/src/lib.rs       | 14 +++++++-------
 arch/cortex-m3/src/lib.rs       | 14 +++++++-------
 arch/cortex-m4/src/lib.rs       | 16 ++++++++--------
 arch/rv32i/src/lib.rs           |  8 ++++----
 arch/rv32i/src/support.rs       |  4 ++--
 arch/rv32i/src/syscall.rs       |  2 +-
 chips/arty_e21_chip/src/chip.rs |  6 +++---
 chips/arty_e21_chip/src/lib.rs  |  2 +-
 chips/ibex/src/chip.rs          |  2 +-
 chips/ibex/src/lib.rs           |  2 +-
 libraries/riscv-csr/src/csr.rs  |  4 ++--
 libraries/riscv-csr/src/lib.rs  |  2 +-
 15 files changed, 45 insertions(+), 45 deletions(-)

44dc0221 update rust to nightly-2020-06
 .vscode/settings.json        | 2 +-
 doc/Getting_Started.md       | 4 ++--
 rust-toolchain               | 2 +-
 shell.nix                    | 2 +-
 tools/netlify-build.sh       | 2 +-
 tools/update_rust_version.sh | 1 -
 6 files changed, 6 insertions(+), 7 deletions(-)

6f97ca6e capsules: usb: cdc updates and renaming
 capsules/src/usb/cdc.rs              | 117 ++++++++++++++++++++---------------
 capsules/src/usb/descriptors.rs      |  58 ++++++++---------
 capsules/src/usb/usbc_client_ctrl.rs |  26 +++++---
 3 files changed, 115 insertions(+), 86 deletions(-)

3a97280d nrf52: usb: fix more register mapping errors
 chips/nrf52/src/usbd.rs | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

13f95d50 Fix broken link to board 'arty_e21'
 boards/README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

bb17267e redboard_artemis_nano: Connect the timer
 boards/redboard_artemis_nano/src/main.rs | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

eea75156 chips: apollo3: Initial commit of the stimer
 chips/README.md             |   6 +-
 chips/apollo3/src/chip.rs   |   2 +
 chips/apollo3/src/lib.rs    |   1 +
 chips/apollo3/src/stimer.rs | 183 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 189 insertions(+), 3 deletions(-)

6f67dbd6 apollo3: uart: Fix the UART callback
 chips/apollo3/src/uart.rs | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

4c0ddeb7 nrf52: usb: correct enum matching
 chips/nrf52/src/usbd.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

88329a40 opentitan: update to new USB interface
 boards/opentitan/src/usb.rs     | 5 ++++-
 capsules/src/usb/cdc.rs         | 2 ++
 capsules/src/usb/usbc_client.rs | 2 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

2e8b9ad1 imix: update to new usb_client
 boards/imix/src/imix_components/usb.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

2510e9a5 capsules: usb: fmt
 capsules/src/usb/usbc_client.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

ac62f2fd revert chip/board specific code for usb updates
 boards/imix/src/imix_components/usb.rs | 24 ++++----------
 boards/imix/src/main.rs                | 58 +++++-----------------------------
 boards/nordic/nrf52dk_base/src/lib.rs  | 28 ----------------
 chips/nrf52/src/usbd.rs                | 53 ++-----------------------------
 chips/sam4l/src/usbc/mod.rs            | 25 ++++-----------
 5 files changed, 23 insertions(+), 165 deletions(-)

f26dde9d capsules: usb: update to flexible packet len
 capsules/src/usb/usbc_client.rs | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

3b23cf3f capsules: usb: cleanup
 capsules/src/usb/cdc.rs              |  23 ++--
 capsules/src/usb/descriptors.rs      | 198 ++++++++------------------------
 capsules/src/usb/mod.rs              |   2 +-
 capsules/src/usb/usbc_client.rs      |  32 +++---
 capsules/src/usb/usbc_client_ctrl.rs | 211 ++++++++++-------------------------
 5 files changed, 138 insertions(+), 328 deletions(-)

33c8f59a sam4l: usb: fmt
 chips/sam4l/src/usbc/mod.rs | 1 -
 1 file changed, 1 deletion(-)

1b3d9836 nrf52: usb: fmt
 chips/nrf52/src/usbd.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

5b627891 imix fmt
 boards/imix/src/imix_components/usb.rs |  5 ++++-
 boards/imix/src/main.rs                | 17 +++++------------
 2 files changed, 9 insertions(+), 13 deletions(-)

46bdfe2e nrf52dk: usb: fmt
 boards/nordic/nrf52dk_base/src/lib.rs | 17 -----------------
 1 file changed, 17 deletions(-)

025cb54f usb: cdc: implement uart.receive
 capsules/src/usb/cdc.rs | 163 +++++++++++++++++++++---------------------------
 1 file changed, 70 insertions(+), 93 deletions(-)

80cea171 sam4l: usb: dont just queue resume in
 chips/sam4l/src/usbc/mod.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

ed6ae949 imix do not use userspace usb app
 boards/imix/src/main.rs | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

c6ceda51 imix: use cdc for console
 boards/imix/src/imix_components/usb.rs |  2 +-
 boards/imix/src/main.rs                | 49 ++++++++++++++++++++++++++++++++--
 2 files changed, 48 insertions(+), 3 deletions(-)

2e125236 cdc: impl UartData for CDC
 capsules/src/usb/cdc.rs | 1 +
 1 file changed, 1 insertion(+)

21680f6d cdc: make max packet size a variable
 capsules/src/usb/cdc.rs | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

c2cc66ff impl uart for cdc (not done yet)
 capsules/src/usb/cdc.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

61d40749 update imix to compile
 boards/imix/src/imix_components/usb.rs | 8 ++++----
 boards/imix/src/main.rs                | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

d42eaf24 nrf52840dk: attempt to support CTRL WRITE
 chips/nrf52/src/usbd.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

0b724010 cdc: set max pkt size to 64
 capsules/src/usb/cdc.rs | 1 +
 1 file changed, 1 insertion(+)

6a68da1a try to get cdc working on nrf
 boards/nordic/nrf52dk_base/src/lib.rs | 45 +++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

6c5458a8 rustfmt + fix lifetime issues
 capsules/src/usb/cdc.rs              | 176 +++++++++++++++++------------------
 capsules/src/usb/usbc_client_ctrl.rs |  33 +++----
 2 files changed, 96 insertions(+), 113 deletions(-)

976c0245 trying to impl uart:tx, but lifetime errors
 capsules/src/usb/cdc.rs | 275 +++++++++++++++++++++++++++++-------------------
 1 file changed, 169 insertions(+), 106 deletions(-)

e05918cd cdc echo works
 capsules/src/usb/cdc.rs              | 162 ++++++++++++++++++++++-------------
 capsules/src/usb/usbc_client_ctrl.rs |   8 +-
 2 files changed, 108 insertions(+), 62 deletions(-)

45e0a5d6 cdc full descriptor, showing up
 capsules/src/usb/cdc.rs              | 12 ++++---
 capsules/src/usb/descriptors.rs      | 70 ++++++++++++++++++++++++++++++++++--
 capsules/src/usb/usbc_client_ctrl.rs | 70 +++++++++++++++++++++++++++++++++---
 3 files changed, 140 insertions(+), 12 deletions(-)

d4485ec7 shrink size, makes it fit
 capsules/src/usb/cdc.rs | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

7b52405f start on cdc descriptor
 capsules/src/usb/cdc.rs         | 26 ++++++++++++-
 capsules/src/usb/descriptors.rs | 85 ++++++++++++++++++++++++++++++++++++++++-
 capsules/src/usb/usbc_client.rs |  1 +
 3 files changed, 109 insertions(+), 3 deletions(-)

080c62ec cdc: fix interface number
 capsules/src/usb/cdc.rs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

95eda8b6 actually copy data
 capsules/src/usb/descriptors.rs      | 18 ++++++++++++++++++
 capsules/src/usb/usbc_client_ctrl.rs | 17 +++++++++++++----
 2 files changed, 31 insertions(+), 4 deletions(-)

593c8ccf Consolidate creation of descriptor buffers
 capsules/src/usb/cdc.rs              | 104 ++++++++++---------
 capsules/src/usb/descriptors.rs      | 188 +++++++++++++++++++++++++++++++++++
 capsules/src/usb/usbc_client.rs      |  79 ++++++++-------
 capsules/src/usb/usbc_client_ctrl.rs | 111 ++++-----------------
 4 files changed, 307 insertions(+), 175 deletions(-)

a7d12c3a Remove interface response for get descriptor
 capsules/src/usb/usbc_client_ctrl.rs | 12 ------------
 1 file changed, 12 deletions(-)

543e62dc capsules: usb: update to array of interface descriptors
 capsules/src/usb/cdc.rs              | 115 ++++++++++++++++++++---------------
 capsules/src/usb/usbc_client.rs      |  19 +++++-
 capsules/src/usb/usbc_client_ctrl.rs | 107 ++++++++++++++++++++------------
 3 files changed, 152 insertions(+), 89 deletions(-)

cc060d3e setup some descriptors for cdc
 capsules/src/usb/cdc.rs | 78 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 69 insertions(+), 9 deletions(-)

ca41d096 update imix to use cdc
 boards/imix/src/imix_components/usb.rs | 21 ++++++++++++++-------
 boards/imix/src/main.rs                |  2 +-
 2 files changed, 15 insertions(+), 8 deletions(-)

fb9f34aa start on cdc
 capsules/src/usb/cdc.rs | 238 ++++++++++++++++++++++++++++++++++++++++++++++++
 capsules/src/usb/mod.rs |   1 +
 2 files changed, 239 insertions(+)

76b01b77 sam4l: usb: update check for buffer full
 chips/sam4l/src/usbc/mod.rs | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

85ef7956 sam4l: usb: ensure buffers are at least 8 bytes
 chips/sam4l/src/usbc/mod.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

3c5ca90e sam4l: usb: handle `OkSetAddress` return code
 chips/sam4l/src/usbc/mod.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

d7f585b0 sam4l: usb: dont just queue resume in
 chips/sam4l/src/usbc/mod.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

6ba5561a add comments
 arch/rv32i/src/pmp.rs | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

a48efc9b rust: remove all uses of in_band_lifetimes
 arch/rv32i/src/lib.rs                         |  9 +------
 arch/rv32i/src/machine_timer.rs               |  8 +++----
 boards/arty_e21/src/main.rs                   |  2 +-
 boards/arty_e21/src/timer_test.rs             |  4 ++--
 boards/imix/src/main.rs                       |  1 -
 boards/imix/src/test/icmp_lowpan_test.rs      |  2 +-
 capsules/src/adc.rs                           |  8 +++----
 capsules/src/aes_ccm.rs                       |  8 ++++---
 capsules/src/alarm.rs                         |  6 ++---
 capsules/src/ambient_light.rs                 |  8 +++----
 capsules/src/analog_sensor.rs                 | 12 +++++-----
 capsules/src/app_flash_driver.rs              |  6 ++---
 capsules/src/ble_advertising_driver.rs        | 10 ++++----
 capsules/src/buzzer_driver.rs                 |  6 ++---
 capsules/src/console.rs                       |  8 +++----
 capsules/src/crc.rs                           |  6 ++---
 capsules/src/dac.rs                           |  4 ++--
 capsules/src/fm25cl.rs                        |  8 +++----
 capsules/src/fxos8700cq.rs                    |  8 +++----
 capsules/src/gpio_async.rs                    |  6 ++---
 capsules/src/hmac.rs                          |  8 ++++---
 capsules/src/humidity.rs                      |  6 ++---
 capsules/src/i2c_master_slave_driver.rs       |  8 +++----
 capsules/src/ieee802154/driver.rs             | 16 ++++++-------
 capsules/src/ieee802154/framer.rs             | 12 +++++-----
 capsules/src/ieee802154/mac.rs                |  8 +++----
 capsules/src/ieee802154/virtual_mac.rs        | 14 +++++------
 capsules/src/ieee802154/xmac.rs               | 14 +++++------
 capsules/src/isl29035.rs                      |  8 +++----
 capsules/src/l3gd20.rs                        | 10 ++++----
 capsules/src/lib.rs                           |  2 +-
 capsules/src/lps25hb.rs                       |  8 +++----
 capsules/src/lsm303dlhc.rs                    | 10 ++++----
 capsules/src/ltc294x.rs                       | 12 +++++-----
 capsules/src/max17205.rs                      | 10 ++++----
 capsules/src/mcp230xx.rs                      |  8 +++----
 capsules/src/net/icmpv6/icmpv6_send.rs        |  6 ++---
 capsules/src/net/ieee802154.rs                | 14 +++++------
 capsules/src/net/ipv6/ipv6.rs                 |  4 ++--
 capsules/src/net/ipv6/ipv6_send.rs            |  8 +++----
 capsules/src/net/sixlowpan/sixlowpan_state.rs | 12 +++++-----
 capsules/src/net/thread/tlv.rs                | 28 +++++++++++-----------
 capsules/src/net/udp/udp_send.rs              |  8 +++----
 capsules/src/ninedof.rs                       |  6 ++---
 capsules/src/nonvolatile_storage_driver.rs    |  8 +++----
 capsules/src/nonvolatile_to_pages.rs          |  6 ++---
 capsules/src/nrf51822_serialization.rs        |  8 +++----
 capsules/src/pca9544a.rs                      |  6 ++---
 capsules/src/rf233.rs                         | 12 +++++-----
 capsules/src/rng.rs                           | 34 +++++++++++++--------------
 capsules/src/sdcard.rs                        | 14 +++++------
 capsules/src/segger_rtt.rs                    |  4 ++--
 capsules/src/si7021.rs                        | 10 ++++----
 capsules/src/spi.rs                           | 12 +++++-----
 capsules/src/temperature.rs                   |  6 ++---
 capsules/src/test/aes.rs                      | 12 +++++-----
 capsules/src/test/aes_ccm.rs                  |  4 ++--
 capsules/src/test/alarm.rs                    |  4 ++--
 capsules/src/tmp006.rs                        |  8 +++----
 capsules/src/tsl2561.rs                       |  8 +++----
 capsules/src/usb/descriptors.rs               |  8 +++----
 capsules/src/usb/usb_user.rs                  |  2 +-
 capsules/src/virtual_alarm.rs                 | 14 +++++------
 capsules/src/virtual_digest.rs                | 16 ++++++++-----
 capsules/src/virtual_flash.rs                 | 14 +++++------
 capsules/src/virtual_hmac.rs                  | 16 ++++++++-----
 capsules/src/virtual_i2c.rs                   | 12 +++++-----
 capsules/src/virtual_pwm.rs                   |  8 +++----
 capsules/src/virtual_spi.rs                   | 18 +++++++-------
 capsules/src/virtual_uart.rs                  |  2 +-
 chips/apollo3/src/lib.rs                      |  2 +-
 chips/apollo3/src/uart.rs                     | 16 ++++++-------
 chips/cc26x2/src/lib.rs                       |  2 +-
 chips/cc26x2/src/rtc.rs                       |  8 +++----
 chips/ibex/src/aes.rs                         |  6 ++---
 chips/ibex/src/lib.rs                         |  2 +-
 chips/ibex/src/timer.rs                       |  6 ++---
 chips/lowrisc/src/hmac.rs                     |  8 +++----
 chips/lowrisc/src/lib.rs                      |  2 +-
 chips/lowrisc/src/uart.rs                     | 12 +++++-----
 chips/lowrisc/src/usbdev.rs                   |  4 ++--
 chips/nrf5x/src/aes.rs                        | 10 ++++----
 chips/nrf5x/src/lib.rs                        |  2 +-
 chips/nrf5x/src/rtc.rs                        |  8 +++----
 chips/nrf5x/src/timer.rs                      |  6 ++---
 chips/nrf5x/src/trng.rs                       |  4 ++--
 chips/sam4l/src/aes.rs                        |  8 +++----
 chips/sam4l/src/ast.rs                        | 10 ++++----
 chips/sam4l/src/crccu.rs                      |  4 ++--
 chips/sam4l/src/eic.rs                        |  4 ++--
 chips/sam4l/src/lib.rs                        |  2 +-
 chips/sam4l/src/trng.rs                       |  6 ++---
 chips/sam4l/src/usart.rs                      | 23 +++++++++---------
 chips/sam4l/src/usbc/debug.rs                 |  2 +-
 chips/sam4l/src/usbc/mod.rs                   |  4 ++--
 chips/sifive/src/lib.rs                       |  2 +-
 chips/sifive/src/uart.rs                      | 12 +++++-----
 chips/stm32f303xc/src/exti.rs                 |  2 +-
 chips/stm32f303xc/src/gpio.rs                 | 14 +++++------
 chips/stm32f303xc/src/i2c.rs                  |  8 +++----
 chips/stm32f303xc/src/lib.rs                  |  2 +-
 chips/stm32f303xc/src/spi.rs                  |  8 +++----
 chips/stm32f303xc/src/tim2.rs                 | 10 ++++----
 chips/stm32f303xc/src/usart.rs                | 16 ++++++-------
 chips/stm32f4xx/src/dma1.rs                   |  2 +-
 chips/stm32f4xx/src/exti.rs                   |  2 +-
 chips/stm32f4xx/src/gpio.rs                   | 14 +++++------
 chips/stm32f4xx/src/lib.rs                    |  2 +-
 chips/stm32f4xx/src/spi.rs                    |  6 ++---
 chips/stm32f4xx/src/tim2.rs                   |  6 ++---
 chips/stm32f4xx/src/usart.rs                  | 14 +++++------
 kernel/src/common/list.rs                     |  6 ++---
 kernel/src/common/peripherals.rs              |  4 ++--
 kernel/src/common/ring_buffer.rs              |  4 ++--
 kernel/src/grant.rs                           |  8 +++----
 kernel/src/lib.rs                             |  1 -
 kernel/src/process.rs                         |  4 ++--
 117 files changed, 474 insertions(+), 470 deletions(-)

c1fab66f add core wg notes 05-29-2020
 doc/wg/core/notes/core-notes-2020-05-29.md | 202 +++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)

bc12d4d5 Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

075fc311 sam4l: usb: update check for buffer full
 chips/sam4l/src/usbc/mod.rs | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

c141fc69 capsules: usb: change config descriptor to 1
 capsules/src/usb/descriptors.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

bdf7c12a sam4l: usb: ensure buffers are at least 8 bytes
 chips/sam4l/src/usbc/mod.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

670e529b sam4l: usb: handle `OkSetAddress` return code
 chips/sam4l/src/usbc/mod.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

acca05c5 ci: add ci-nosetup target
 Makefile | 166 ++++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 122 insertions(+), 44 deletions(-)

ea00accf ci: move artifacts into tools/ folder
 .github/workflows/ci.yml |  2 +-
 .gitignore               |  3 ---
 Makefile                 | 13 +++++++------
 tools/.gitignore         |  1 +
 4 files changed, 9 insertions(+), 10 deletions(-)

9016538f Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

fc709186 Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

fc180066 Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

212e5ac1 Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

a56939fc Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

690fb596 Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

d344431a Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

6f3d5e6d ci: move bors.toml into .github
 bors.toml => .github/bors.toml | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

eb1beace remove empty .gitmodules file
 .gitmodules | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

9d8b9c8b build: add back `list` target to root Makefile
 Makefile | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

e66b6b8c ci: support format rule on non-git checkouts
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

5a78f452 remove unused asm feature flags
 boards/hifive1/src/main.rs          | 1 -
 boards/launchxl/src/main.rs         | 2 +-
 boards/nucleo_f429zi/src/main.rs    | 1 -
 boards/nucleo_f446re/src/main.rs    | 1 -
 boards/opentitan/src/main.rs        | 1 -
 boards/stm32f3discovery/src/main.rs | 2 +-
 chips/e310x/src/lib.rs              | 1 -
 chips/lowrisc/src/lib.rs            | 2 +-
 chips/nrf52/src/lib.rs              | 2 +-
 chips/sam4l/src/lib.rs              | 2 +-
 chips/sifive/src/lib.rs             | 2 +-
 chips/stm32f303xc/src/lib.rs        | 2 +-
 chips/stm32f4xx/src/lib.rs          | 2 +-
 13 files changed, 8 insertions(+), 13 deletions(-)

48d09db5 ci: add hidden `clippy` target
 Makefile | 9 +++++++++
 1 file changed, 9 insertions(+)

d0c7a13d ci: run actual format during prepush
 Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

75b86f39 build: use cargo check directly on workspace
 Makefile               | 5 +----
 boards/Makefile.common | 2 +-
 2 files changed, 2 insertions(+), 5 deletions(-)

e8786522 ci: improve format performance
 Makefile               | 11 ++++++++---
 tools/.gitignore       |  2 +-
 tools/run_cargo_fmt.sh | 22 ++++++++++++++++++++--
 3 files changed, 29 insertions(+), 6 deletions(-)

b29645fa ci: Implement new CI policy
 .github/PULL_REQUEST_TEMPLATE.md |   3 +-
 .github/workflows/ci.yml         |  60 ++---
 .gitignore                       |   3 +
 .travis.yml                      |  48 ----
 Makefile                         | 553 +++++++++++++++++++++++++--------------
 README.md                        |   3 +-
 boards/opentitan/Makefile        |   2 +
 bors.toml                        |   3 +-
 tools/netlify-build.sh           |   2 +-
 tools/qemu-runner/src/main.rs    |  44 +++-
 tools/run_cargo_fmt.sh           |  43 +--
 tools/run_clippy.sh              |   5 +-
 tools/toc.sh                     |   2 +-
 13 files changed, 464 insertions(+), 307 deletions(-)

74edbb86 Core WG notes from May 22
 doc/wg/core/notes/core-notes-2020-05-22.md | 132 +++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

def5731b ci: actually deny warnings in doc builds
 boards/Makefile.common                                     | 4 +++-
 boards/nordic/nrf52dk_base/src/nrf52_components/startup.rs | 7 +------
 2 files changed, 4 insertions(+), 7 deletions(-)

3e4c3840 boards: sparkfun_redboard_artemis_nano: Add the flash script
 .gitignore                                         |   3 +
 boards/redboard_artemis_nano/ambiq/README.md       |   4 +
 boards/redboard_artemis_nano/ambiq/am_defines.py   | 527 ++++++++++++
 .../redboard_artemis_nano/ambiq/ambiq_bin2board.py | 900 +++++++++++++++++++++
 boards/redboard_artemis_nano/ambiq/keys_info.py    |  46 ++
 5 files changed, 1480 insertions(+)

f92a6804 boards: Initial commit of Sparkfun's Redboard Artemis Nano
 Cargo.toml                               |   1 +
 boards/README.md                         |  31 +++---
 boards/redboard_artemis_nano/Cargo.toml  |  13 +++
 boards/redboard_artemis_nano/Makefile    |  18 ++++
 boards/redboard_artemis_nano/README.md   |  38 +++++++
 boards/redboard_artemis_nano/build.rs    |   4 +
 boards/redboard_artemis_nano/layout.ld   |  10 ++
 boards/redboard_artemis_nano/src/io.rs   |  56 ++++++++++
 boards/redboard_artemis_nano/src/main.rs | 180 +++++++++++++++++++++++++++++++
 9 files changed, 336 insertions(+), 15 deletions(-)

c48f5b74 chips: apollo3: Initial commit of PwrCtrl
 chips/apollo3/src/lib.rs     |  1 +
 chips/apollo3/src/pwrctrl.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)

fdb84fa8 chips: apollo3: Initial commit of ClkGen
 chips/apollo3/src/clkgen.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++
 chips/apollo3/src/lib.rs    |  1 +
 2 files changed, 64 insertions(+)

6bf64329 chips: apollo3: Initial commit of GPIO
 chips/apollo3/src/chip.rs |   2 +
 chips/apollo3/src/gpio.rs | 687 ++++++++++++++++++++++++++++++++++++++++++++++
 chips/apollo3/src/lib.rs  |   1 +
 3 files changed, 690 insertions(+)

e36b5383 chips: apollo3: Initial commit of UART
 chips/apollo3/src/chip.rs |   3 +
 chips/apollo3/src/lib.rs  |   1 +
 chips/apollo3/src/uart.rs | 370 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 374 insertions(+)

1c6850fe chips: Add the apollo3 crate
 Cargo.toml                |   1 +
 chips/README.md           |  88 ++++++++++++++++++------------------
 chips/apollo3/Cargo.toml  |  11 +++++
 chips/apollo3/README.md   |   8 ++++
 chips/apollo3/src/chip.rs |  83 ++++++++++++++++++++++++++++++++++
 chips/apollo3/src/lib.rs  | 113 ++++++++++++++++++++++++++++++++++++++++++++++
 chips/apollo3/src/nvic.rs |  33 ++++++++++++++
 7 files changed, 293 insertions(+), 44 deletions(-)

d85859e2 kernel: remove unstable pragma
 kernel/src/callback.rs             | 10 ++++-----
 kernel/src/common/deferred_call.rs |  8 +++----
 kernel/src/config.rs               |  8 +++----
 kernel/src/grant.rs                |  4 ++--
 kernel/src/ipc.rs                  |  2 +-
 kernel/src/lib.rs                  |  1 -
 kernel/src/mem.rs                  |  4 ++--
 kernel/src/memop.rs                |  2 +-
 kernel/src/platform/mod.rs         |  2 +-
 kernel/src/process.rs              |  2 +-
 kernel/src/sched.rs                | 20 ++++++++---------
 kernel/src/tbfheader.rs            | 45 +++++++++++++++++++++-----------------
 12 files changed, 56 insertions(+), 52 deletions(-)

1182aae7 Revert changes to disable_mpu
 arch/rv32i/src/pmp.rs | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

1fa97a1b Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

90ca804d Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

e9eee33a Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

d0d4c4fd Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

fc3fa40d Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

42abe4ed Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

e9d8a1a9 Update boards/Makefile.common
 boards/Makefile.common | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

c1be2ac5 Update boards/Makefile.common
 boards/Makefile.common | 1 +
 1 file changed, 1 insertion(+)

072d4871 Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

9d26088e Update boards/Makefile.common
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

1cec68b2 create generic 15.4 component, use it to replace board-specific 15.4 components
 boards/components/src/ieee802154.rs                | 185 +++++++++++++++++++++
 boards/components/src/lib.rs                       |   1 +
 boards/imix/src/imix_components/mod.rs             |   2 -
 boards/imix/src/imix_components/radio.rs           | 137 ---------------
 boards/imix/src/main.rs                            |  12 +-
 boards/nordic/nrf52dk_base/src/lib.rs              |   9 +-
 .../src/nrf52_components/ieee802154.rs             | 128 --------------
 .../nrf52dk_base/src/nrf52_components/mod.rs       |   2 -
 8 files changed, 199 insertions(+), 277 deletions(-)

7baf4c01 fix nrf 15.4 to be standards-compliant
 chips/nrf52/src/ieee802154_radio.rs | 77 +++++++++++++++++++------------------
 1 file changed, 40 insertions(+), 37 deletions(-)

de32f11d use map_or instead of map in configure_mpu
 arch/rv32i/src/pmp.rs | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

3dccfa80 doc: Codify CI policy
 doc/CodeReview.md | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 100 insertions(+), 4 deletions(-)

9dc3d84d cortex-m: Add a function to disable the FPU
 arch/cortex-m/src/scb.rs | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

368f83dc dont write to read only register
 boards/acd52832/src/main.rs                                |  1 -
 boards/nordic/nrf52dk_base/src/nrf52_components/startup.rs |  1 -
 chips/nrf52/src/clock.rs                                   | 12 +++---------
 3 files changed, 3 insertions(+), 11 deletions(-)

121b33f8 cortex-m: fix MPU cacheing logic
 arch/cortex-m3/src/mpu.rs | 54 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 15 deletions(-)

a19b11de doc: Add note for newly added feature
 libraries/tock-cells/src/lib.rs | 7 +++++++
 1 file changed, 7 insertions(+)

138a582a refactor unhandled_interrupt code
 arch/cortex-m4/src/lib.rs    | 24 ++++++++++++++++++++++++
 chips/cc26x2/src/crt1.rs     |  8 +++-----
 chips/nrf52/src/crt1.rs      | 26 +++-----------------------
 chips/sam4l/src/lib.rs       | 27 +++------------------------
 chips/stm32f303xc/src/lib.rs | 27 +++------------------------
 chips/stm32f446re/src/lib.rs |  3 +--
 chips/stm32f4xx/src/lib.rs   | 25 +------------------------
 7 files changed, 38 insertions(+), 102 deletions(-)

043b29c0 dont cache qemu if travis doesnt run it
 .travis.yml | 2 --
 1 file changed, 2 deletions(-)

19bacb71 cortex-m0: Handle pulsed interrupts correctly
 arch/cortex-m0/src/lib.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)

3c29f9e7 Add comment for setting pending bit and apply fix to Cortex-M4, too.
 arch/cortex-m3/src/lib.rs |  6 +++++-
 arch/cortex-m4/src/lib.rs | 10 ++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

0c9ddaaf Remove emulation-check from travis-ci.
 Makefile | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

351befce Makefile: Perform a shallow clone when cloning QEMU
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

c70ea941 Makefil: Print some more useful information when buildling QEMU
 Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

8cf20e11 Makefile: Don't pipe QEMU build to /dev/null
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

27e8e068 cortex-m: Add dirty tracking to MPU
 arch/cortex-m3/src/mpu.rs | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

5933fbd3 cells: add `contains` method to OptionalCell
 libraries/tock-cells/src/lib.rs           | 1 +
 libraries/tock-cells/src/optional_cell.rs | 8 ++++++++
 2 files changed, 9 insertions(+)

29950613 cortex-m: Add missing ISB after CONTROL writes
 arch/cortex-m0/src/lib.rs |  2 ++
 arch/cortex-m3/src/lib.rs | 15 +++++++++++++++
 arch/cortex-m4/src/lib.rs | 15 +++++++++++++++
 3 files changed, 32 insertions(+)

915d607b Deny documentation warnings.
 boards/Makefile.common | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

148eeca0 Fix documentation warning.
 capsules/src/lsm303dlhc.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

1c69c423 Make no_main attribute conditional to work around rust-lang/rust#62184 (fix #1334).
 boards/acd52832/src/main.rs               | 4 +++-
 boards/arty_e21/src/main.rs               | 4 +++-
 boards/hail/src/main.rs                   | 4 +++-
 boards/hifive1/src/main.rs                | 4 +++-
 boards/imix/src/main.rs                   | 4 +++-
 boards/launchxl/src/ccfg.rs               | 4 +++-
 boards/launchxl/src/main.rs               | 4 +++-
 boards/nordic/nrf52840_dongle/src/main.rs | 4 +++-
 boards/nordic/nrf52840dk/src/main.rs      | 4 +++-
 boards/nordic/nrf52dk/src/main.rs         | 4 +++-
 boards/nucleo_f429zi/src/main.rs          | 4 +++-
 boards/nucleo_f446re/src/main.rs          | 4 +++-
 boards/opentitan/src/main.rs              | 4 +++-
 boards/stm32f3discovery/src/main.rs       | 4 +++-
 14 files changed, 42 insertions(+), 14 deletions(-)

ded1b2ac kernel: configure MPU only if switching to a different process
 arch/cortex-m3/src/mpu.rs  |   3 +-
 arch/rv32i/src/pmp.rs      | 319 ++++++++++++++++++++++++---------------------
 kernel/src/platform/mpu.rs |   6 +-
 kernel/src/process.rs      |   4 +-
 4 files changed, 181 insertions(+), 151 deletions(-)

dbfafa50 qemu-runner: Test OpenTitan
 Makefile                      |  1 +
 tools/qemu-runner/src/main.rs | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

b656290b Makefile: Download the OpenTitan ROM for emulation-setup
 Makefile | 8 ++++++++
 1 file changed, 8 insertions(+)

0bca6eaa opentitan: Support running in QEMU
 boards/opentitan/Makefile  |  6 ++++++
 boards/opentitan/README.md | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 1 deletion(-)

dd544d02 tools: rename check-format -> format-check
 .github/workflows/ci.yml |  4 ++--
 Makefile                 | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

cf08fd58 use target with banner for travis
 .github/workflows/ci.yml | 2 +-
 Makefile                 | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

d5600126 Set interrupt pending bit manually so it is not reset before service_pending_interrupts() is reached.
 arch/cortex-m3/src/lib.rs | 6 ++++++
 1 file changed, 6 insertions(+)

126584d1 libraries/tock-rt0: Rename parameters to `zero_bss`
 libraries/tock-rt0/src/lib.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

13afcdcf Tree-wide rename of `tock_rt0` to `tock-rt0`
 arch/rv32i/Cargo.toml         | 2 +-
 chips/cc26x2/Cargo.toml       | 2 +-
 chips/lowrisc/Cargo.toml      | 2 +-
 chips/nrf52/Cargo.toml        | 2 +-
 chips/nrf52832/Cargo.toml     | 2 +-
 chips/nrf52840/Cargo.toml     | 2 +-
 chips/sam4l/Cargo.toml        | 2 +-
 chips/stm32f303xc/Cargo.toml  | 2 +-
 chips/stm32f429zi/Cargo.toml  | 2 +-
 chips/stm32f446re/Cargo.toml  | 2 +-
 chips/stm32f4xx/Cargo.toml    | 2 +-
 libraries/tock-rt0/Cargo.toml | 2 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

f7771d3a update github workflow after makefile changes
 .github/workflows/ci.yml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

e30dd359 remove make lints
 .github/PULL_REQUEST_TEMPLATE.md |  2 +-
 Makefile                         | 16 ++++++----------
 2 files changed, 7 insertions(+), 11 deletions(-)

0a95cd81 add back clippy-only makefile target
 Makefile | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

6bf538c3 remove formatall
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

8a613804 Makefile reorganization
 .github/PULL_REQUEST_TEMPLATE.md |  3 ++-
 Makefile                         | 38 ++++++++++++++++++--------------------
 2 files changed, 20 insertions(+), 21 deletions(-)

e1a66555 alpha-order makefile list
 Makefile | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

b9422e8f remove unneeded return that snuck in since last clippy PR
 capsules/src/hmac.rs | 1 -
 1 file changed, 1 deletion(-)

4cd5e064 add clippy to CI, replace tools/check_wildcard_imports with clippy option
 Makefile                        | 20 +++++++++++++-----
 tools/check_wildcard_imports.sh | 47 -----------------------------------------
 tools/run_clippy.sh             |  5 +++++
 3 files changed, 20 insertions(+), 52 deletions(-)

97ea5b05 doc: `Google` -> `Google LLC` on AUTHORS list
 AUTHORS.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

4b8ea0b6 doc: add explicit AUTHORS file & update
 AUTHORS.md | 24 ++++++++++++++++++++++++
 README.md  | 23 -----------------------
 2 files changed, 24 insertions(+), 23 deletions(-)

820a76c3 review updates
 boards/components/src/nonvolatile_storage.rs | 26 ++++++----
 boards/imix/src/main.rs                      |  6 ++-
 boards/imix/src/test/linear_log_test.rs      |  1 -
 boards/imix/src/test/log_test.rs             |  1 -
 boards/nordic/nrf52dk_base/src/lib.rs        |  8 +--
 capsules/src/mx25r6435f.rs                   |  2 -
 capsules/src/virtual_flash.rs                |  2 -
 chips/nrf52/src/nvmc.rs                      |  4 --
 chips/sam4l/src/flashcalw.rs                 | 75 +++++++++++++++-------------
 kernel/src/hil/flash.rs                      |  6 ---
 10 files changed, 62 insertions(+), 69 deletions(-)

efd04890 boards: hifive1: update doc
 boards/hifive1/README.md   | 12 ++++++++++--
 boards/hifive1/src/main.rs | 10 +++-------
 2 files changed, 13 insertions(+), 9 deletions(-)

a1d876fb hifive1: Increase app size
 boards/hifive1/src/main.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

c9b491c5 update flash component to work for nrf correctly
 boards/components/src/nonvolatile_storage.rs | 33 ++++++++++++++--------------
 boards/imix/src/main.rs                      | 11 ++++++++++
 boards/nordic/nrf52dk_base/src/lib.rs        |  3 ++-
 3 files changed, 30 insertions(+), 17 deletions(-)

881e3af3 create NrfClockComponent + fix tests
 boards/nordic/nrf52dk_base/src/lib.rs              | 10 +--------
 .../nrf52dk_base/src/nrf52_components/mod.rs       |  2 +-
 .../nrf52dk_base/src/nrf52_components/startup.rs   | 26 ++++++++++++++++++++++
 capsules/src/mx25r6435f.rs                         |  4 +---
 capsules/src/virtual_flash.rs                      |  4 +---
 chips/nrf52/src/nvmc.rs                            |  3 ++-
 chips/sam4l/src/flashcalw.rs                       |  3 ++-
 kernel/src/hil/flash.rs                            | 12 +++++++---
 8 files changed, 43 insertions(+), 21 deletions(-)

e5a99e75 create NrfStartupComponent
 boards/nordic/nrf52dk_base/src/lib.rs              | 88 ++++----------------
 .../nrf52dk_base/src/nrf52_components/mod.rs       |  2 +
 .../nrf52dk_base/src/nrf52_components/startup.rs   | 95 ++++++++++++++++++++++
 3 files changed, 111 insertions(+), 74 deletions(-)

3c519738 generic temperature sensor component
 boards/components/src/lib.rs          |  1 +
 boards/components/src/si7021.rs       | 45 +++-----------------------------
 boards/components/src/temperature.rs  | 48 +++++++++++++++++++++++++++++++++++
 boards/hail/src/main.rs               |  3 ++-
 boards/imix/src/main.rs               |  5 ++--
 boards/nordic/nrf52dk_base/src/lib.rs | 11 +++-----
 6 files changed, 61 insertions(+), 52 deletions(-)

fc47824d create generic mx25r6435f component
 boards/components/src/lib.rs          |   1 +
 boards/components/src/mx25r6435f.rs   | 138 ++++++++++++++++++++++++++++++++++
 boards/nordic/nrf52dk_base/src/lib.rs |  77 ++++---------------
 3 files changed, 152 insertions(+), 64 deletions(-)

f7f46ee5 create generic nvstorage component, use for nrf52dk
 boards/components/src/lib.rs                       |   1 +
 boards/components/src/nonvolatile_storage.rs       | 118 +++++++++++++++++++++
 boards/imix/src/imix_components/mod.rs             |   2 -
 .../src/imix_components/nonvolatile_storage.rs     |  81 --------------
 boards/imix/src/main.rs                            |   9 +-
 boards/imix/src/test/linear_log_test.rs            |   5 +-
 boards/imix/src/test/log_test.rs                   |   5 +-
 boards/nordic/nrf52dk_base/src/lib.rs              |  25 +++--
 capsules/src/mx25r6435f.rs                         |  12 ++-
 capsules/src/virtual_flash.rs                      |   4 +
 chips/nrf52/src/nvmc.rs                            |  15 ++-
 chips/sam4l/src/flashcalw.rs                       |  70 ++++++------
 kernel/src/hil/flash.rs                            |   6 +-
 13 files changed, 216 insertions(+), 137 deletions(-)

07754a20 nrf52: use spi component + make analog comparator component generic across all chips
 boards/components/src/analog_comparator.rs         | 81 ++++++++++++++++++++++
 boards/components/src/lib.rs                       | 11 ++-
 .../imix/src/imix_components/analog_comparator.rs  | 53 --------------
 boards/imix/src/imix_components/mod.rs             |  2 -
 boards/imix/src/main.rs                            | 13 +++-
 boards/nordic/nrf52dk_base/src/lib.rs              | 30 ++++----
 capsules/src/analog_comparator.rs                  | 16 ++---
 chips/nrf52/src/acomp.rs                           | 18 ++---
 chips/sam4l/src/acifc.rs                           | 11 ++-
 kernel/src/hil/analog_comparator.rs                |  4 +-
 10 files changed, 133 insertions(+), 106 deletions(-)

fc56a185 Makefile: Use a RISC-V fork of QEMU
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

a564e43a hifive1: Use LED capsule for LEDs
 boards/hifive1/src/main.rs | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

958b7493 chips/e310x: Enable PMP
 chips/e310x/src/chip.rs | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

dd217fbc boards/hifive1: Upddate the README to support rev B
 boards/hifive1/README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

e37d7824 hifive1: Makefile: Support the revB board
 boards/hifive1/Makefile | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

356f9005 hifive1: Makefile: Remove flash protect off
 boards/hifive1/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

0b90b0ca e310x: chips: Re-write interrupt handling logic
 chips/e310x/src/chip.rs | 239 +++++++++++++++++++-----------------------------
 1 file changed, 96 insertions(+), 143 deletions(-)

5509af1a e310x: Remove the debug print
 chips/e310x/src/chip.rs | 1 -
 1 file changed, 1 deletion(-)

54d8c9d5 e310x: Correct the frequency
 boards/hifive1/src/main.rs |  2 +-
 chips/e310x/src/uart.rs    |  2 +-
 chips/sifive/src/prci.rs   | 14 +++-----------
 3 files changed, 5 insertions(+), 13 deletions(-)

eee57aa0 sifive: pwm: Set the PWM compare registers
 chips/sifive/src/pwm.rs | 6 ++++++
 1 file changed, 6 insertions(+)

1056ff99 sifive: rtc: Set the RTC compare register
 chips/sifive/src/rtc.rs | 3 +++
 1 file changed, 3 insertions(+)

720510cd hifive1b: board now uses jlink
 boards/hifive1/Makefile | 10 ++++++++++
 1 file changed, 10 insertions(+)

300a2a50 hifive1b: flash start address changed
 boards/hifive1/layout.ld | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

33bc36ac dont change version
 libraries/tock-register-interface/CHANGELOG.md | 2 +-
 libraries/tock-register-interface/Cargo.toml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

b5f075cb Update doc/wg/opentitan/notes/2020-04-30.md
 doc/wg/opentitan/notes/2020-04-30.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

c990833c doc: add OT WG notes
 doc/wg/opentitan/notes/2020-04-23.md | 65 +++++++++++++++++++++++++++++
 doc/wg/opentitan/notes/2020-04-30.md | 81 ++++++++++++++++++++++++++++++++++++
 doc/wg/opentitan/notes/2020-05-07.md | 46 ++++++++++++++++++++
 3 files changed, 192 insertions(+)

af0eccf5 update bors post macosx actions
 bors.toml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

df25a50a kernel: rustfmt
 kernel/src/tbfheader.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

19917977 Update boards/hail/src/main.rs
 boards/hail/src/main.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

981ef6d0 kernel: tbfheader: improve comment
 kernel/src/tbfheader.rs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

e0d531f0 ibex: Handle USB interrupts
 chips/ibex/src/chip.rs       |  4 ++++
 chips/ibex/src/interrupts.rs | 17 +++++++++++++++++
 chips/lowrisc/src/usbdev.rs  |  4 ++++
 3 files changed, 25 insertions(+)

45d01290 lowrisc: Allow enabling and attaching USB
 chips/lowrisc/src/usbdev.rs | 204 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 189 insertions(+), 15 deletions(-)

ad2784bd hil: usb: Derive default for DeviceSpeed
 kernel/src/hil/usb.rs | 1 +
 1 file changed, 1 insertion(+)

f4124350 opentitan: Connect the USB device
 boards/opentitan/src/main.rs |  9 +++++++
 boards/opentitan/src/usb.rs  | 59 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

e1209746 fixed addresses: various improvements
 doc/TockBinaryFormat.md |  6 +++---
 kernel/src/process.rs   | 12 ++++++------
 kernel/src/tbfheader.rs | 34 +++++++++++++++-------------------
 3 files changed, 24 insertions(+), 28 deletions(-)

c50c021e simplify register_bitmasks when no array elements passed
 libraries/tock-register-interface/src/macros.rs | 31 ++++---------------------
 1 file changed, 5 insertions(+), 26 deletions(-)

290eabbd bump version to 0.6.0
 libraries/tock-register-interface/CHANGELOG.md | 3 ++-
 libraries/tock-register-interface/Cargo.toml   | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

dfc29d46 doc: update TBF table of contents
 doc/TockBinaryFormat.md | 1 +
 1 file changed, 1 insertion(+)

7b3881e3 kernel: process: check TBF header addresses
 kernel/src/process.rs | 66 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 47 insertions(+), 19 deletions(-)

5024d4cd kernel: process: check fixed addresses
 kernel/src/process.rs | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

c2f9f8a3 kernel: tbf: add support for fixed addresses
 doc/TockBinaryFormat.md | 30 +++++++++++++++++
 kernel/src/tbfheader.rs | 88 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+)

a98075b8 kernel: tbf: forbid unsafe
 kernel/src/tbfheader.rs | 3 +++
 1 file changed, 3 insertions(+)

c194650f chips: lowrisc: uart: Add receive support
 chips/lowrisc/src/uart.rs | 41 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 37 insertions(+), 4 deletions(-)

c1dcdd5f lowrisc: Initial stub of the USB device
 chips/ibex/src/lib.rs       |   1 +
 chips/ibex/src/usbdev.rs    |   7 ++
 chips/lowrisc/src/lib.rs    |   1 +
 chips/lowrisc/src/usbdev.rs | 294 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 303 insertions(+)

5f30ee5e seperate out bitmask into helper macro for readability
 libraries/tock-register-interface/src/macros.rs | 28 ++++++++++++++++---------
 1 file changed, 18 insertions(+), 10 deletions(-)

b504b492 syscalls link
 capsules/src/lsm303dlhc.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

20cdc008 make valtype ident instead of ty
 libraries/tock-register-interface/src/macros.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

04798c83 link to syscalls
 capsules/src/lsm303dlhc.rs | 59 +---------------------------------------------
 1 file changed, 1 insertion(+), 58 deletions(-)

868d04b3 run actions ci on osx as well as ubuntu
 .github/workflows/ci.yml | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

b6b65763 doc: add some clarification on the nordic boards
 boards/nordic/README.md | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

c9580708 Update boards/components/src/gpio.rs
 boards/components/src/gpio.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

b369eac1 deleted None => from comments
 boards/nucleo_f429zi/src/main.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

09c5cd76 update pin numbering, example and documentation
 boards/components/src/gpio.rs     | 50 ++++++++++++++++++++++++++++-----------
 boards/nordic/nrf52dk/src/main.rs | 24 +++++++++----------
 2 files changed, 48 insertions(+), 26 deletions(-)

23171fe3 Update chips/stm32f446re/src/lib.rs
 chips/stm32f446re/src/lib.rs | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

7e49dfc5 remove clone/copy from StoredState
 arch/cortex-m/src/syscall.rs | 2 +-
 arch/rv32i/src/syscall.rs    | 2 +-
 kernel/src/syscall.rs        | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

d11c92d7 rebase and format
 boards/stm32f3discovery/src/main.rs |   6 +-
 capsules/src/lsm303dlhc.rs          |  12 -
 chips/stm32f303xc/src/i2c.rs        | 528 ++++++++++++++++++++++++++++++++++++
 3 files changed, 531 insertions(+), 15 deletions(-)

a4557f78 set only api for now
 capsules/src/lsm303dlhc.rs | 56 +---------------------------------------------
 1 file changed, 1 insertion(+), 55 deletions(-)

d1f924c0 reverted hil modifications, set only api for now
 capsules/src/virtual_i2c.rs | 20 +++-----------------
 kernel/src/hil/i2c.rs       | 32 --------------------------------
 2 files changed, 3 insertions(+), 49 deletions(-)

0db2f575 rebase
 chips/stm32f303xc/src/spi.rs | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

641a55a9 update field
 capsules/src/lsm303dlhc.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

9d3c6f39 register field
 capsules/src/lsm303dlhc.rs | 4 ++--
 kernel/src/hil/i2c.rs      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

5873c016 added modify register to i2c trait
 capsules/src/lsm303dlhc.rs  | 109 ++++++++++++++++++++++++++++++++++++++++++--
 capsules/src/virtual_i2c.rs |  20 ++++++--
 kernel/src/hil/i2c.rs       |  32 +++++++++++++
 3 files changed, 154 insertions(+), 7 deletions(-)

05b4d51d enum from primitive
 capsules/src/lsm303dlhc.rs | 65 +++++++++++++++++++++++++---------------------
 1 file changed, 36 insertions(+), 29 deletions(-)

c18a0b53 Update doc/syscalls/70006_lsm303dlhc.md
 doc/syscalls/70006_lsm303dlhc.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

940bc228 Update doc/syscalls/70006_lsm303dlhc.md
 doc/syscalls/70006_lsm303dlhc.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

6a954de8 typo
 capsules/src/ninedof.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

16533c8e typo
 chips/stm32f303xc/src/spi.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

e1a9da77 ninedof slice instead of List
 boards/components/src/ninedof.rs            | 92 ++++++++++-------------------
 boards/hail/src/main.rs                     |  6 +-
 boards/imix/src/imix_components/fxos8700.rs |  6 +-
 boards/stm32f3discovery/src/main.rs         |  9 +--
 capsules/src/ninedof.rs                     | 39 +++---------
 5 files changed, 44 insertions(+), 108 deletions(-)

f6018254 lsm303dlhc command 4 parameters order switch
 capsules/src/lsm303dlhc.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

addf2a0f deleted unused import
 boards/stm32f3discovery/src/main.rs | 1 -
 1 file changed, 1 deletion(-)

ecfa09ff ninedof component, drivers, update hail and imix
 boards/components/src/lib.rs                |   1 +
 boards/components/src/ninedof.rs            | 106 ++++++++++++++++++++
 boards/hail/src/main.rs                     |  12 +--
 boards/imix/src/imix_components/fxos8700.rs |  11 +--
 boards/stm32f3discovery/src/main.rs         |  38 +++----
 capsules/src/lsm303dlhc.rs                  | 148 ++++++++++++----------------
 capsules/src/ninedof.rs                     |  72 +++++---------
 chips/stm32f303xc/src/spi.rs                |   2 +
 doc/syscalls/70006_lsm303dlhc.md            |   1 +
 9 files changed, 214 insertions(+), 177 deletions(-)

66762b12 Update boards/stm32f3discovery/src/main.rs
 boards/stm32f3discovery/src/main.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

ff34f171 deleted unused spi import from imix
 boards/imix/src/main.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

cf2c0c8c ninedof return value
 boards/hail/src/main.rs | 2 +-
 capsules/src/ninedof.rs | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

5c170be8 original makefile
 boards/stm32f3discovery/Makefile | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

9c05ba7a stm32f3xx i2c, lsm303dlhc sensor and ninedof
 boards/components/src/lsm303dlhc.rs |  35 ++++---
 boards/stm32f3discovery/src/main.rs |  21 +++--
 capsules/README.md                  |   1 +
 capsules/src/lsm303dlhc.rs          | 178 ++++++++++++++++++++++++++++++------
 capsules/src/ninedof.rs             |  34 +++++--
 chips/stm32f3xx/src/i2c.rs          | 107 +++-------------------
 doc/syscalls/70005_l3gd20.md        |   4 +-
 doc/syscalls/70006_lsm303dlhc.md    | 129 ++++++++++++++++++++++++++
 doc/syscalls/README.md      …
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P-Significant This is a substancial change that requires review from all core developers. triage-0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants