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

Board-based instantiation of chip drivers and interrupt --> driver mapping for Apollo3 + SAM4L #2069

Merged
merged 2 commits into from Nov 4, 2020

Conversation

hudson-ayers
Copy link
Contributor

@hudson-ayers hudson-ayers commented Aug 7, 2020

Pull Request Overview

This pull request proposes a new design for managing chip drivers and interrupts.
The new design makes boards responsible for instantiating chip drivers, and for defining the mapping from interrupt numbers --> drivers.
It also adds the InterruptService trait to kernel/src/platform/mod.rs, as it will no longer only be used by nordic boards.

I would appreciate feedback before I implement this for all chips/boards, and answers to my outstanding questions below.

Advantages of the design:

  • makes it possible for boards to exclude code for chip drivers that they are not using (e.g. solves Unused chip drivers still take up RAM #625)
  • makes boards responsible for static initialization of all chip drivers, much in the same way that boards are responsible for initializing capsules, which removes reliance on global static mut variables in these scenarios (a step in the right direction for static mut data considered harmful (as opposed to static_init) #1545 / Missed optimization opportunities with static mut data? #1662 ).
  • If so desired, out-of-tree board authors can write chip drivers that live in the boards crate, and still use the upstream chip crate.
  • introduces macros that live in chips/ to define the default interrupt mapping, so that upstream boards will not have to reimplement interrupt -> driver mappings in the common case.
  • removes all dependence on const_fn throughout Tock, except for in tock-register-interface. Most uses of const_fn in Tock today are only required because of the widespread practice of initializing drivers as globals. By transitioning away from this design, most constructors can be made non-const, a big step towards Building Tock with stable rustc #1654 .
  • I think these changes would enable OpenTitan to use the upstream earlgray crate, and maintain only a board crate out-of-tree, which is probably a win for both projects.

So far, this PR is only implemented for the apollo3/redboard_artemis_nano combination (I picked it because there aren't very many apollo3 drivers at this point, so the total work was smallest).

I have verified that this PR excludes chip driver code in a way that is not currently possible on master, by removing the ble and i2c drivers from the board. Unfortunately removing const_fn everywhere seems to have introduced some code size cost.

Testing Strategy

This pull request was tested by compiling.

TODO or Help Wanted

Outstanding Questions

  1. How to handle deferred calls? I propose that they should be handled identically to interrupts in this design, that is handle_deferred_call() should be added to the InterruptService trait, and populated by a macro for the common case. -- Done.

  2. Is modifying the Platform trait ideal, or would it be better to use basically the InterruptService trait suggested in [RFC] trait for servicing interrupts #1501, which could be implemented for the Platform, or for a struct containing just the drivers? I decided that using InterruptService is clearer and makes more sense than conflating Platform with interrupt mapping. This technique allows for chips to still define some set of required interrupt mappings if it wishes, and should make adapting this to the nordic boards easier.

  3. Is it in fact desirable to remove all uses of #[const_fn], or should I remove that portion of this PR and save it as a followup PR? It seems to me that const constructors would be preferable if the feature was stable, so maybe I am jumping the gun on this. Decided to revert the const removals, for now.

  4. Some drivers do not handle interrupts (mcuctrl, pwrctrl, clkctrl in the Apollo3 case), but still do not need to be initialized as globals. I propose that when these drivers are only used in main.rs, they should simply be stack allocated in reset_handler(). If used in chip.rs, they should be made fields on the respective chip struct, and initialized with the Chip. This makes it clear which drivers are necessary for chip operation vs. optionally included by boards. In fact, this approach could be taken one step further, by making "required" drivers fields of the chip struct. Things like uart and timer which are prerequisites for including a board in Tock could be placed on the chip struct.

Documentation Updated

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

Formatting

  • Ran make prepush.

@bradjc
Copy link
Contributor

bradjc commented Aug 11, 2020

I was skeptical at first, but now I think this is a very nice change that I would like to see merged.

My main comment is just around the naming. I think using "peripheral" instead of "driver" would be less confusing, since Driver is the trait for implementing a syscall. I also think the macro name should include "default".

  1. Agreed.
  2. Makes sense.
  3. no comment
  4. This would all still happen in the macro wouldn't it? So our current boards wouldn't see a difference? I'm not sure we need to specify anything at this point.

@bradjc
Copy link
Contributor

bradjc commented Aug 11, 2020

I think it would also make sense to start a "layer responsibilities" doc that describes what various layers are tasked with doing, and why. I think this PR adds a rather nonintuitive responsibility for board crates.

@silvestrst silvestrst self-requested a review August 12, 2020 07:42
Copy link

@silvestrst silvestrst left a comment

Choose a reason for hiding this comment

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

@hudson-ayers thank you for this PR!

I have actually played around with the idea myself when working on the OpenTitan chip_config.rs, as it is cleaner and more flexible. I have eventually dropped the idea, because it seemed to costly for the benefit of chip_config alone. You have found stronger reasons, more useful use-cases, making this change more justifiable. I think this is a great idea, thanks again!

Tiny thing, which I think is not an issue is that if board decides to override a driver - the default chip driver will still be built. I guess that is not much of an issue, as this does not affect the final image size, just increases the intermediate library size and the compilation time. However, I imagine overriding default drivers will probably be a rare occasion, which makes this a non-issue?

pub static mut UART1: Uart = Uart::new(UART1_BASE);

const UART1_BASE: StaticRef<UartRegisters> =
pub const UART1_BASE: StaticRef<UartRegisters> =
unsafe { StaticRef::new(0x4001_D000 as *const UartRegisters) };

register_structs! {

Choose a reason for hiding this comment

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

I think that register definitions should probably be split out in a separate .rs, as they remain the same regardless what driver we use. Allows to avoid reinventing the wheel for the "board" drivers.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that can be done on a per-chip basis as needed. Having everything in one place is convenient in the common case.

impl Apollo3 {
pub unsafe fn new() -> Apollo3 {
Apollo3 {
impl<P: Platform + 'static> Apollo3<P> {

Choose a reason for hiding this comment

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

For earlgrey, I think it is worth now initialise the chip_config::Config, from chip_config.rs in the corresponding board and passing the structure as a parameter into new.

For OpenTitan it will also allow to remove the following features from the .../earlgrey/Cargo.toml:

[features]
config_fpga_nexysvideo = ["config_disable_default"]
config_sim_verilator = ["config_disable_default"]
config_disable_default = []

And instead have the config related features entirely in the board Cargo.toml.

P.S.

I know this is apollo related change, but seems like the most appropriate place to leave this comment.

@@ -8,13 +8,72 @@ use kernel::common::registers::{register_bitfields, register_structs, ReadWrite}
use kernel::common::StaticRef;
use kernel::hil::gpio;

const GPIO_BASE: StaticRef<GpioRegisters> =
pub const GPIO_BASE: StaticRef<GpioRegisters> =

Choose a reason for hiding this comment

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

I think that base address, together with the register definitions should probably be split out in a separate .rs, as they remain the same regardless what driver we use. Allows to avoid reinventing the wheel for the "board" drivers.

Basically decouple implementation from the register and base definitions.

pub unsafe fn new() -> Apollo3 {
Apollo3 {
impl<I: InterruptService + 'static> Apollo3<I> {
pub unsafe fn new(interrupt_service: &'static I) -> Self {

Choose a reason for hiding this comment

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

I think apollo3_driver_definitions would need to be passed into the chip, as the chip might want internally use a driver which has been overridden by the board. Otherwise we would have a mismatch of board using one driver implementation, and the board another.

In this case the macro below, probably could just be a function, something like apollo3_default_drivers_get or something similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that if a chip needs to use a driver internally, that driver should be a field on the Chip struct itself, revealing that the Chip depends on that specific driver (and thereby showing that driver is not optional). If we want that driver to further be replaceable by multiple implementations, then introducing a trait for that particular driver would be appropriate. But I think we want to make it explicitly not possible for the chip to depend on the particular contents of whatever struct implements InterruptService, and instead depend only on the interface exposed by InterruptService.

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like having that driver be an argument to chip::new() is reasonable to handle this case.

@hudson-ayers
Copy link
Contributor Author

I have added support for deferred calls, and implemented this for the sam4l + Imix. Doing so ended up requiring..a lot of code changes. I will do this for hail next, but after that I think it might be best to get this in as separate PRs for each subsequent chip.

Imix code size report from before this PR:

   text    data     bss     dec     hex filename
 174081    3272   21304  198657   30801 /home/hudson/tock/target/thumbv7em-none-eabi/release/imix

Imix code size report from after this PR:

   text    data     bss     dec     hex filename
 176641      64   32704  209409   33201 /home/hudson/tock/target/thumbv7em-none-eabi/release/imix

Noticeably, almost nothing left in .data, which is pretty cool to see, though much of that size appears to be moved into .text. But now it is possible to build a minimal board without the many sam4l drivers!

For a minimal "Imix_mini" board that only supports gpio + led + timer, with no modifications to the sam4l crate:

with this PR:

   text    data     bss     dec     hex filename
  52737       0   16384   69121   10e01 /home/hudson/tock/target/thumbv7em-none-eabi/release/imix_mini

Function groups (flash): 31491 bytes
  capsules::*          2418 bytes
  compiler_builtins::* 76 bytes
  components::*        304 bytes
  core::*              11655 bytes
  cortexm4::*          2200 bytes
  cortexm::*           1720 bytes
  imix_mini::*         288 bytes
  kernel::*            11628 bytes
  sam4l::*             1202 bytes

before this PR:

   text    data     bss     dec     hex filename
  61953    3148   13232   78333   131fd /home/hudson/tock/target/thumbv7em-none-eabi/release/imix_mini2

Function groups (flash): 40379 bytes
  capsules::*          2414 bytes
  compiler_builtins::* 76 bytes
  components::*        308 bytes
  core::*              11947 bytes
  cortexm4::*          2200 bytes
  cortexm::*           1720 bytes
  imix_mini2::*        368 bytes
  kernel::*            16152 bytes
  sam4l::*             5100 bytes
  tock_cells::*        74 bytes
  tock_registers:      20 bytes

This was a rough/quick comparison, and does not exclude debug machinery or the power manager in either example. But it is at least clear that excluding drivers can provide meaningful benefit for code size, both by removing code size from drivers, and by reducing the portion of the core kernel code that is actually included in the final binary.

@brghena
Copy link
Contributor

brghena commented Aug 13, 2020

Is the data just going into .bss instead? In the imix_mini example, it grows by the exact amount data shrinks, plus 4.

@hudson-ayers
Copy link
Contributor Author

hudson-ayers commented Aug 13, 2020

Is the data just going into .bss instead? In the imix_mini example, it grows by the exact amount data shrinks, plus 4.

I am not sure..is this maybe an MPU alignment thing, where the RAM section is always going to be a power of 2, and the leftover RAM is given to uninitialized variables?

Have some numbers:

imix_mini2 (current master):

(.venv) hudson: ~/tock (no-more-globals) $ ./tools/print_tock_memory_usage.py --depth=3 -v target/thumbv7em-none-eabi/release/imix_mini2.elf
Tock memory usage report for target/thumbv7em-none-eabi/release/imix_mini2.elf
Kernel occupies 64852 bytes of flash
   61704        code and constant strings
    3148        variable initializers
Kernel occupies 16380 bytes of RAM
    8192        stack
    5040        uninitialized variables
    3148        initialized variables
    8188        variables total
Applications allocated 0 bytes of RAM

Variable groups (RAM): 3942 bytes
  imix_mini2::CHIP:                     4 bytes
  imix_mini2::PROCESSES:                32 bytes
  imix_mini2::io::WRITER:               1 bytes
  imix_mini2::reset_handler::BUF1:      24 bytes
  imix_mini2::reset_handler::BUF2:      20 bytes
  imix_mini2::reset_handler::BUF::*     300 bytes
  kernel::common::deferred_call:        4 bytes
  sam4l::adc::ADC0:                     52 bytes
  sam4l::aes::AES:                      40 bytes
  sam4l::ast::AST:                      12 bytes
  sam4l::crccu::CRCCU:                  548 bytes
  sam4l::dma::DMA_CHANNELS:             384 bytes
  sam4l::dma::NUM_ENABLED:              4 bytes
  sam4l::flashcalw::FLASH_CONTROLLER:   32 bytes
  sam4l::gpio::INTERRUPT_COUNT:         4 bytes
  sam4l::gpio::PA:                      516 bytes
  sam4l::gpio::PB:                      516 bytes
  sam4l::gpio::PC:                      516 bytes
  sam4l::i2c::I2C0:                     72 bytes
  sam4l::i2c::I2C1:                     72 bytes
  sam4l::i2c::I2C2:                     72 bytes
  sam4l::i2c::I2C3:                     72 bytes
  sam4l::pm::PM:                        8 bytes
  sam4l::spi::SPI:                      32 bytes
  sam4l::trng::TRNG:                    12 bytes
  sam4l::usart::IS_PANICING:            1 bytes
  sam4l::usart::USART0:                 56 bytes
  sam4l::usart::USART1:                 56 bytes
  sam4l::usart::USART2:                 56 bytes
  sam4l::usart::USART3:                 56 bytes
  sam4l::usbc::USBC:                    368 bytes
   ! 7 bytes of data or padding after sam4l::usart::IS_PANICING
   ! 3 bytes of data or padding after imix_mini2::io::WRITER
Total of 10 bytes wasted in RAM

Embedded data (flash): 15229 bytes

imix_mini (this PR):

(.venv) hudson: ~/tock (no-more-globals) $ ./tools/print_tock_memory_usage.py --depth=3 -v target/thumbv7em-none-eabi/release/imix_mini.elf
Tock memory usage report for target/thumbv7em-none-eabi/release/imix_mini.elf
Kernel occupies 52560 bytes of flash
   52560        code and constant strings
       0        variable initializers
Kernel occupies 16384 bytes of RAM
    8192        stack
    8192        uninitialized variables
       0        initialized variables
    8192        variables total
Applications allocated 0 bytes of RAM

Variable groups (RAM): 1966 bytes
  imix_mini::CHIP:                  4 bytes
  imix_mini::PROCESSES:             32 bytes
  imix_mini::io::WRITER:            1 bytes
  imix_mini::reset_handler::BUF1:   24 bytes
  imix_mini::reset_handler::BUF2:   20 bytes
  imix_mini::reset_handler::BUF::*  1876 bytes
  kernel::common::deferred_call:    4 bytes
  sam4l::gpio::INTERRUPT_COUNT:     4 bytes
  sam4l::usart::IS_PANICING:        1 bytes
   ! 4 bytes of data or padding after imix_mini::reset_handler::BUF
   ! 2 bytes of data or padding after sam4l::usart::IS_PANICING
Total of 6 bytes wasted in RAM

Embedded data (flash): 13164 bytes

Clearly some of .data has moved to .bss, such as the gpio::PA struct. But I don't see why, say, there would be space for an unitinitialized USBC struct, unless I have done something wrong.

@bradjc
Copy link
Contributor

bradjc commented Aug 13, 2020

Hmm...given that the sam4l has 8x more flash than RAM, this seems like a change we don't want.

RAM usage goes up by (32704-21304) - (3272-64) = 8192 bytes.

@hudson-ayers
Copy link
Contributor Author

hudson-ayers commented Aug 13, 2020

Hmm...given that the sam4l has 8x more flash than RAM, this seems like a change we don't want.

RAM usage goes up by (32704-21304) - (3272-64) = 8192 bytes.

I think this is just an artifact of MPU alignment. If i decrease the stack size on Imix by 100 bytes, then the bss size drops to 24512 (a decrease of 8192 bytes, leaving the total RAM usage the same as without this PR). So the impact of this change on RAM usage is much smaller than that in reality.

Note: The MPU minimum alignment for the sam4l is 8K.

@hudson-ayers hudson-ayers changed the title [RFC] Board-based instantiation of chip drivers and interrupt --> driver mapping. Board-based instantiation of chip drivers and interrupt --> driver mapping for Apollo3 + SAM4L Aug 14, 2020
@hudson-ayers
Copy link
Contributor Author

I think this is ready for review, for apollo3 + sam4l. I have reverted the const_fn removal based on the core call discussion today.

By playing with the stack size on current master and this PR to see what stack size marks the boundary where RAM use increases by 8k, I have determined that this PR actually increases memory usage by about 175 bytes.

One thing to pay attention to: constructors of chip peripherals are now public, so they can be called from boards. This has the potential to be a bit of a footgun, as only one instance of the peripheral can receive interrupts. We could potentially prevent this with a capability, but for now I think we should just see how it works out.

alistair23
alistair23 previously approved these changes Aug 31, 2020
Copy link
Contributor

@alistair23 alistair23 left a comment

Choose a reason for hiding this comment

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

I'm not a fan of the giant macro but otherwise I think this is a good improvement. The current way of handling interrupts has always annoyed me and I think this is a bit better.

I reviewed the Apollo3 parts, no the SAM4L though.

@hudson-ayers
Copy link
Contributor Author

I have removed the large macros, and just use structs defined in chips.rs instead. I also added a little documentation to Porting.md.

Copy link
Contributor

@phil-levis phil-levis left a comment

Choose a reason for hiding this comment

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

Can you fix the merge conflicts?

alistair23
alistair23 previously approved these changes Sep 22, 2020
Copy link
Contributor

@alistair23 alistair23 left a comment

Choose a reason for hiding this comment

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

Looks good for the Apollo3

@hudson-ayers
Copy link
Contributor Author

Can you fix the merge conflicts?

done

alistair23
alistair23 previously approved these changes Sep 22, 2020
@phil-levis
Copy link
Contributor

Some new conflicts, resolve and I'm ready to approve.

@bradjc
Copy link
Contributor

bradjc commented Sep 24, 2020

@hudson-ayers Have you verified that the non-macro approach does make a smaller binary if you do not use all peripherals?

@hudson-ayers
Copy link
Contributor Author

@hudson-ayers Have you verified that the non-macro approach does make a smaller binary if you do not use all peripherals?

Just did, the results seem pretty much the same as using the macro approach -- still significant savings.

@bradjc bradjc dismissed phil-levis’s stale review November 4, 2020 19:14

Merge conflicts have been addressed.

@bradjc
Copy link
Contributor

bradjc commented Nov 4, 2020

bors r+

@bors
Copy link
Contributor

bors bot commented Nov 4, 2020

Build failed:

@hudson-ayers
Copy link
Contributor Author

looks like a network connection error.

bors retry

@bors
Copy link
Contributor

bors bot commented Nov 4, 2020

Build failed:

@hudson-ayers
Copy link
Contributor Author

https://git.qemu.org/ is down, so the QEMU CI cannot pass. But neither of these chips is one of the QEMU tested chips anyway, so I think this is safe to manually merge.

@bradjc bradjc merged commit d096bd6 into tock:master Nov 4, 2020
@alistair23
Copy link
Contributor

That's a pain. We could use the GitHub mirror instead?

@hudson-ayers
Copy link
Contributor Author

Given that we already have to rely on Github being up to run CI, that would probably be an improvement. This may be a sufficiently rare occurrence it isn't worth investing the time to switch it though.

@mciantyre mciantyre mentioned this pull request Nov 15, 2020
7 tasks
@hudson-ayers hudson-ayers mentioned this pull request Nov 21, 2020
2 tasks
bors bot added a commit that referenced this pull request Dec 2, 2020
2189: Board based instantiation of chip drivers and interrupt mappings: Msp432 r=hudson-ayers a=hudson-ayers

### Pull Request Overview

This pull request ports the MSP432 chip/board to the new peripheral instantiation approach that does not rely on global variables (first proposed in #2069).

This chip was relatively easy to change compared to some of the others, but @lebakassemmerl I would still appreciate a quick look over the changes or a test of a couple apps to ensure I haven't done anything stupid.

This is the last remaining chip before all upstream chips/boards have been ported!


### Testing Strategy

This pull request was tested by compiling, hardware testing would be nice.


### TODO or Help Wanted

N/A

### Documentation Updated

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

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Hudson Ayers <hayers@stanford.edu>
bors bot added a commit that referenced this pull request Dec 2, 2020
2200: Add Teensy 4 board r=bradjc a=mciantyre

### Pull Request Overview

The PR proposes Tock support for the Teensy 4. As of this PR, the Tock kernel, and a variety of small examples, can run on [Teensy 4.0][teensy40] and [Teensy 4.1][teensy41] development boards. The PR builds on the i.MX RT chip foundation added in #1918.

[teensy40]: https://www.pjrc.com/store/teensy40.html
[teensy41]: https://www.pjrc.com/store/teensy41.html

The board makes use of

- the LED on pin 13
- UART2 on pins 14 and 15
- GPT1 as an alarm

The Teensy 4 boards use i.MX RT **1062** chips. Given our current chip features, the 1060 chip family is identical to the 1050 chip family. Before integrating the Teensy 4 board, I *renamed `chips/imxrt1050` to `chips/imxrt10xx`*. I updated the `imxrt1050-evkb` board to use the renamed crate.

Additional changes to the i.MX RT chip crate include

- adding a LPUART2 peripheral
- renaming the `gpt1` module to `gpt`, and adding `GPT2`
- supporting periodic clock selection, allowing a user to select the static crystal oscillator as the GPT clock source

Changes to the chip crate should be backwards compatible for `imxrt1050-evkb` users. Let me know if we see an issue.

### Testing Strategy

I tested the PR by running `blink` and `console` libtock-c examples on both a Teensy 4.0 and 4.1 board. I repackaged the examples [here](https://github.com/mciantyre/tock-teensy4-apps).

The PR was **not** tested on an NXP i.MX RT 1050 evaluation board; I don't have that hardware.

### TODO or Help Wanted

This pull request may be tested on a 1050 evaluation board. @valexandru, if you have an opportunity to test this work and review these changes, I'd appreciate it!

This PR does not address any of the TODOs noted in #1918. In particular, the `imxrt10xx` chip still does not use the new peripheral instantiation approach (#2069). If this is still TODO and not urgent, I'm happy to support that cleanup in a separate PR.

This Teensy 4 support was based on a different chip implementation. That chip implementation supported DMA, and a UART driver that used DMA. If we see value in a DMA driver for i.MX RT chips, I'm happy to contribute the driver.

### Documentation Updated

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

I've added documentation in `boards/teensy4`. The documentation

- lists the tools that you need to program a Teensy 4
- how to build the kernel and apps
- how to convert the program to a HEX file, which is necessary to program a board

### Formatting

- [x] Ran `make prepush`.

### New Platform Checklist

- [x] Hardware is widely available.
- [x] I can support the platform, which includes release testing for the platform, at least initially.
- Basic features are implemented:
  - [x] `Console`, including `debug!()` and userspace `printf()`.
  - [x] Timers.
  - [x] GPIO with interrupts.

I assume the basic chip features were provided by #1918. Let me know if we need to make all three features available through the board. As of this writing, the Teensy 4 board does not expose an input GPIO that responds to an interrupt.


2216: add 15.4 and ble to nano33ble r=bradjc a=hudson-ayers

### Pull Request Overview

This pull request adds the 15.4 and BLE drivers to the nano33ble, rather than leaving support as commented out, as the comments had already fallen out-of-date.


### Testing Strategy

BLE was tested using the `ble_advertising` and `ble_passive_scanning` apps in `libtock-c`.

15.4 was tested using the `radio_tx` and `radio_rx` apps in `libtock-c` and sending messages back and forth with an nrf52840-dk.

### TODO or Help Wanted

N/A

### Documentation Updated

- [x] No updates are required.

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Ian McIntyre <ianpmcintyre@gmail.com>
Co-authored-by: Hudson Ayers <hayers@stanford.edu>
Co-authored-by: Hudson Ayers <32688905+hudson-ayers@users.noreply.github.com>
bors bot added a commit that referenced this pull request Jan 5, 2021
2311: Board based instantiation of chip drivers and interrupt mappings: imxrt10xx r=bradjc a=mciantyre

### Pull Request Overview

The PR refactors the `imxrt10xx` chip and boards to support board-based initialization (first proposed in #2069). It builds on the work of #1918 and #2200, where we noted the effort as a TODO. After this PR, you may instantiate and configure i.MX RT peripherals in a board, or use the default peripherals provided by the chip.

Most peripherals were easily transitioned to the new API. The exception was the GPIO driver, which referenced `static` GPIO ports and pins throughout the code. I may have found some issues in the driver, so I took the refactoring opportunity to update the implementation, trying to follow [this suggestion](https://github.com/tock/tock/blob/master/chips/stm32f4xx/src/gpio.rs#L595). I'll leave more details in review comments.

Other changes include

- fix a GPT clock gating bug introduced in #2200
- move UART root clock initialization out of the `configure()` method, and into CCM peripheral setup

### Testing Strategy

Tested `boards/teensy40` on a Teensy 4.0 using the tests from #2200.

`boards/imxrt1050-evkb` continues to compile, but I don't have the hardware to test examples.

### TODO or Help Wanted

Looking for feedback on the refactor. Let me know if it deviates too much from the other chips.

Holding as draft to

- [x] ~~wait for #2310, since the new GPIO driver needs `min_const_generics`~~ accepting as-is, and we'll remove the feature later
- [x] figure out a way to remove the remaining `static` peripheral in `iomuxc_snvs`
- [x] remove `std` dependency in new unit tests, avoiding the conditional `no_std` in the crate
- [x] leave thoughts on GPIO changes
- [x] clean up commit messages

### Documentation Updated

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

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Ian McIntyre <ianpmcintyre@gmail.com>
hudson-ayers added a commit to hudson-ayers/tock that referenced this pull request Jul 14, 2022
This commit removes the const_mut_refs unstable feature and
all uses of it. For the most part, this just required making every const
constructor that created a `TakeCell` no longer const, as a result of
`TakeCell::empty()` no longer being const. Thanks to the updated
peripheral instantation approach in
tock#2069 and related PRs, this was very
straightforward to perform, as peripherals no longer need to be created
in const context.
bors bot added a commit that referenced this pull request Jul 22, 2022
3082: Remove `#![feature(const_mut_refs)]` r=bradjc a=hudson-ayers

### Pull Request Overview

This PR removes the `const_mut_refs` unstable feature and all uses of it. For the most part, this just required making every const constructor that created a `TakeCell` no longer const, as a result of `TakeCell::empty()` no longer being const. Thanks to the updated peripheral instantation approach in #2069 and related PRs, this was very straightforward to perform, as peripherals no longer need to be created in const context.

### Testing Strategy

This pull request was tested by compiling, no functional changes are included.


### TODO or Help Wanted

N/A

### Documentation Updated

- [x] I will update #1654 if/when this is merged.

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Hudson Ayers <hayers@stanford.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants