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

RISC-V support over CLINT #815

Merged
merged 39 commits into from
Mar 20, 2024
Merged

RISC-V support over CLINT #815

merged 39 commits into from
Mar 20, 2024

Conversation

romancardenas
Copy link
Contributor

The Software-Level Interrupt Controller (SLIC) is a software interrupt controller that aims to mimic the PLIC but using a single interrupt source. It currently works for the CLINT peripheral, but I plan to add additional mechanisms so a broader amount of RISC-V targets can benefit from it.

This PR is a work-in-progress effort for adapting the SLIC to RTIC. I already modified some aspects:

  • New interrupt_mod codegen function.
  • New extra_modules codegen function.

But I'd like to do two additional major changes before this PR is accepted:

  • Remove core peripherals from rtic::export (I currently use a very dirty patch to avoid issues with my implementation)
  • Add a new backend field to the AppArgs struct that, depending on the selected backend, can potentially parse additional configuration parameters.

Additionally, as the SLIC is able to generate any number of synthetic interrupt sources, I would like to modify the current implementation so users won't need to define their dispatchers. Instead, the dispatchers will be automatically generated as needed by the application.

All the feedback is more than welcome, let me know what do you think about my proposals :)

@romancardenas
Copy link
Contributor Author

I added backend-specific configuration arguments to the app macro. This solves #816

Copy link
Contributor

@onsdagens onsdagens left a comment

Choose a reason for hiding this comment

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

awesome, one small comment from a quick look

rtic-macros/src/codegen/pre_init.rs Outdated Show resolved Hide resolved
@romancardenas
Copy link
Contributor Author

I followed the peripherals macro argument approach and added a core macro argument. This argument defaults to true in order to be backwards compatible. However, when set to false, RTIC will remove the core peripherals from its internals.

In case of my RISC-V SLIC, this field is mandatory to be false (again, I still need a pre-processing step in which I can manipulate the app args before generating all the code).

With this approach, removing core peripherals from RTIC is very similar to #720.

Related issue: #746

@romancardenas
Copy link
Contributor Author

I added the pre_init_preprocessing binding to allow backends to modify the App structure according to their needs before any other action is triggered.

You can see how the SLIC backend uses this binding here. In this case, I force the core argument to be false. I also check that the dispatchers are empty, because I later generate as much dispatchers as needed by the SLIC.

With all these changes I am happy with the final result. So it's time to discuss my proposal and fine-tune/reorder the code before merging it :) Let me know what you think.

@romancardenas
Copy link
Contributor Author

Last week I've been working on integrating use cases of RTIC on a HiFive1 RISC-V microcontroller in the CI. I adapted the CI of the repo to test examples for a RISC-V target using my new backend. The main changes are explained below:

  • The rtic crate does not contain examples anymore.
  • Now, xtask accepts a new parameter platform to select which platform we want to test. By default, it is set to lm3s6965.
  • Each platform has custom rust flags and a default backend. Additionally, the features method allows us to define which backends are valid for every platform and, if needed, which features must be enabled when building their examples.
  • All the examples for a given platform are in the examples/<platform> crate. We can continue expanding the number of platforms.
  • For QEMU runs, the ci/expected/<platform> directory will contain a file with the expected outcome of a given example. xtask will then check that the execution matches the expected outcome.

About usage examples builds, I'm not sure if these are longer needed, as we can now treat them as regular examples. Of course, we now should adapt all the examples to be emulated in QEMU when possible. In this way, the CI will be enriched, as it does not limit to a single platform.

@perlindgren
Copy link
Collaborator

Small comment, RTIC typically should require no unsafe user code. For the Cortex and ESP32 targets setting up the interrups are done by the framework. This also ensures that the init is guaranteed to run to end in a "global critical section".

@romancardenas romancardenas force-pushed the master branch 3 times, most recently from 4ee01cc to a47383b Compare January 10, 2024 20:06
@romancardenas
Copy link
Contributor Author

@perlindgren I'll take a loop to ESP's implementation to see where is the proper place to enable the interrupts right after the init code finishes

@onsdagens
Copy link
Contributor

onsdagens commented Jan 10, 2024

@perlindgren I'll take a loop to ESP's implementation to see where is the proper place to enable the interrupts right after the init code finishes

the global interrupt enable is already there here, so it's probably just a matter of removing it from the example. We were also discussing offline the premature interrupt enable being a possible cause of some concurrency issues leading to the CI weirdness.

the slic.set_interrupts() can probably be done anywhere in the pre_init, my reasoning here being it shouldn't have any side effects with the interrupts disabled

@romancardenas
Copy link
Contributor Author

I fixed the unsafe code issue.

The weird thing is that the shared variable is correctly read and written from all the tasks but when it comes to idle, it reads the initial value as if the other tasks didn't run before

@romancardenas
Copy link
Contributor Author

romancardenas commented Jan 11, 2024

Hey wait! The issue is that idle locks the shared counter before the medium task preempts it! That makes more sense. I'll take a look to find the bug.

(still weird that CI fails depending on which host system is running QEMU)

@romancardenas
Copy link
Contributor Author

QEMU version via apt is 6.2, while I'm using 8.2.0 on my machine. I'll try to build the latest version of QEMU from source and see if that was it.

@romancardenas romancardenas force-pushed the master branch 10 times, most recently from 8263e3e to 7139493 Compare January 11, 2024 10:47
@romancardenas
Copy link
Contributor Author

closes #746, closes #816

@AfoHT AfoHT linked an issue Mar 6, 2024 that may be closed by this pull request
Copy link
Contributor

@AfoHT AfoHT 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 looking great!

Love the cleanup of the examples structure, the platform makes it tidy and extensive!

Some comments and nitpicks here and there

Do you have a plan for riscv-slic crate? For long term I guess there will be some release we'll depend on, rather than the current git-rev dep :)

rtic/src/export/riscv_common.rs Outdated Show resolved Hide resolved
xtask/src/argument_parsing.rs Outdated Show resolved Hide resolved
}
Commands::Book(args) => {
info!("Running mdbook");
cargo_book(globals, &args.arguments)
}
// TODO these two commands are not needed anymore
Copy link
Contributor

Choose a reason for hiding this comment

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

Great! Then I think you should remove them together with the associated "usage" functions etc.! 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done (maybe I forgot something, a second check would be very useful :D)

rtic-monotonics/CHANGELOG.md Outdated Show resolved Hide resolved
Comment on lines +12 to +13
input.span(),
"cortex backend does not accept any arguments",
Copy link
Contributor

Choose a reason for hiding this comment

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

Discussion point: the features exposed are cortex-m-*, and some modules are cortex, while others are riscv_xyz.

I wonder if it makes sense to keep to cortex-m/cortex_m here too for consistency? That includes module name etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I guess that we should use cortex-m / cortex_m, as it follows the name of the architecture crate (for RISC-V, the crate is riscv).

rtic-macros/src/codegen/bindings/riscv_slic.rs Outdated Show resolved Hide resolved
rtic-macros/CHANGELOG.md Outdated Show resolved Hide resolved
examples/hifive1/examples/prio_inheritance.rs Outdated Show resolved Hide resolved
heapless = "0.8.0"
hifive1 = { git = "https://github.com/romancardenas/hifive1.git", features = ["board-redv"] }
e310x = { git = "https://github.com/greenlsi/e310x.git", features = ["rt"]}
# riscv-rt = {path = "../../../riscv/riscv-rt", features = ["single-hart"]}
Copy link
Contributor

Choose a reason for hiding this comment

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

TODO before publish

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The issue with the official e310x and hifive1 crates is that they do not follow the new riscv-peripheral crate fashion. It is something I have to start moving, but I'm now kind of busy with riscv-pac and adding support to vectored mode in riscv-rt

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Once RTIC provides support to any RISC-V uC with a CLINT peripheral provided the PAC uses riscv-peripheral, maintainers will have a strong motivation to adopt the new crate 😁

I also plan to look at svd2rust and contribute there to ease the port task.

esp32c3 = { version = "0.20.0", optional = true}
riscv = {version = "0.11.0", optional = true}
cortex-m = { version = "0.7.0", optional = true }
bare-metal = "1.0.0"
#portable-atomic = { version = "0.3.19" }
# portable-atomic = { version = "0.3.19" }
Copy link
Contributor

Choose a reason for hiding this comment

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

Not used at all, do we need it? 🤔 @korken89

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 it is a "reminder" that we should move from atomic-polyfill to portable-atomic :D

@romancardenas
Copy link
Contributor Author

Do you have a plan for riscv-slic crate? For long term I guess there will be some release we'll depend on, rather than the current git-rev dep :)

I will ship a 0.1.0 release as soon as I get your OK to merge the PR :) I'm still waiting in case we detect any deficiency during the review process

@romancardenas
Copy link
Contributor Author

@AfoHT I addressed all your comments :)

Copy link
Contributor

@AfoHT AfoHT left a comment

Choose a reason for hiding this comment

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

Nice! 🚀

I think we can have this on master to really start playing with it.

@perlindgren you also had some devices to test on?

@korken89 korken89 added this pull request to the merge queue Mar 20, 2024
Merged via the queue into rtic-rs:master with commit 4060c3d Mar 20, 2024
53 checks passed
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.

rtic-macros: add backend-specific AppArgs (partially) removing core peripherals from RTIC context
5 participants